Link to home
Start Free TrialLog in
Avatar of Allan_Fernandes
Allan_Fernandes

asked on

Kill Task like Task Mgr

I want my Uninstall.exe (running with admin rights) to Terminate my Application that was installed and is running with Std User Rights.
Whereas this works in OS above win XP it fails on Win XP.

function Tform_Main.KillTask(ExeFileName: string): integer;
const
  PROCESS_TERMINATE=$0001;
var
  ContinueLoop: BOOL;
  FSnapshotHandle,ProcessHandl: THandle;
  FProcessEntry32: TProcessEntry32;
begin
  result := 0;
  FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  FProcessEntry32.dwSize := Sizeof(FProcessEntry32);
  ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
  while integer(ContinueLoop) <> 0 do
  begin
    if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = UpperCase(ExeFileName)) or
       (UpperCase(FProcessEntry32.szExeFile) = UpperCase(ExeFileName))) then
    begin
      ProcessHandl:=OpenProcess(PROCESS_TERMINATE,BOOL(0),FProcessEntry32.th32ProcessID) ;
      Result := Integer(TerminateProcess(ProcessHandl, 0));
      CloseHandle(ProcessHandl);
    end;
    ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
  end;
  CloseHandle(FSnapshotHandle);
end;

Open in new window

Avatar of Sinisa Vuk
Sinisa Vuk
Flag of Croatia image

- first you must find process id using EnumProcesses and compare started process module name with your exe file:

function FindExeProcess(sExe: String): Cardinal;
var
  PIDArray: array [0..1023] of DWORD;
  cb: DWORD;
  i, ProcCount: Integer;
  hMod: HMODULE;
  hProcess: THandle;
  ModuleName: array [0..300] of Char;
begin
  Result := 0;
  sExe := UpperCase(sExe);
  EnumProcesses(@PIDArray, SizeOf(PIDArray), cb); //get all process list
  ProcCount := cb div SizeOf(DWORD);
  
  for i := 0 to ProcCount - 1 do
  begin
    hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, PIDArray[i]);
    if (hProcess <> 0) then
    begin
      EnumProcessModules(hProcess, @hMod, SizeOf(hMod), cb);
      GetModuleFilenameEx(hProcess, hMod, ModuleName, SizeOf(ModuleName));
      if UpperCase(ModuleName) = sExe then
      begin
        Result := PIDArray[i];
      end;
      CloseHandle(hProcess);
      if Result > 0 then Break; //found it
    end;
  end;
end;

Open in new window


... and kill process by process id:
procedure KillProcess(hProcessID: Cardinal);
Var
  hProcess : THandle;
  ovExitCode : LongWord;
begin
  try
    if hProcessID<>0 then
    begin
      hProcess:=OpenProcess(PROCESS_TERMINATE, True, hProcessID);
      if hProcess<>0 then
      begin
        GetExitCodeProcess(hProcess, ovExitCode);
        TerminateProcess(hProcess, ovExitCode);
        CloseHandle(hProcess);
      end;
    end;
  except
  end;
end;

procedure TForm1.Button6Click(Sender: TObject);
var
  hPid: Cardinal;
begin
  hPid := FindExeProcess('C:\Program Files (x86)\Foxit Software\Foxit Reader\Foxit Reader.exe');
  if hPid > 0 then
    KillProcess(hPid);
end;

Open in new window

Avatar of Allan_Fernandes
Allan_Fernandes

ASKER

The code you have given works only within the User
check if function FindExeProcess get valid Pid (>0) for different user. Is running exe 64 bit? or 32bit?
try change:
const
  PROCESS_QUERY_LIMITED_INFORMATION = $1000;
...
hProcess := OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, False, PIDArray[i]);
...

Open in new window

Sorry that does not help either.
ASKER CERTIFIED SOLUTION
Avatar of Sinisa Vuk
Sinisa Vuk
Flag of Croatia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial