В Может ли приложение узнать какие программы в настоящее время запущены?
В. Может ли приложение узнать, какие программы в настоящее время запущены?
Да. В основу метода положено использование функции EnumWindows (т.е. пересчитать окна). Вот параметры этой функции.
Сама вызываемая процедура получает два параметра: дескриптор найденного окна и определенный выше параметр. По известному дескриптору с помощью функции GetWindowThreadProcessId можно определить уникальный идентификатор процесса или потока, который владеет данным окном. Имея же идентификатор, мы можем, в частности, удалить данный процесс из памяти с помощью функции TerminateProcess (впрочем, будьте осторожнее).
Ниже на Рисунок 3.5.4 представлен пример программы, выдающей список работающих процессов. Обратите внимание на использование функции GetWindowText, которая определяет текст заголовка окна. Не пугайтесь, что в списке будут представлены и те процессы, окна которых мы не видим. Окна, как известно, могут быть скрытыми. Заметьте, что в список попадают и консольные приложения. Программа определяет также уникальные идентификаторы процессов.
// файл proc.rc // определение констант
#define WS_SYSMENU 0x00080000L #define WS_MINIMIZEBOX 0x00020000L #define WS_VISIBLE 0x10000000L #define WS_TABSTOP 0x00010000L #define WS_VSCROLL 0x00200000L #define WS_HSCROLL 0x00100000L #define DS_3DLOOK 0x0004L #define LBS_NOTIFY 0x000lL #define LBS_SORT 0x0002L
// идентификаторы #define LIST1 101
// определение диалогового окна DIAL1 DIALOG 0, 0, 220, 110 STYLE WS_SYSMENU | WS_MINIMIZEBOX | DS_3DLOOK CAPTION "Поиск процессов" FONT 8, "Arial" { CONTROL "ListBox1", LIST1, "listbox", WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | WS_HSCROLL | LBS_NOTIFY, 16, 16, 190, 75 }
; файл proc.inc ; константы ; значения, возвращаемые функцией GetDriveType ; значения 0 и 1 можно считать признаком отсутствия устройства
DRIVE_REMOVABLE equ 2 ; накопитель на гибком диске DRIVE_FIXED equ 3 ; устройство жесткого диска DRIVE_REMOTE equ 4 ; сетевой диск DRIVE_CDROM equ 5 ; накопитель на лазерном диске DRIVE_RAMDISK equ 6 ; электронный диск
; сообщение приходит при закрытии окна WM_CLOSE equ 10h WM_INITDIALOG equ 110h WM_COMMAND equ 111h LB_ADDSTRING equ 180h LB_RESETCONTENT equ 184h WM_LBUTTONDOWN equ 201h
; прототипы внешних процедур IFDEF MASM EXTERN wsprintfA:NEAR EXTERN GetWindowThreadProcessId@8:NEAR EXTERN GetWindowTextA@12:NEAR EXTERN EnumWindows@8:NEAR EXTERN lstrcat@8:NEAR EXTERN ExitProcess@4:NEAR EXTERN GetModuleHandleA@4:NEAR EXTERN DialogBoxParamA@20:NEAR EXTERN EndDialog@8:NEAR EXTERN SendDlgItemMessageA@20:NEAR ELSE EXTERN _wsprintfA:NEAR EXTERN GetWindowThreadProcessId:NEAR EXTERN GetWindowTextA@12:NEAR EXTERN EnumWindows:NEAR EXTERN lstrcat:NEAR EXTERN ExitProcess:NEAR EXTERN GetModuleHandleA:NEAR EXTERN DialogBoxParamA:NEAR EXTERN EndDialog:NEAR EXTERN SendDlgItemMessageA:NEAR
wsprintfA = _wsprintfA GetWindowThreadProcessId@8 = GetWindowThreadProcessId GetWindowTextA@12 = GetWindowTextA EnumWindows@8 = EnumWindows lstrcat@8 = lstrcat ExitProcess@4 = ExitProcess GetModuleHandleA@4 = GetModuleHandleA DialogBoxParamA@20 = DialogBoxParamA EndDialog@8 = EndDialog SendDlgItemMessageA@20 = SendDlgItemMessageA ENDIF
; структуры ; структура сообщения MSGSTRUCT STRUC MSHWND DD ? MSMESSAGE DD ? MSWPARAM DD ? MSLPARAM DD ? MSTIME DD ? MSPT DD ? MSGSTRUCT ENDS
; файл proc.asm .386P ; плоская модель .MODEL FLAT, stdcall include proc.inc ; директивы компоновщику для подключения библиотек IFDEF MASM includelib c:\masm32\lib\user32.lib includelib c:\masm32\lib\kernel32.lib ELSE includelib c:\tasm32\lib\import32.lib ENDIF ;------------------------------------------------- ; сегмент данных _DATA SEGMENT DWORD PUBLIC USE32 'DATA' MSG MSGSTRUCT <?> HINST DD 0 ; дескриптор приложения PA DB "DIAL1",0 BUFER DB 200 DUP (0) BUF DB 20 DUP (0) FORM DB ";%lu",0 IDP DD ? HWN DD ? _DATA ENDS
; сегмент кода _TEXT SEGMENT DWORD PUBLIC USE32 'CODE' START: ; получить дескриптор приложения PUSH 0 CALL GetModuleHandleA@4 MOV [HINST], EAX ;--------------------------------------- PUSH 0 PUSH OFFSET WNDPROC PUSH 0 PUSH OFFSET PA PUSH [HINST] CALL DialogBoxParamA@20 CMP EAX,-1 JNE KOL ; сообщение об ошибке KOL: ;--------------------------------------- PUSH 0 CALL ExitProcess@4 ;---------------------------------------
; процедура окна ; расположение параметров в стеке ; [EBP+014Н] ;LPARAM ; [EBP+10Н] ;WAPARAM ; [EBP+0CH] ;MES ; [EBP+8] ;HWND WNDPROC PROC PUSH EBP MOV EBP,ESP PUSH EBX PUSH ESI PUSH EDI ;------------------------- CMP DWORD PTR [EBP+0CH],WM_CLOSE JNE L1 PUSH 0 PUSH DWORD PTR [EBP+08H] CALL EndDialog@8 JMP FINISH L1: CMP DWORD PTR [EBP+0CH],WM_INITDIALOG JNE FINISH ; запомним дескриптор окна MOV EAX,DWORD PTR [EBP+08H] MOV HWN,EAX ; вызвать функцию EnumWindows PUSH 1 ; неиспользуемый параметр PUSH OFFSET PENUM CALL EnumWindows@8 FINISH: MOV EAX,0 POP EDI POP ESI POP EBX POP EBP RET 16 WNDPROC ENDP
; процедура обратного вызова, вызываемая при поиске окон ; [EBP+0CH] ; параметр ; [EBP+8] ; дескриптор окна PENUM PROC PUSH EBP MOV EBP,ESP ; получить заголовок окна PUSH 200 PUSH OFFSET BUFER PUSH DWORD PTR [EBP+8] CALL GetWindowTextA@12 ; получить идентификатор процесса или потока, ; владеющего окном PUSH OFFSET IDP PUSH DWORD PTR [EBP+8] CALL GetWindowThreadProcessId@8 ; сформировать строку для списка PUSH OFFSET IDP PUSH OFFSET FORM PUSH OFFSET BUF CALL wsprintfA ADD ESP,12 PUSH OFFSET BUF PUSH OFFSET BUFER CALL lstrcat@8 ; добавить в список PUSH OFFSET BUFER PUSH 0 PUSH LB_ADDSTRING PUSH 101 PUSH [HWN] CALL SendDlgItemMessageA@20 POP EBP MOV EAX,1 RET 8 PENUM ENDP _TEXT ENDS END START