Имя пользователя:
Пароль:
 

Показать сообщение отдельно

Аватара для El Sanchez

Ветеран


Contributor


Сообщения: 1274
Благодарности: 1030

Профиль | Отправить PM | Цитировать


Johny777, TerminateProcess стоит применять в крайнем случае, когда другие способы завершения процесса не помогают. Нужно послать окну программы сообщение WM_CLOSE, подождать 5 сек (где-то читал, что приложение считается зависшим, если не отвечает на действия системы в течение 5 сек.) и только потом TerminateProcess, если нужно.

читать дальше »

Код: Выделить весь код
const
    TH32CS_SNAPPROCESS = $2;
    INVALID_HANDLE_VALUE = -1;
    WM_CLOSE = $10;
    WAIT_OBJECT_0 = $0;
    TA_FAILED = 0;
    TA_SUCCESS_CLEAN = 1;
    TA_SUCCESS_KILL = 2;
    SYNCHRONIZE = $100000;
    PROCESS_TERMINATE = $1;

type
    TPROCESSENTRY32 = record
        dwSize, cntUsage, th32ProcessID: DWORD;
        th32DefaultHeapID: Longint;
        th32ModuleID, cntThreads, th32ParentProcessID: DWORD;
        pcPriClassBase: Longint;
        dwFlags: DWORD;
        szExeFile: array [0..MAX_PATH-1] of Char;
    end;

function CreateToolhelp32Snapshot(dwFlags, th32ProcessID: DWORD): THandle; external 'CreateToolhelp32Snapshot@kernel32.dll stdcall';
function Process32First(hSnapshot: THandle; var lppe: TPROCESSENTRY32): Boolean; external 'Process32First@kernel32.dll stdcall';
function Process32Next(hSnapshot: THandle; var lppe: TPROCESSENTRY32): Boolean; external 'Process32Next@kernel32.dll stdcall';
function OpenProcess(dwDesiredAccess: DWORD; bInheritHandle: BOOL; dwProcessId: DWORD): THandle; external 'OpenProcess@kernel32.dll stdcall';
function EnumWindows(lpEnumFunc, lParam: Longint): BOOL; external 'EnumWindows@user32.dll stdcall';
function GetWindowThreadProcessId(hWnd: HWND; var lpdwProcessId: DWORD): DWORD; external 'GetWindowThreadProcessId@user32.dll stdcall';
function WaitForSingleObject(hHandle: THandle; dwMilliseconds: DWORD): DWORD; external 'WaitForSingleObject@kernel32.dll stdcall';
function TerminateProcess(hProcess: THandle; uExitCode: UINT): BOOL; external 'TerminateProcess@kernel32.dll stdcall';
function EnumWindowsProc(hwnd: HWND; lParam: Longint): BOOL;
function CloseHandle(hObject: THandle): BOOL; external 'CloseHandle@kernel32.dll stdcall';

function CharArrayToString(aChar: array of Char): String;
begin
    Result := '';
    while aChar[Length(Result)] <> #0 do Insert(aChar[Length(Result)], Result, Length(Result)+1);
end;

function EnumWindowsProc(hwnd: HWND; lParam: Longint): BOOL;
var
    dwID: DWORD;
begin
    GetWindowThreadProcessId(hwnd, dwID) ;
    if dwID = lParam then PostMessage(hwnd, WM_CLOSE, 0, 0);
    Result := True;
end;

function TerminateApp(const ProcessName: String; dwTimeout: DWORD): DWORD;
var
    hProcessSnap, hProc: THandle;
    pe32: TPROCESSENTRY32;
begin
    hProcessSnap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if hProcessSnap = INVALID_HANDLE_VALUE then Exit;
    try
        pe32.dwSize := SizeOf(pe32);
        if not Process32First(hProcessSnap, pe32) then Exit;
        while Process32Next(hProcessSnap, pe32) do
        begin
            if CompareText(CharArrayToString(pe32.szExeFile), ProcessName) = 0 then
            begin
                hProc := OpenProcess(SYNCHRONIZE or PROCESS_TERMINATE, False, pe32.th32ProcessID);
                if hProc = TA_FAILED then Exit;
                try
                    EnumWindows(CallbackAddr('EnumWindowsProc'), pe32.th32ProcessID);
                    if WaitForSingleObject(hProc, dwTimeout) = WAIT_OBJECT_0 then
                        Result := TA_SUCCESS_CLEAN
                    else if TerminateProcess(hProc, 0) then Result := TA_SUCCESS_KILL else Result := TA_FAILED;
                finally
                    CloseHandle(hProc);
                end;
            end;
        end;
    finally
        CloseHandle(hProcessSnap);
    end;
end;

procedure InitializeWizard();
begin
    TerminateApp('calc.exe', 5000);
end;
Это сообщение посчитали полезным следующие участники:

Отправлено: 17:54, 01-12-2012 | #1344