Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > TerminateProcess


Автор: Гость_Over G 18.8.2003, 16:55
Как закрыть процесс нужного файла ?

Если можно то функцию с описаниями, ато я в делфи полный профан.

Автор: p0s0l 18.8.2003, 17:05
Не проверял, но вот из FAQ:
Код
{ Эта небольшая функция закрывает приложения, соответствующие заданному имени .exe.  
 Пример: KillTask('notepad.exe');  
                 KillTask('iexplore.exe'); }  

uses  
 Tlhelp32, Windows, SysUtils;  

function KillTask(ExeFileName: string): integer;  
const  
 PROCESS_TERMINATE=$0001;  
var  
 ContinueLoop: BOOL;  
 FSnapshotHandle: 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  
     Result := Integer(TerminateProcess(OpenProcess(  
                       PROCESS_TERMINATE, BOOL(0),  
                       FProcessEntry32.th32ProcessID), 0));  
   ContinueLoop := Process32Next(FSnapshotHandle,  
                                 FProcessEntry32);  
 end;  

 CloseHandle(FSnapshotHandle);  
end;

Автор: 0FF 18.8.2003, 21:19
Знакомая трабла, сам с такой сталкнулся, ришение так и не нашел.

2 p0s0l
Этот пример действует только для Win9x тк там szFileName Возвращает путь к файлу + его имя.
И соответвенно можно написать killtask('c:\Folder\File.exe');

А в WinXP (и наверное в других виндах семейства Nt) такая тема не катит
тк, в WinXP szFileName - это не полный путь к файлу + его имя, а только его имя.
поэтому функция killtask('c:\Folder\File.exe'); не даст вообще ни какого результата.
только так killtask('File.exe'); но таким макаром будут убиты все одоимённые файлы.
А надо убить только один.

Автор: p0s0l 18.8.2003, 22:23
Теперь можно и с путем указывать и без пути:

Код
function KillTask (ExeFileName: string) : boolean;
var
 ssh1, ssh2 : THandle;
 pe32 : TProcessEntry32;
 me32 : TModuleEntry32;
begin
 result := false;
 ExeFileName := AnsiUpperCase(ExeFileName);

 ssh1 := CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0);
 pe32.dwSize := SizeOf(pe32);
 me32.dwSize := SizeOf(me32);

 if Process32First(ssh1, pe32) then
 repeat
   Result := ExeFileName = AnsiUpperCase(pe32.szExeFile);

   if not Result then
     if ExtractFileName(ExeFileName) = AnsiUpperCase(ExtractFileName(pe32.szExeFile)) then
     begin
       ssh2 := CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, pe32.th32ProcessID);
       if Module32First(ssh2, me32) then
       repeat
         if (ExeFileName = AnsiUpperCase(me32.szExePath)) then
         begin
           Result := true;
           Break;
         end;
       until not Module32Next(ssh2, me32);
       CloseHandle(ssh2);
     end;

   if Result then
   begin
     Result := TerminateProcess(OpenProcess(PROCESS_TERMINATE, false, pe32.th32ProcessID), 0);
     Break;
   end;
 until not Process32Next(ssh1, pe32);

 CloseHandle (ssh1);
end;


Проверял в Xp - убивает winamp.exe как с путем так и без пути...


Автор: 0FF 19.8.2003, 19:45
Первый break не нужен.

Автор: p0s0l 19.8.2003, 21:11
Цитата
Первый break не нужен.

Если найден модуль с нужным именем, то зачем искать дальше ?

Автор: Fantasist 19.8.2003, 21:21
Наверно имелось в виду:

Цитата
       
      repeat
          if (ExeFileName = AnsiUpperCase(me32.szExePath)) then
            Result := true;
      until (not Module32Next(ssh2, me32)) or (Result);


и break не нужен.

Автор: Fantasist 19.8.2003, 21:54
Правда тогда и второй break не нужен. Вместо:

Код

if Result then
  begin
    Result := TerminateProcess(OpenProcess(PROCESS_TERMINATE, false, pe32.th32ProcessID), 0);
    Break;
  end;
until not Process32Next(ssh1, pe32);


ставим:

Код

until (not Process32Next(ssh1, pe32)) or (Result);

if (Result) then
     Result := TerminateProcess(OpenProcess(PROCESS_TERMINATE, false, pe32.th32ProcessID), 0);

Автор: p0s0l 20.8.2003, 01:20
Ладно, ладно... Только такое ощущение, что писал не в форум, а в какой-то раздел "этюды"...
Сразу укорачивать и упрощать начали... smile

Автор: p0s0l 20.8.2003, 01:39
И если уж дело дошло до этого, то мой вариант (с break) и быстрее, и меньше памяти занимает: smile
(это то что компилит Delphi 7.0)

Вариант с break:
Код

mov bl, $01       // Result := true
jmp +$11          // Break   
lea edx, [ssh2]   // 
mov eax, edi      // edi = offset me32
call Module32Next //
test eax, eax     //
jnz -$4c          // until 


А если делать без break, длина +5 байт:
Код

mov bl, $01       // Result := true
lea edx, [ssh2]
mov eax, edi
call Module32Next
cmp eax, $01
sbb eax, eax
neg eag
or al, bl         // or Result
jz -$51           // until 


И если уж решили делать без break'а, то until надо делать таким: until Result or (not Module32Next...);
Таким образом длина -2 байта:
Код

test bl, bl       // проверям Result
jnz +$11          // и сразу же выход из цикла, если Result = true
lea edx, [ssh2]
mov eax, edi
call Module32Next
test eax, eax
jnz -$4e          // until


smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)