Witam,
Natrafiłem ostatnio na dość użyteczną do moich celów funkcję:
procedure KillProcessHWND(hWindowHandle: HWND);
var
hprocessID: INTEGER;
processHandle: THandle;
DWResult: DWORD;
begin
SendMessageTimeout(hWindowHandle, WM_CLOSE, 0, 0,
SMTO_ABORTIFHUNG or SMTO_NORMAL, 5000, DWResult);
if isWindow(hWindowHandle) then
begin
{ Get the process identifier for the window}
GetWindowThreadProcessID(hWindowHandle, @hprocessID);
if hprocessID <> 0 then
begin
{ Get the process handle }
processHandle := OpenProcess(PROCESS_TERMINATE or PROCESS_QUERY_INFORMATION,
False, hprocessID);
if processHandle <> 0 then
begin
{ Terminate the process }
TerminateProcess(processHandle, 0);
CloseHandle(ProcessHandle);
end;
end;
end;
end;
Oraz
function enumcallback(h:HWND;l:LPARAM):bool;stdcall;
var
i:integer;
p:array of char;
begin
enumcallback:=true;
i:=GetWindowTextLength(h)+1;
SetLength(p,i);
GetWindowText(h,pchar(p),i);
if pos('Kalk',pchar(p))>0 then
begin
HWND(pointer(l)^):=h;
KillProcessHWND(h);
enumcallback:=false;
end;
SetLength(p,0);
end;
Wywołanie:
EnumWindows(@enumcallback,LPARAM(@czatwin));
Pierwsza funkcja ma za zadanie zabicie procesu po uchwycie okna, który przekazany jest przez funkcję drugą.
Obie funkcje działają prawidłowo na koncie z uprawnieniami administratora – i tylko tam.
Problem polega na tym, że aplikacja ma działać na koncie użytkownika z ograniczonymi uprawnieniami.
Logika podpowiada, że wystarczy uruchomić program z uprawnieniami systemowymi i problem powinien się rozwiązać. Sam program nie mógł działać jako usługa ponieważ zarówno wbudowana funkcja FundWindow (z której właśnie dlatego zrezygnowałem) jak i (jeśli dobrze pamiętam) funkcja druga nie działały prawidłowo – czytać wcale (prawdopodobnie przeszukiwane były tylko nazwy w obrębie usług a nie wszystkich procesów). Dlatego napisałem prostą usługę uruchamiającą program z ww funkcjami a dziedziczenie uprawnień w systemie windows generalnie powinno załatwić problem. Ale nic z tego. Tutaj już nie sprawdzałem czy funkcja szukająca nazwy okna czy zabijająca proces nie działa ponieważ efekt z punktu widzenia użytkownika pozostawał niezmienny. Ostatnim pomysłem było wykorzystanie systemowej komendy runas i odpalenie programu jako użytkownik z uprawnieniami administratora... I tu już zupełnie zgłupiałem bo niby wszystko działa ale funkcja, która powinna zabić proces po prostu go minimalizuje... Jakieś pomysły? Krócej się chyba nie dało ;-)
Jak ktoś coś wymyśli to dzięki piękne za pomoc.
Pozdrawiam.
//edit: usunąłem śmiecie w funkcji.