Zamykanie aplikacji na podstawie pid

0

Czy jest możliwe zamknięcie aplikacji jeśli znamy jej PID ewentualnie uchwyt?
Zaznaczam, że nie chodzi mi tutaj o zabicie procesu ale o zamknięcie, tak aby aplikacja mogła chociażby zapisać swoje ustawienia.

0

Na podstawie uchwytu można bez problemów zamknąć. Poniżej mój przykład dla emulatora WinUAE:

var
  WinUAE_HWND : HWND;
begin
  WinUAE_HWND := FindWindow('PCsuxRox', nil);
  SendMessage(WinUAE_HWND, WM_SYSCOMMAND, SC_CLOSE, 0);
end;

// PID to nie uchwyt okna! - Ł

0
uses
  TlHelp32, PSApi, ShellApi, ShlObj;

function ZamknijProcesPID(PID: Cardinal): Boolean;
var
 PHandle, FHandle: THandle;
 Process: TProcessEntry32;
 Next: Boolean;
begin
 Result := False;
 FHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
 Process.dwSize := Sizeof(Process);
 Next := Process32First(FHandle, Process);
  while Next do
    begin
     PHandle := OpenProcess(PROCESS_TERMINATE, False, PID);
     if TerminateProcess(PHandle, 0) then Result := True;
     Next := Process32Next(FHandle, Process);
    end;
 CloseHandle(FHandle);
end;
0
gosc napisał(a)

ewentualnie uchwyt?

LF: napisał że uchwyt też może być, wiem że to nie to samo co pid, ale Opi już podał mu chyba ok sposób.

0

Nie chodziło mi o zamykanie na podstawie nazwy okna. Powiedzmy, że mamy uruchomione kilka kopii tego same go procesu. Ja chce zamknąć konkretny proces znając jego PID. Nie mogę wykonać terminate, gdyż to nie pozwoli na prawidłowe zakończenie działania procesu i zapisanie wyniku.

0
Gosc napisał(a)

Nie chodziło mi o zamykanie na podstawie nazwy okna. Powiedzmy, że mamy uruchomione kilka kopii tego same go procesu. Ja chce zamknąć konkretny proces znając jego PID. Nie mogę wykonać terminate, gdyż to nie pozwoli na prawidłowe zakończenie działania procesu i zapisanie wyniku.

Jeśli to jest Twoja aplikacja to zaimplementuj odbieranie komunikatu o wymuszeniu zamknięcia.
Jeśli to obca aplikacja to chyba też można wysłać odpowiedni komunikat do programu.

var
  MyHandle: THandle;
begin
  MyHandle:=FindWindow(nil, 'Delphi Help');
  SendMessage(MyHandle, WM_CLOSE, 0, 0);
end;
0

Ta opcja raczej odpada.
Napisałem usługę sysemową która cyklicznie uruchamia pewne procesy przez OpenProcess. Wtedy uzyskuje bez problemu PID oraz uchwyt procesu. Potrzebny jest mi natomiast uchwyt okna aby wysłać komunikat zamknięcia. W momencie zatrzymania usługi muszę wysłać do uruchomionej aplikacji komunikat zamknięcia. Napisałem taką procedurę:

function TForm1.GetHandleFromPID(PID: Cardinal): THandle;
 function EnumWindowsProc(wHandle: HWND): Boolean; StdCall;
  var
    ePID : DWORD;
  begin
    Result := True;
    GetWindowThreadProcessId(WHandle, @ePID);
    if ePID = PID then GetHandleFromPID := wHandle;
  end;
begin
  EnumWindows(@EnumWindowsProc,0);
end;

Procedura sprawdza wszystkie dostępne uchwyty. Na ich podstawie mogę pobrać pid, jednak przy próbie porównania ePID = PID wywala AccesViolation.

1 użytkowników online, w tym zalogowanych: 0, gości: 1