Форум: "WinAPI";
Текущий архив: 2006.02.12;
Скачать: [xml.tar.bz2];
ВнизКак завершить процесс, зная откуда он запущен? Найти похожие ветки
← →
Volf_555 (2005-11-27 01:48) [0]Как завершить процесс, зная откуда он запущен?
(Именно по пути!)
← →
gdaujk © (2005-11-27 07:05) [1]
function GetIdFileName(Id: DWORD; lpName: PChar; Size: Cardinal): Boolean;
var
ProcH: THandle;
ModH: HMODULE;
Count: Cardinal;
begin
Result := False;
ProcH := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, Id);
if ProcH <> 0 then
begin
EnumProcessModules(ProcH, @ModH, SizeOf(ModH), Count);
if GetModuleFileNameEx(ProcH, ModH, lpName, Size) > 0
then Result := True;
end;
CloseHandle(ProcH);
end;
EnumProcesses(@ID, SizeOf(ID), Count);
...
if OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, TokenH) then
if LookupPrivilegeValue(nil, "SeDebugPrivilege", Luid) then
begin
with TokenPriv do
begin
PrivilegeCount := 1;
Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
Privileges[0].Luid := luid;
end;
AdjustTokenPrivileges(TokenH, false, TokenPriv, 0, nil, ReturnLen);
end;
for i := 0 to (Count div SizeOf(DWORD)) - 1 do
if GetIdFileName(ID[i], ModName, SizeOf(ModName))...
И тому подобное. В общем, адо перебрать все запущенные процессы, у каждого узнать путь, и если нужный путь найден, то TerminateProcess. Используй PSAPI.pas
← →
Volf_555 (2005-11-29 02:32) [2]а точнее?
← →
01e9 (2005-11-30 00:25) [3]точнее только готовый проект твоей проги)))
← →
Zeqfreed © (2005-11-30 15:12) [4]Volf_555 (29.11.05 2:32) [2]
function KillWinNTProcessByName(const FullName : String) : Boolean;
type
TPIDArray = array[0..0] of DWORD;
var
PIDs : Pointer;
PIDl : Cardinal;
cb: DWORD;
hProcess: THandle;
ModuleName: array [0..MAX_PATH] of Char;
i : Integer;
begin
try
Result := false;
PIDl := 200;
GetMem(PIDs, PIDl * SizeOf(DWORD));
for i := 0 to 10 do begin
if (i = 10) then raise Exception.Create("The program got tired with increasing the buffer for process IDs!");
EnumProcesses(PIDs, PIDl, cb);
if (cb <= PIDl) then Break;
FreeMem(PIDs);
Inc(PIDl, Round(PIDl * 0.3));
GetMem(PIDs, PIDl);
end;
if (cb <= 0) then raise Exception.Create("Obviously, process enumeration failed");
for i := 0 to (cb div SizeOf(DWORD)) do begin
hProcess := OpenProcess(PROCESS_TERMINATE or PROCESS_VM_READ or PROCESS_QUERY_INFORMATION, false, TPIDArray(PIDs^)[i]);
if (hProcess <> 0) then begin
GetModuleFilenameEx(hProcess, 0, ModuleName, MAX_PATH);
if (AnsiLowerCase(ModuleName) = AnsiLowerCase(FullName)) then begin
Result := TerminateProcess(hProcess, 0);
Exit;
end;
CloseHandle(hProcess);
end;
end;
finally
FreeMem(PIDs);
end;
end;
Достаточно точно?
← →
Zeqfreed © (2005-11-30 15:25) [5]Zeqfreed © (30.11.05 15:12) [4]
Упс. Извиняюсь, но цикл должен выглядеть вот так:for i := 0 to 10 do begin
if (i = 10) then raise Exception.Create("The program got tired with increasing the buffer for process IDs!");
EnumProcesses(PIDs, PIDl * SizeOf(DWORD), cb);
if (cb div SizeOf(DWORD) < PIDl) and (cb > 0) then Break;
FreeMem(PIDs);
Inc(PIDl, Round(PIDl * 0.3));
GetMem(PIDs, PIDl * SizeOf(DWORD));
end;
← →
gdaujk © (2005-12-01 00:35) [6]Zeqfreed © (30.11.05 15:25) [5]
Как альтернатива вашему циклу:function gdaEnumProcesses(var lpidProcess: Pointer): Cardinal;
const
IdArraySize = $4FF;
var
IdArray: array[0..IdArraySize - 1] of DWORD;
begin
EnumProcesses(@IdArray, IdArraySize * SizeOf(DWORD), Result);
lpidProcess := VirtualAlloc(nil, Result, MEM_COMMIT, PAGE_READWRITE);
CopyMemory(lpidProcess, @IdArray, Result);
end;
procedure gdaFreeProcesses(lpidProcess: Pointer);
begin
VirtualFree(lpidProcess, 0, MEM_RELEASE);
end;
А за TPIDArray спасибо. Ни разу не пользовался такими конструкциями.
PS: Размер $4FF (1024) (как и идея большого массива) взят из Micro$oft"овского примера. Получается размер IdArray равен 32 kB, что не так уж и много...
← →
gdaujk © (2005-12-01 00:40) [7]М-да, поспешишь - людей насмешишь. По самым последним подсчётам :-))) размер IdArray равен 4 kB, что ишшо меньше...
PS: интересно, может реально быть запущено 1024 процесса??? У меня щас ~ 20...
← →
Zeqfreed © (2005-12-01 11:10) [8]gdaujk © (01.12.05 0:35) [6]
Я щас туго соображаю, но просмотрев код я пришёл к выводу, что это не аналог моего цикла, который, согласно справке, увеличивает буфер при необходимости.
gdaujk © (01.12.05 0:40) [7]
> PS: интересно, может реально быть запущено 1024
> процесса??? У меня щас ~ 20...
Это наверно имеются в виду те, которые отображает Task Manager? У меня EnumProcesses возвращала около 200 процессов. Насчет ограничения количества процессов не знаю, искать не стану :)
← →
gdaujk © (2005-12-01 11:45) [9]>Zeqfreed © (01.12.05 11:10) [8]
согласно справке, увеличивает буфер при необходимости.
А согласно тому, что делает моя процедура, на выходе получается массив lpidProcess, точно (в противоположность вашему "примерно") подходящий под содержание того числа pID"ов, которое запущенно в системе. А при большем, чем 200, колличестве процессов, ваш цикл наверное, ещё и дольше работать будет...
У меня EnumProcesses возвращала около 200 процессов.
200 процессов, или бит, помещённых в PIDs (cb)?
Насчет ограничения количества процессов...
Я не про гипотетическое, я про среднестатистическое :-))
← →
Zeqfreed © (2005-12-01 12:16) [10]gdaujk © (01.12.05 11:45) [9]
> 200 процессов, или бит, помещённых в PIDs (cb)?
Процессов.
> на выходе получается массив lpidProcess, точно (в
> противоположность вашему "примерно") подходящий под
> содержание того числа pID"ов, которое запущенно в
> системе.
А если воспользоваться [6] в то время, когда в системе запущено 1280 процессов?
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/perfmon/base/enumprocesses.asp
To determine how many processes were enumerated, divide the pBytesReturned value by sizeof(DWORD). There is no indication given when the buffer is too small to store all process identifiers. Therefore, if pBytesReturned equals cb, consider retrying the call with a larger array.
← →
gdaujk © (2005-12-01 13:23) [11]Zeqfreed © (01.12.05 12:16) [10]
Мне, кажется, это написано на тот случай, если разроботчик (девелопер :-))) вдруг решит использовать буфер, например, в 5 элементов. Почему-то же не использованно наращивание массива в примере
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/perfmon/base/enumerating_all_processes.asp
На крайний случай - 1280 процессов (!!!) - можно в моём примере IdArraySize приравнять $FFF (16 кБ - 4096 элементов - процессов), или, в рассчёте на пользователя экстримала, ещё на порядок больше :-). Я считаю, что лучше один раз выделить на малое время большой (относительно) кусок памяти, чем несколько раз (при большом количестве запущенных процессов) производить операции, описаные вами в цикле. К слову, в вашем примере max число процессов тоже ограничено (~2757).
Кстати, можно предположить, что среди 1280 :-) процессов найдётся несколько (напрмер 128) запущенных из одного места. Автор все собирается терминатить?
PS: А где автор?
← →
Zeqfreed © (2005-12-02 12:57) [12]gdaujk © (01.12.05 13:23) [11]
Наконец-то снова имею возможность быть онлайн, чему несказанно рад. Ну это было лирическое отступление :)
> К слову, в вашем примере max число процессов тоже
> ограничено (~2757).
Для того чтобы этого избежать нужно всего-лишь изменить цикл, единожды. В вашем коде нужно менять константу каждый раз, когда появляется необходимость перечислять большее кол-во процессов.
> Автор все собирается терминатить?
Почему нет?
p.s.
А вообще, я не нахожу эту тему настолько интересной чтобы мусолить её из поста в пост.
← →
gdaujk © (2005-12-02 21:52) [13]>Zeqfreed © (02.12.05 12:57) [12]
>p.s.
Точно :-)
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2006.02.12;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.044 c