Q&A

  • 나를 제외한 프로그램 종료
안녕하세요?
회사 공정관리 프로그램을 수정하고 있는 초보 델파이 입문자입니다.

이번에 수정중인 내용은
패치가 발생하면 자동으로 서버에서 다운로드를 받아 업그레이드를 하는 부분을 개발중입니다.

구현방법은 프로그램 실행하여 로그인을 하면
패치가 있는지 확인하여 프로그램을 종료하고 업데이트프로그램을 구동하는 방식을 구현하였습니다.

문의드리는 내용은
본 프로그램인 workprocess.exe가 여러개 미리 실행되어 있는 경우에
새로 로그인을 한 workprocess.exe를 제외하고
이미 실행되고 있는 프로그램들을 종료하는 방법입니다.

FindWindow 후 PostMessage(handle, wm_close, 0, 0)을 해보니
기존 프로그램은 종료 안 하고 새로 실행한 프로그램만 종료가 되더군요... ㅠ_ㅠ
for문이나 while문으로 findwindow를 순차적으로 돌릴수 있나요?
제가 하니까 계속 같은 프로그램만 나타나더라구요... ㅠ_ㅠ

작은 도움 주시면 감사하겠습니다..
2  COMMENTS
  • Profile
    가시나무 새 2006.04.04 20:25
    <!--CodeS-->
    function EnumWindowsProc(Hwnd:Hwnd;IParam:lParam):Boolean; stdcall;
    begin
      Result:=True;
      // 일단 윈도우가 보이는 상태인지 보이지 않는 상태인지 검사하는 API 함수
      if not IsWindowVisible(Hwnd) then
      // 눈에 보이지 않는 윈도우 핸들이면 나갑니다.
      Exit;
      // 그 다음에 윈도우가 아이콘화되어있는지 검사하는 API 함수
      if IsIconic(Hwnd) then
      // 아이콘화 된 윈도우 핸들이라면 나갑니다.
      Exit;
      // 요기서 종료시킬 윈도우를 찾아서 종료시키면 되지 않을가요 ?..
      // PostMessage(Hwnd, wm_close, 0, 0)


    end;
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      EnumWindows(@EnumWindowsProc,0);
    end;

    코드끝: <!--CodeE-->
    허접한 생각이엇습니다 ㅡ.ㅡ
  • Profile
    박종철 2006.04.04 19:22
    어제 1시간이 조금 더 넘게 검색을 하다가
    팁/테크에서 찾았습니다.
    검색으로 찾지말고 팁/테크 게시물을 하나씩 찾을걸 그랬어요... ㅠ_ㅠ
    팁/테크에 글을 올려주신 neps님께 무한한 감사를 드립니다.

    다음은 neps님께서 올려주신 글입니다.




    이것은 자신의 만든 프로그램의 실행 프로세스를 항상
    1개로 고정해두기 위한 클래스입니다.

    작동원리는 우선 자신의 파일명과 동일한 프로세스를 먼저
    검색한 후, 있다면 종료 시키면서 자신의 프로세서만 남게됩니다.

    사용법은 다음과 같습니다.

    begin
    Application.Initialize;

    ProcessUnique := TProcessUnique.Create;
    ProcessUnique.ExecuteProcessUnique;
    ProcessUnique.Free;

    Application.CreateForm(TForm1, Form1);
    Application.Run;
    end.

    클래스는 다음과 같습니다.

    unit ClassProcessUnique;

    interface
    uses
    Windows, Messages, SysUtils, Classes, Forms, Dialogs, TlHelp32, ShellAPI;
    type
    TProcessUnique = class(TObject)
    private
    Procedure KillProcess(ProcID:DWORD);
    procedure AnalyProcess(PList:TStringlist);
    public
    Constructor Create;
    Procedure ExecuteProcessUnique;
    end;

    var
    ProcessUnique : TProcessUnique;

    implementation

    Constructor TProcessUnique.Create;
    begin
    end;

    //{UniqueProcess 모듈}====================================================
    Procedure TProcessUnique.ExecuteProcessUnique;
    var
    AppName : String;
    ProcessList, AnalyStr, ResultList : TStringList;
    num : Integer;
    begin
    ProcessList := TStringList.Create;
    AnalyStr := TStringList.Create;
    ResultList := TStringList.Create;

    AppName := LowerCase(ExtractFileName(Application.ExeName));
    AnalyProcess(ProcessList);

    for num := 0 to ProcessList.Count -1 do {자신의 실행 파일 목록과 동일한 것을 추려냄}
    begin
    AnalyStr.Clear;
    AnalyStr.CommaText := ProcessList.Strings[num];
    if AppName = AnalyStr.Strings[0] then
    ResultList.Add (ProcessList.Strings[num]);
    end;

    ResultList.Delete(ResultList.Count -1 ); {자신의 프로세스는 삭제}
    for num := 0 to ResultList.Count -1 do
    begin
    AnalyStr.Clear;
    AnalyStr.CommaText := ResultList.Strings[num];
    KillProcess(StrToInt64(AnalyStr.Strings[1])); {프로세스 삭제}
    end;

    ProcessList.Free;
    AnalyStr.Free;
    ResultList.Free;
    end;

    //{프로세스 종료 Function}====================================================
    Procedure TProcessUnique.KillProcess(ProcID:DWORD);
    var
    hProcess: THandle;
    TermSucc: BOOL;
    begin
    hProcess := OpenProcess(PROCESS_ALL_ACCESS, TRUE, ProcID);
    if hProcess <> NULL then TermSucc := TerminateProcess(hProcess, 0);
    CloseHandle(hProcess);
    end;

    //{UniqueProcess 분석 시작}====================================================
    procedure TProcessUnique.AnalyProcess(PList:TStringlist);
    var
    Process32: TProcessEntry32;
    SHandle: THandle;
    Next: BOOL;
    begin
    Process32.dwSize := SizeOf(TProcessEntry32);
    SHandle := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if Process32First(SHandle, Process32) then
    begin
    PList.Add(LowerCase(ExtractFileName(Process32.szExeFile)) + ','+
    Inttostr(Process32.th32ProcessID));
    repeat
    Next := Process32Next(SHandle, Process32);
    if Next then
    begin
    PList.Add(LowerCase(ExtractFileName(Process32.szExeFile)) + ','+
    Inttostr(Process32.th32ProcessID));
    end;
    until not Next;
    end;
    CloseHandle(SHandle);
    end;

    end.