Убить процесс

Clarion, Clarion 7

Модератор: Дед Пахом

Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
Ответить
NewUser
Старожил
Сообщения: 238
Зарегистрирован: 10 Ноябрь 2005, 23:07
Откуда: Краснодар
Благодарил (а): 6 раз

Убить процесс

Сообщение NewUser »

Подскажите, пожалуйста, как напрочь втихую (что бы не выскакивало окно предупреждения) убить процесс в Винде (ХР, Виста, 7) посредством API?
Что лучше использовать:
CloseHandle
TerminateApp
TerminateProcess
TerminateThread
если известно только имя процесса?

Вообще-то надо, по-хорошему, наверное, проверить существует ли такой процесс, и в случае удачи - закилить его.
Может у кого есть рабочий код (с декларированием прототипов)?
Yufil
Ветеран движения
Сообщения: 1277
Зарегистрирован: 16 Май 2006, 14:34
Контактная информация:

Re: Убить процесс

Сообщение Yufil »

FreeABC Templates включает процедуру убивания процесса по имени (глобальный шаблон API:Terminate a Process)
Вполне самодостаточно, а при необходимости можно и на код поглядеть...
Аватара пользователя
WadimZapara
Активист
Сообщения: 181
Зарегистрирован: 11 Июнь 2008, 12:11
Откуда: Тамбов

Re: Убить процесс

Сообщение WadimZapara »

А админские права-то есть?
Компьютер имеет то преимущество перед мозгом, что им пользуются...
NewUser
Старожил
Сообщения: 238
Зарегистрирован: 10 Ноябрь 2005, 23:07
Откуда: Краснодар
Благодарил (а): 6 раз

Re: Убить процесс

Сообщение NewUser »

Yufil писал(а):FreeABC Templates включает процедуру убивания процесса ...
Спасибо, Юрий!
Нашел, прикрутил - заработало. Но..
Код этого шаблона не убивает процесс, и даже не прерывает его, а всего лишь завершает. Приметно тоже самое, что нажать на крестик в правом верхнем углу окна - абсолютно бесполезное действие, если приложение зависло. Или обрабатывает данные из другого приложения. Или ...
Одним словом не подошло мне действие данного шаблона. :(
NewUser
Старожил
Сообщения: 238
Зарегистрирован: 10 Ноябрь 2005, 23:07
Откуда: Краснодар
Благодарил (а): 6 раз

Re: Убить процесс

Сообщение NewUser »

WadimZapara писал(а):А админские права-то есть?
Да. Работаю под администратором.
Аватара пользователя
morkovin
Ветеран
Сообщения: 935
Зарегистрирован: 20 Июль 2005, 14:53
Откуда: Volgograd, Russia
Благодарил (а): 9 раз
Поблагодарили: 4 раза
Контактная информация:

Re: Убить процесс

Сообщение morkovin »

Подскажите, пожалуйста, как напрочь втихую (что бы не выскакивало окно предупреждения) убить процесс
Просто вызвать из своей программы утилиту KillProcess (http://www.par2.com/cws/c5launch.dll?5C9B1D06/D7.htm)
WBR, morkovin
Аватара пользователя
morkovin
Ветеран
Сообщения: 935
Зарегистрирован: 20 Июль 2005, 14:53
Откуда: Volgograd, Russia
Благодарил (а): 9 раз
Поблагодарили: 4 раза
Контактная информация:

Re: Убить процесс

Сообщение morkovin »

Подскажите, пожалуйста, как напрочь втихую (что бы не выскакивало окно предупреждения) убить процесс
Просто вызвать из своей программы утилиту KillProcess
Правильная ссылка : http://www.par2.com (раздел Download)
WBR, morkovin
NewUser
Старожил
Сообщения: 238
Зарегистрирован: 10 Ноябрь 2005, 23:07
Откуда: Краснодар
Благодарил (а): 6 раз

Re: Убить процесс

Сообщение NewUser »

morkovin писал(а):Просто вызвать из своей программы утилиту KillProcess
Спасибо, утилита работает просто убойно!
Аватара пользователя
WadimZapara
Активист
Сообщения: 181
Зарегистрирован: 11 Июнь 2008, 12:11
Откуда: Тамбов

Re: Убить процесс

Сообщение WadimZapara »

Делюсь кодом убиения процесса по имени под любой виндой:

Код: Выделить всё

   !PROGRAM
   !MEMBER
INFINITE  EQUATE(0FFFFFFFFh) ! бесконечное ожидание

! цели открытия процесса
PROCESS_TERMINATE           Equate(00000001h)
PROCESS_VM_READ             EQUATE(00000010h)
PROCESS_QUERY_INFORMATION   EQUATE(00000400h)
!

! ПЕРЕМЕННЫЕ - ХРАНИТЕЛИ АДРЕСА ФУНКЦИЙ, КОТОРЫЕ МОГУТ БЫТЬ, А МОГУТ ОТСУТСТВОВАТЬ
! из psapi.dll
PSAPI_dll           Unsigned,Static    !handle
EnumProcesses       ULong(0),Static,Name('MeEnumProcesses')
EnumProcessModules  ULong(0),Static,Name('MeEnumProcessModules')
GetModuleFileNameEx ULong(0),Static,Name('GetModuleFileNameEx')

! из kernel32.dll
kernel32_dll             Unsigned,Static  !handle
CreateToolhelp32Snapshot ULong(0),Static,Name('MeCreateToolhelp32Snapshot')
Process32First           ULong(0),Static,Name('MeProcess32First')
Process32Next            ULong(0),Static,Name('MeProcess32Next')

  MAP
      Module('')
         ! Эти функции присутствуют не во всех ОС, поэтому вызываются посредством 
         ! попытки загрузки модуля, выборки адреса и присвоения этого адреса ULONG-переменным с тем же атрибутом Name()

         ! из kernel32.dll. Имеются в Win98/Win2k/Win2k3/WinXP
         ! В Win-NT этих функций нет, поэтому их адреса будут вычислены динамически
         CreateToolhelp32Snapshot(ULong dwFlags, Ulong th32ProcessID), Long, Raw,Pascal,DLL(TRUE),Name('MeCreateToolhelp32Snapshot')
         Process32First(Long hSnapshot, ULong Addr_lppe), BOOL, Raw,Pascal,DLL(TRUE),Name('MeProcess32First')
         Process32Next(Long hSnapshot, ULong Addr_lppe), BOOL, Raw,Pascal,DLL(TRUE),Name('MeProcess32Next')

         ! из PSAPI.dll. Имеются в Win2k/Win2k3/WinXP, при установке этой dll - в WinNT
         !               В Win-98 нет
         EnumProcesses(ULong AddrArrProcessIds, ULong LenBytes_Arr, *ULong BytesWrite), |
                                            BOOL,PASCAL,DLL(TRUE),Name('MeEnumProcesses')
         EnumProcessModules(UnSigned hProcess, ULong AddrArrModuleHandle, ULong LenBytes_Arr, *ULong BytesWrite), |
                                            BOOL,PASCAL,DLL(TRUE),Name('MeEnumProcessModules')
         GetModuleFileNameEx(UnSigned hProcess, UnSigned hModule=0, *CString Filename, ULong nSizeFilename), |
                                            ULong, PASCAL,RAW,DLL(TRUE),Name('GetModuleFileNameEx'),Proc
      End
      MODULE('Windows.DLL')
         GetLastError(),DWORD,PASCAL,Dll(TRUE)
         GetModuleHandle(*CString NameOfModule), UnSigned, RAW,Pascal,DLL(TRUE),Name('GetModuleHandleA')
         LoadLibrary(*CString NameLibrary), UnSigned,RAW,Pascal,DLL(TRUE),Name('LoadLibraryA')
         FreeLibrary(UnSigned handle),BOOL, RAW,Pascal,DLL(TRUE)
         GetProcAddress(UnSigned handle, *CString NameFunction), ULong,Raw,Pascal,DLL(TRUE)
         OpenProcess(ULong dwDesiredAccess, BOOL bInheritHandle, UnSigned dwProcessId), UnSigned, Raw,Pascal,DLL(TRUE)
         TerminateProcess(UnSigned hProcess,  ULong SecurCodes), BOOL, Raw,Pascal,DLL(TRUE), Proc
         WaitForSingleObject(UnSigned handle, ULong TimeOut_ms),ULong, Raw,Pascal,DLL(TRUE), Proc
         CloseHandle(UnSigned Handle), BOOL, Raw,Pascal,DLL(TRUE), Proc
      END
  END

  MAP
     HandleOpenProcess32(String ExeName, ULong DesiredAccess=0, <*CString FullPath>), UnSigned
     KillProcess32(UnSigned HandleProcess, Byte bWait=TRUE), Long
! Вспомогательные функции
     SetAddrFuncFromLib(String NameOfLibrary, String NameOfFunction, *UnSigned HandleLib, *ULong FuncAddr), Long
     ClearHandleLib(*UnSigned hLib), Long, Proc
     ULONG_FromAddr(ULong addr), ULONG
  END

  CODE

!======================================================================================
HandleOpenProcess32     Function(String ExeName, ULong DesiredAccess=0, <*CString FullPath>) !, UnSigned
TH32CS_SNAPPROCESS      Equate(2)
HSnap               Long,Auto

pe                  Group
dwSize                Long(296)          !   0          4
cntUsage              Long               !   4          8
th32ProcessID         ULong              !   8         12
th32DefaultHeapID     ULong              !  12         16
th32ModuleID          ULong              !  16         20
cntThreads            Long               !  20         24
th32ParentProcessID   ULong              !  24         28
pcPriClassBase        Long               !  28         32
dwFlags               ULong              !  32         36
szExeFile             CString(256)       !  36        292
empty_                Long               !  292       296
                    End

HandleProcess   UnSigned(0)
UpExeName       CString(256)
ok              Byte(FALSE)
buff  &String
ul    ULong
us    UnSigned
err   Long(0)
!======================================================================================
  CODE
  UpExeName = '\'& Upper(Clip(ExeName))
  DesiredAccess = BOR(DesiredAccess, PROCESS_QUERY_INFORMATION + PROCESS_VM_READ)

  IF ~PSAPI_DLL THEN
    HSnap = SetAddrFuncFromLib('PSAPI.DLL', 'EnumProcesses', PSAPI_DLL, EnumProcesses)
    If ~HSnap Then
      SetAddrFuncFromLib('PSAPI.DLL', 'EnumProcessModules', PSAPI_DLL, EnumProcessModules)
      SetAddrFuncFromLib('PSAPI.DLL', 'GetModuleFileNameExA', PSAPI_DLL, GetModuleFileNameEx)
    End
  END

  IF EnumProcesses THEN       ! для NT
    hsnap = 512 * 4;  buff &= New(String(hsnap))
    Loop While EnumProcesses(Address(buff), hsnap, ul)
      If ul = hsnap Then
        Dispose(buff)
        hsnap *= 2;  buff &= New(String(hsnap))
      Else
        Break
      End
    End
    ul /= 4
    pe.dwflags = Address(buff)
    Loop hsnap = 1 To ul
      pe.th32ProcessID = ULONG_FromAddr(pe.dwflags)
      HandleProcess = OpenProcess(DesiredAccess, FALSE, pe.th32ProcessID)
      If HandleProcess Then
        GetModuleFileNameEx(HandleProcess, , pe.szExeFile, Size(pe.szExeFile))    ! в pe.szExeFile получаем полное имя exe
        if InString(UpExeName, Upper(pe.szExeFile), 1, 1) then  ok += 1; Break.
        CloseHandle(HandleProcess)
      End !If HandleProcess 
      pe.dwflags += 4
    End !Loop hsnap = 
    Dispose(buff)
    If ~ok Then Clear(HandleProcess).
  ELSIF CreateToolhelp32Snapshot Or ~kernel32_dll THEN  !есть адрес CreateToolhelp32Snapshot или нет handle'a kernel32.dll
    If ~kernel32_dll Then
      pe.szExeFile = 'KERNEL32.DLL';  kernel32_dll = GetModuleHandle(pe.szExeFile)  ! получили handle kernel32.dll
      if kernel32_dll then
        pe.szExeFile = 'CreateToolhelp32Snapshot';  CreateToolhelp32Snapshot = GetProcAddress(kernel32_dll, pe.szExeFile)
        pe.szExeFile = 'Process32First';            Process32First           = GetProcAddress(kernel32_dll, pe.szExeFile)
        pe.szExeFile = 'Process32Next';             Process32Next            = GetProcAddress(kernel32_dll, pe.szExeFile)
      end !if
    End !If ~kernel32_dll
    If CreateToolhelp32Snapshot Then
      ! 1. Проверяем все процессы в системе: ищем PID
      HSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
      If HSnap = -1 Then Return(0).
      HandleProcess = Process32First(HSnap, Address(pe.dwSize))
      Loop While HandleProcess
        If InString(UpExeName, Upper(pe.szExeFile), 1, 1) Then Break.                ! в pe.szExeFile получаем имя exe
        HandleProcess = Process32Next(HSnap, Address(pe.dwSize))
      End
      CloseHandle(HSnap)
      ! 2. Если PID получен, получаем HANDLE с заданным разрешением
      If HandleProcess Then  HandleProcess = OpenProcess(DesiredAccess, FALSE, pe.th32ProcessID).
    End !IF CreateToolhelp32Snapshot
  END !IF
  If ~Omitted(3) And HandleProcess Then FullPath = pe.szExeFile.
  RETURN(HandleProcess)
!=========================================================================================


!=========================================================================================
KillProcess32          FUNCTION(UnSigned HandleProcess, Byte bWait=TRUE) !, Long
err  Long(0)
!=========================================================================================
 CODE
   IF ~TerminateProcess(HandleProcess, 0) THEN
     err = GetLastError()
   ELSIF bWait THEN
     WaitForSingleObject(HandleProcess, INFINITE)
   END
   CloseHandle(HandleProcess)
 RETURN(err)
!=========================================================================================

!=========================================================================================
SetAddrFuncFromLib Function(String NameOfLibrary, String NameOfFunction, *UnSigned hLib, *ULong FuncAddr) !,Long
err Long(0)
Cs  CString(256),Auto
!=========================================================================================
  Code
    IF ~FuncAddr Or ~hlib THEN
      If ~hlib Then
        Cs = NameOfLibrary;  hlib = LoadLibrary(Cs)
        if ~hlib then err = GetLastError().
      End
      If hlib Then
        Cs = NameOfFunction;  FuncAddr = GetProcAddress(hlib, Cs)
        if ~FuncAddr then err = GetLastError().
      End !If hlib 
    END !IF ~FuncAddr 
  Return(err)

!=========================================================================================
ClearHandleLib  Function(*UnSigned hLib) !,Long
err Long(0)
!=========================================================================================
 Code
   If hLib Then 
     if ~FreeLibrary(hlib) then err = GetLastError().
     Clear(hLib)
   End
 Return(err)

!==========================================================================================
ULONG_FromAddr       FUNCTION (ULong addr) !, ULONG
!==========================================================================================
! Реализует возврат значения по указателю.
! На входе: addr    - адрес значения
! Следующие структуры используют одно и то же место в памяти
! и реализуют получение по адресу значения

AddressX  Group                 ! адрес на значение переменной
addrX       ULong,Auto
lng         ULong(4)
          End
pLong     Group,Over(AddressX)    ! ссылка на ULong
_long       &ULong
          End
  CODE 
  AddressX.addrX = addr
  Return(pLong._long)
!======================================================================================
Пример применения:

Код: Выделить всё

HandleProcess UnSigned
FullName      CString(1024)
err           Long,Auto
bWait         Byte(2)
  Code
  HandleProcess = HandleOpenProcess32('MyName.Exe', PROCESS_TERMINATE, FullName)
! если не интересен маршрут можно не передавать параметр FullName, то есть вызов:
! HandleProcess = HandleOpenProcess32('MyName.Exe', PROCESS_TERMINATE)
  IF ~HandleProcess Then 
    Message('Процесс MyName.Exe открыть для убийства не удалось - или он не запущен, или нет прав')
  ELSE
    Execute Message('Убить с ожиданием?', 'Ваш выбор?', ICON:Question, 'Ждать|Нет|Отмена')
      bWait = TRUE
      bWait = FALSE
    End !Execute
    If bWait = 2 Then
      Message('Вы решили не убивать процесс MyName.Exe')
    Else
      err = KillProcess32(HandleProcess, bWait)
      if err then
        Message('Процесс MyName.Exe убить не удалось, код ошибки API '& err)
      elsif bWait then
        Message('Процесс MyName.Exe уже убит. Полный маршрут Файла: '& FullName)
      else
        Message('Успешно запущено убиение процесса MyName.Exe. Полный маршрут Файла: '& FullName)
      end !if
    End !If
  END !IF
! Если это продолжение кода программы, приведённой выше, следует освободить при ненужности
! задействованной библиотеки PSAPI.dll или kernel32.dll, которая была загружена с помощью LoadLibrary
  IF PSAPI_dll THEN                 ! освободить Handle PSAPI.dll
    ClearHandleLib(PSAPI_dll)
  ELSIF kernel32_dll THEN           ! освободить Handle kernel32.dll
    ClearHandleLib(kernel32_dll)
  END !IF
Компьютер имеет то преимущество перед мозгом, что им пользуются...
NewUser
Старожил
Сообщения: 238
Зарегистрирован: 10 Ноябрь 2005, 23:07
Откуда: Краснодар
Благодарил (а): 6 раз

Re: Убить процесс

Сообщение NewUser »

Спасибо, Вадим! На будущее - это самое то. Судя по представленному коду - процесс полностью управляем и контролируем.
Ответить