Ветеран
Сообщения: 649
Благодарности: 444
|
Профиль
|
Отправить PM
| Цитировать
в предыдущее сообщение не поместилось  , поэтому вот второе:
kodzoyev,
Цитата kodzoyev:
окна которое рекомендует пользователю закрыть браузер »
|
Реализовал таки(пришлось напрячься  ):
принцип такой:
имеем тип-запись:
Код: 
BROWSER_ERROR_STRUCT = record
ProcsToTerminate: array of String;
ErrorForm: TForm;
end;
именно этот тип и возвращает функция прототипа: function CreateBrowserError(const BrowserAraay, BrowserProcNames: array of String): BROWSER_ERROR_STRUCT;
где входные параметры - два динамичных массива записей:
первый содержит запись А = имя браузера
второй содержит запись А = имя процесса или путь к папке экзешника (спасибо ещё раз El Sanchez-у) выше упомянутого браузера
вот такие "пары" мы и отправляем
в функции CreateBrowserError() в цикле пробегаем по входным массивам и проверяем наличие процесса(ов) попутно, если какой-то процесс запущен заполняя два локальных массива
если массивы не пусты то в BROWSER_ERROR_STRUCT.ErrorForm создаём форму с именами работающих бразеров и кнопками
BROWSER_ERROR_STRUCT.ProcsToTerminate присваиваем массив с именами процессов оных!
полученную формы показываем модально и если в переменную ShowModal запишется mrYes из кнопки "да", то отправляем наш массив процессов BROWSER_ERROR_STRUCT.ProcsToTerminate в
function TerminateManyApps(const AppProcArray: array of String): BOOL; которая в цикле завершает процессы/закрывает окна.
Внимание: Функция TerminateManyApps возвращает булев значение короое формируется из булев значений локального массива, в каждый элемент которого пишется - завершился или не завершился тот или иной процесс. Те если из 3-х папущенных процессов не завершится 1 (очень мало вероятно  ) то функция вернёт False!
Пользуйтесь кому надо! Буду рад!
код:
читать дальше »
Код: 
[Setup]
SourceDir=.
OutputDir=final
AppName=GoldSource
AppVerName=GoldSource
AppVersion=GoldSource
AppPublisher=VALVE
AppCopyright=VALVE
DefaultDirName={pf}\steamapps
DefaultGroupName=GoldSource
AllowNoIcons=yes
WizardImageFile=WizardImage.bmp
WizardSmallImageFile=WizardSmallImage.bmp
OutputBaseFilename=Setup
WindowVisible=no
WindowShowCaption=no
WindowResizable=no
Compression=none
;lzma2/ultra64
LZMAUseSeparateProcess=yes
LZMAMatchFinder=BT
LZMANumFastBytes=273
LZMADictionarySize=262144
///LZMADictionarySize=131072
InternalCompressLevel=ultra64
DiskSpanning=true
DiskSliceSize=960495616
SlicesPerDisk=1
UninstallFilesDir={app}\Uninstall
[ code]
#ifdef UNICODE
#define A "W"
#else
#define A "A"
#endif
const
TH32CS_SNAPPROCESS = $2;
INVALID_HANDLE_VALUE = -1;
PROCESS_TERMINATE = $1;
PROCESS_CREATE_THREAD = $2;
PROCESS_VM_OPERATION = $8;
PROCESS_VM_WRITE = $20;
PROCESS_QUERY_INFORMATION = $400;
SYNCHRONIZE = $100000;
MEM_COMMIT = $1000;
MEM_RESERVE = $2000;
PAGE_EXECUTE_READWRITE = $40;
TOKEN_QUERY = $8;
TOKEN_ADJUST_PRIVILEGES = $20;
SE_PRIVILEGE_ENABLED = $2;
MAX_PATH = 260;
TA_FAILED = 0;
TA_SUCCESS_CLEAN = 1;
TA_SUCCESS_KILL = 2;
WM_CLOSE = $10;
WAIT_OBJECT_0 = $0;
WAIT_TIMEOUT = $102;
type
TPROCESSENTRY32 = record
dwSize, cntUsage, th32ProcessID: DWORD;
th32DefaultHeapID: Longint;
th32ModuleID, cntThreads, th32ParentProcessID: DWORD;
pcPriClassBase: Longint;
dwFlags: DWORD;
szExeFile: array [0..259] of char;
end;
BROWSER_ERROR_STRUCT = record
ProcsToTerminate: array of String;
ErrorForm: TForm;
end;
_LUID = record
LowPart: DWORD;
HighPart: Longint;
end;
_LUID_AND_ATTRIBUTES = record
Luid: _LUID;
Attributes: DWORD;
end;
_TOKEN_PRIVILEGES = record
PrivilegeCount: DWORD;
Privileges: array [0..0] of _LUID_AND_ATTRIBUTES;
end;
function CreateToolhelp32Snapshot(dwFlags, th32ProcessID: DWORD): THandle; external 'CreateToolhelp32Snapshot@kernel32.dll stdcall';
#ifdef UNICODE
function Process32First(hSnapshot: THandle; var lppe: TPROCESSENTRY32): Boolean; external 'Process32First{#A}@kernel32.dll stdcall';
function Process32Next(hSnapshot: THandle; var lppe: TPROCESSENTRY32): Boolean; external 'Process32Next{#A}@kernel32.dll stdcall';
#else
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';
#endif
function CloseHandle(hObject: THandle): BOOL; external 'CloseHandle@kernel32.dll stdcall';
function GetModuleFileNameEx(hProcess: THandle; hModule: Longint; var lpFilename: Char; nSize: DWORD): DWORD; external 'GetModuleFileNameEx{#A}@psapi.dll stdcall';
function OpenProcess(dwDesiredAccess: DWORD; bInheritHandle: BOOL; dwProcessId: DWORD): THandle; external 'OpenProcess@kernel32.dll stdcall';
function GetModuleHandle(lpModuleName: String): THandle; external 'GetModuleHandle{#A}@kernel32.dll stdcall';
function GetProcAddress(hModule: THandle; lpProcName: String): Longint; external 'GetProcAddress@kernel32.dll stdcall';
function CreateRemoteThread(hProcess: THandle; lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags: DWORD; var lpThreadId: DWORD): THandle; external 'CreateRemoteThread@kernel32.dll stdcall';
function GetCurrentThread(): THandle; external 'GetCurrentThread@kernel32.dll stdcall';
function GetCurrentProcess(): THandle; external 'GetCurrentProcess@kernel32.dll stdcall';
function OpenProcessToken(ProcessHandle: THandle; DesiredAccess: DWORD; var TokenHandle: THandle): BOOL; external 'OpenProcessToken@advapi32.dll stdcall';
function TerminateProcess(hProcess: THandle; uExitCode: UINT): BOOL; external 'TerminateProcess@kernel32.dll stdcall';
function WaitForSingleObject(hHandle: THandle; dwMilliseconds: DWORD): DWORD; external 'WaitForSingleObject@kernel32.dll stdcall';
function LookupPrivilegeValue(lpSystemName, lpName: String; var lpLuid: _LUID): BOOL; external 'LookupPrivilegeValue{#A}@advapi32.dll stdcall';
function AdjustTokenPrivileges(TokenHandle: THandle; DisableAllPrivileges: BOOL; NewState: _TOKEN_PRIVILEGES; BufferLength: DWORD; var PreviousState: _TOKEN_PRIVILEGES; var ReturnLength: Longint): BOOL; external 'AdjustTokenPrivileges@advapi32.dll stdcall';
function VirtualAllocEx(hProcess: THandle; lpAddress, dwSize: Longint; flAllocationType, flProtect: DWORD): Longint; external 'VirtualAllocEx@kernel32.dll stdcall';
function WriteProcessMemory(hProcess: THandle; lpBaseAddress, lpBuffer, nSize: Longint; var lpNumberOfBytesWritten: Longint): BOOL; external 'WriteProcessMemory@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 IsProcessRunning(const FileName: String): Boolean; //FileName - имя exe-файла процесса
var
hProcessSnap: THandle;
pe32: TPROCESSENTRY32;
szExeFile: String;
begin
hProcessSnap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if hProcessSnap = INVALID_HANDLE_VALUE then Exit;
pe32.dwSize := sizeof(pe32);
if not Process32First(hProcessSnap, pe32) then Exit;
while not Result and Process32Next(hProcessSnap, pe32) do
begin
szExeFile := '';
while not (pe32.szExeFile[Length(szExeFile)] = #0) do szExeFile := szExeFile + pe32.szExeFile[Length(szExeFile)];
Result := LowerCase(FileName) = LowerCase(szExeFile);
end;
CloseHandle(hProcessSnap);
end;
/////////////////////////////////////////////////////////
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 szProcess: String; dwTimeout: DWORD): DWORD;
var
hProcessSnap, hProc, hToken, hThread, lpProcName: THandle;
pe32: TPROCESSENTRY32;
szExeFile: array [0..MAX_PATH-1] of Char;
ptrProc: Longint;
tkp: _TOKEN_PRIVILEGES;
SeDebugNameValue: _LUID;
lpMemory, ret: Longint;
lpThreadId: DWORD;
begin
ptrProc := CallbackAddr('EnumWindowsProc');
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), ExtractFileName(szProcess)) <> 0 then Continue;
// try open process
hProc := OpenProcess(PROCESS_TERMINATE or PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or PROCESS_VM_WRITE or PROCESS_QUERY_INFORMATION or SYNCHRONIZE, False, pe32.th32ProcessID);
if hProc = TA_FAILED then
begin
// open process token adjust privileges
if not OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then Exit;
if not LookupPrivilegeValue('', 'SeDebugPrivilege', SeDebugNameValue) then Exit;
try
// fill token privileges struct
tkp.PrivilegeCount := 1;
tkp.Privileges[0].Luid := SeDebugNameValue;
tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
// set debug privileges
if not AdjustTokenPrivileges(hToken, False, tkp, SizeOf(tkp), tkp, ret) then Exit;
// try open process with debug privileges
hProc := OpenProcess(PROCESS_TERMINATE or PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or PROCESS_VM_WRITE or PROCESS_QUERY_INFORMATION or SYNCHRONIZE, False, pe32.th32ProcessID);
if hProc = TA_FAILED then Exit;
finally
tkp.Privileges[0].Attributes := 0;
AdjustTokenPrivileges(hToken, False, tkp, SizeOf(tkp), tkp, ret);
CloseHandle(hToken);
end;
end;
// if szProcess is full path
if CompareText(szProcess, ExtractFileName(szProcess)) <> 0 then
begin
GetModuleFileNameEx(hProc, 0, szExeFile[0], MAX_PATH);
if CompareText(CharArrayToString(szExeFile), szProcess) <> 0 then
begin
CloseHandle(hProc);
//Continue;
end;
end;
// try stop process
try
EnumWindows(ptrProc, pe32.th32ProcessID);
case WaitForSingleObject(hProc, dwTimeout) of
WAIT_OBJECT_0: Result := TA_SUCCESS_CLEAN;
WAIT_TIMEOUT: try
lpProcName := GetProcAddress(GetModuleHandle('kernel32.dll'), 'ExitProcess');
if lpProcName = 0 then Exit;
//
lpMemory := VirtualAllocEx(hProc, 0, SizeOf(lpProcName), MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if not WriteProcessMemory(hProc, lpMemory, lpProcName, SizeOf(lpProcName), ret) then Exit;
//
hThread := CreateRemoteThread(hProc, 0, 0, lpMemory, 0, 0, lpThreadId);
if hThread > 0 then
case WaitForSingleObject(hThread, dwTimeout) of
WAIT_OBJECT_0: Result := TA_SUCCESS_CLEAN;
WAIT_TIMEOUT: if TerminateProcess(hProc, 0) then Result := TA_SUCCESS_KILL;
end;
finally
CloseHandle(hThread);
end;
end;
finally
CloseHandle(hProc);
if CompareText(szProcess, ExtractFileName(szProcess)) <> 0 then Exit;
end;
end;
finally
CloseHandle(hProcessSnap);
end;
end;
function CreateBrowserError(const BrowserAraay, BrowserProcNames: array of String): BROWSER_ERROR_STRUCT;
var
uBrowserStringArray, uBrowserProcStringArray: array of String;
StaticInfo: TNewStaticText;
uString: String;
i: Integer;
begin
for i := 0 to GetArrayLength(BrowserAraay)-1 do
begin
if IsProcessRunning(BrowserProcNames[i]) then
begin
SetArrayLength(uBrowserStringArray, i+1);
uBrowserStringArray[i] := BrowserAraay[i];
SetArrayLength(uBrowserProcStringArray, i+1);
uBrowserProcStringArray[i] := BrowserProcNames[i];
end;
end;
if GetArrayLength(uBrowserStringArray) = 0 then Exit;
Result.ErrorForm := TForm.Create(nil)
with Result.ErrorForm do
begin
ClientHeight := ScaleY(100);
Position := PoscreenCenter;
BorderStyle := bsDialog;
Caption := 'Error';
StaticInfo := TNewStaticText.Create(Result.ErrorForm)
with StaticInfo do
begin
Parent := Result.ErrorForm;
Left := ScaleX(7);
Top := ScaleY(7);
Font.Size := 10;
Caption := 'Запущен(ы) браузер(ы):';
for i := 0 to GetArrayLength(uBrowserStringArray)-1 do Caption := Caption + #32 + uBrowserStringArray[i] + ',';
uString := Caption;
Delete(uString, Length(uString), Length(uString));
Caption := uString + '.' + #13#10 + 'Завершить процессы?';
end;
ClientWidth := ScaleX(StaticInfo.Width+30);
with TNewButton.Create(Result.ErrorForm) do
begin
Parent := Result.ErrorForm;
SetBounds(ScaleX(Result.ErrorForm.Width-100), ScaleY(Result.ErrorForm.Height-60), ScaleX(80), ScaleY(25));
Caption := SetupMessage(msgButtonNo);
ModalResult := mrNo;
end;
with TNewButton.Create(Result.ErrorForm) do
begin
Parent := Result.ErrorForm;
SetBounds(ScaleX(Result.ErrorForm.Width-190), ScaleY(Result.ErrorForm.Height-60), ScaleX(80), ScaleY(25));
Caption := SetupMessage(msgButtonYes);
ModalResult := mrYes;
end;
end;
SetArrayLength(Result.ProcsToTerminate, GetArrayLength(uBrowserProcStringArray));
Result.ProcsToTerminate := uBrowserProcStringArray;
end;
function TerminateManyApps(const AppProcArray: array of String): BOOL;
var
bArray: array of BOOL;
uArrayLen: Integer;
i: Integer;
begin
for i := 0 to GetArrayLength(AppProcArray)-1 do
begin
SetArrayLength(bArray, i+1);
bArray[i] := TerminateApp(AppProcArray[i], 5000) = 1;
end;
Result := bArray[0];
uArrayLen := GetArrayLength(bArray);
if uArrayLen > 1 then for i := 1 to uArrayLen-1 do Result := Result and bArray[i];
end;
function NextButtonClick(CurPageID: Integer): Boolean;
var
uBROWSER_ERROR_STRUCT: BROWSER_ERROR_STRUCT;
begin
if CurPageID = wpReady then
begin
uBROWSER_ERROR_STRUCT := CreateBrowserError(['Mozilla Firefox', 'Internet Explorer'], ['firefox.exe', 'iexplore.exe']);
if uBROWSER_ERROR_STRUCT.ErrorForm <> nil then
if uBROWSER_ERROR_STRUCT.ErrorForm.ShowModal = mrYes then
Result := TerminateManyApps(uBROWSER_ERROR_STRUCT.ProcsToTerminate);
end else Result := True;
end;
скрин:
|