Johny777
03-07-2012, 19:26
Да бевел это. »
всё мимо
В итоге оказалось, что это стиль границы листбокса задач :grin:
====================================================================================================
У меня возник вопрос
при удалении игры деинсталятор ориентируется на экзешник
есть экзешник там = есть и игра = есть активный чекбокс на форме
если же в диспетчере задач висит процесс этого самого экзешника и при этом попытаться его удалить, то удаляется всё кроме него, а он остаётся
те никаких ошибок и прочего
подскажите пожалуйста как определить директорию расположения экзешника, процесс которого висит
(определение процесса уже есть в шапке в 2-х вариантах)
почему именно папку?
дело в том, что речь идёт о процессе hl2.exe а он может быть и не от моей пиратки, а от другой или от steam версии
и было бы некрасиво завершать процесс слева, удаляя справа
также прошу не помогать мне если писанина подобного кода является трудоёмкой задачей, тк это "косметическая" правка и нацелена она
на устранение хоть и надеюсь редкого, но возможного конфликта.
El Sanchez
03-07-2012, 22:04
Johny777, определение рабочей папки процесса:
[Code]
#ifdef UNICODE
#define A "W"
#else
#define A "A"
#endif
const
TH32CS_SNAPPROCESS = $2;
INVALID_HANDLE_VALUE = -1;
PROCESS_QUERY_INFORMATION = $400;
PROCESS_VM_READ = $10;
MAX_PATH = 260;
type
TPROCESSENTRY32 = record
dwSize, cntUsage, th32ProcessID: DWORD;
th32DefaultHeapID: Longint;
th32ModuleID, cntThreads, th32ParentProcessID: DWORD;
pcPriClassBase: Longint;
dwFlags: DWORD;
szExeFile: array [0..MAX_PATH-1] of Сhar;
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 GetProcessImageFileName(hProcess: THandle; var lpImageFileName: Char; nSize: DWORD): DWORD; external 'GetProcessImageFileName{#A}@psapi.dll stdcall';
function GetLogicalDriveStrings(nBufferLength: DWORD; var lpBuffer: Char): DWORD; external 'GetLogicalDriveStrings{#A}@kernel32.dll stdcall';
function QueryDosDevice(lpDeviceName: String; var lpTargetPath: Char; ucchMax: DWORD): DWORD; external 'QueryDosDevice{#A}@kernel32.dll stdcall';
function OpenProcess(dwDesiredAccess: DWORD; bInheritHandle: BOOL; dwProcessId: DWORD): THandle; external 'OpenProcess@kernel32.dll stdcall';
function CharArrayToString(aChar: array of Char): String;
begin
Result := '';
while not (aChar[Length(Result)] = #0) do Result := Result + aChar[Length(Result)];
end;
function GetProcessWorkingDirectory(ProcessName: String): TArrayOfString;
var
hProcessSnap, hProc: THandle;
pe32: TPROCESSENTRY32;
szExeFile, szDrives, szDeviceName: array [0..MAX_PATH-1] of Char;
sDeviceName: String;
i, iLen: DWORD;
begin
SetArrayLength(Result, 0);
hProcessSnap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if hProcessSnap = INVALID_HANDLE_VALUE then Exit;
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(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, pe32.th32ProcessID);
if GetProcessImageFileName(hProc, szExeFile[0], MAX_PATH) = 0 then Exit;
SetArrayLength(Result, GetArrayLength(Result)+1);
Result[GetArrayLength(Result)-1] := CharArrayToString(szExeFile);
iLen := GetLogicalDriveStrings(MAX_PATH, szDrives[0]);
if iLen = 0 then Exit;
i := 0;
while i <= iLen-3 do
begin
if QueryDosDevice(szDrives[i] + ':', szDeviceName[0], MAX_PATH) > 0 then
begin
sDeviceName := CharArrayToString(szDeviceName);
if (Length(sDeviceName) <= Length(Result[GetArrayLength(Result)-1])) and
(Pos(sDeviceName, Result[GetArrayLength(Result)-1]) = 1) then
begin
StringChangeEx(Result[GetArrayLength(Result)-1], sDeviceName, szDrives[i] + ':', True);
Result[GetArrayLength(Result)-1] := RemoveBackSlash(ExtractFilePath(Result[GetArrayLength(Result)-1]));
Break;
end;
end;
i := i + 4;
end;
CloseHandle(hProc);
end;
end;
CloseHandle(hProcessSnap);
end;
procedure InitializeWizard();
var
szArray: TArrayOfString;
i: Integer;
begin
//хочу знать откуда калькуляторы запущены
szArray := GetProcessWorkingDirectory('calc.exe');
if GetArrayLength(szArray) > 0 then for i := 0 to GetArrayLength(szArray)-1 do MsgBox(szArray[i], mbInformation, MB_OK);
end;
Johny777
04-07-2012, 00:31
El Sanchez, огромное спасибо за функцию
результат:
if GetProcessWorkingDirectory('hl2.exe') = ExpandConstant('{app}\common\half-life 2') then Exec('taskkill', '/f /im hl2.exe', '', SW_Hide, ewWaitUntilTerminated, ErrorCode);
работает отлично! :)
надеюсь тебе было не в напряг
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,,,,,,,,
можно пожалуйста ещё 2 мелких вопроса?
1. в чём разница между ErrorCode и ResultCode
Если они оба сравниваются только с 0 , то я понимаю
if (ErrorCode <> 0) then // если ошибка то...
if (ResultCode <> 0) then // если успех то...
а если ещё и с единицей, то не вижу разницы
вот напимер форма которая создаётся в пределах создания формы Авторана в случае работающего сервиса Steam
if (FileExists(AppPath + '\common\half-life 2\hl2.exe') or FileExists(AppPath + '\common\half-life 2 episode one\hl2.exe') or
FileExists(AppPath + '\common\half-life 2 episode two\hl2.exe') or FileExists(AppPath + '\common\portal\hl2.exe'))
and (IsProcessRunning('Steam.exe')) then
begin
MyExit := TForm.Create(nil);
with MyExit do
begin
Position := poScreenCenter;
BorderStyle := bsDialog;
ClientWidth := ScaleX(440);
ClientHeight := ScaleY(180);
Caption := ExpandConstant(SetupMessage(msgErrorTitle));
Color := clBtnFace;
DeleteMenu(GetSystemMenu(MyExit.Handle,False), $F060,0);/// сделать кнопку "закрыть" неактивной
SetClassLong(MyExit.Handle, -26, GetClassLong(MyExit.Handle, -26) or $200); /// блокировка комбинации alt + f4
SendMessage(MyExit.Handle, $0080, 0, LoadImage(0,ExpandConstant('{tmp}')+'\icon.ico',1,16,16,$1010)); /// иконка в углу
OnMouseDown := @MouseDown2;
with TBitmapImage.Create(MyExit) do
begin
Parent := MyExit;
ExtractTemporaryFile('Pic1.bmp');
Bitmap.LoadFromFile(ExpandConstant('{tmp}\Pic1.bmp'));
SetBounds(ScaleX(0), ScaleY(0), ScaleX(440), ScaleY(120));
OnMouseDown := @MouseDown2;
end;
with TLabel.Create(MyExit) do
begin
SetBounds(ScaleX(20), ScaleY(131), ScaleX(270), ScaleY(30));
AutoSize := False;
Caption := ExpandConstant('{cm:Steam_Runs}');
Transparent := True;
WordWrap := True;
Parent := MyExit;
Font.Color := clWindowText;
//Font.Color := $48c1ca;
Font.Size := 9;
OnMouseDown := @MouseDown2;
end;
with TButton.Create(MyExit) do
begin
Caption := ExpandConstant(SetupMessage(msgButtonYes));
Parent := MyExit;
SetBounds(ScaleX(270), ScaleY(135), ScaleX(71), ScaleY(25));
ModalResult := mrYes;
end;
with TButton.Create(MyExit) do
begin
Parent := MyExit;
Caption := ExpandConstant(SetupMessage(msgButtonNo));
SetBounds(ScaleX(350), ScaleY(135), ScaleX(71), ScaleY(25));
ModalResult:= mrNo;
end;
end;
ExtractTemporaryFile('launch_deny2.wav');
sndPlaySound(ExpandConstant('{tmp}\launch_deny2.wav'),$0001);
case
MyExit.ShowModal() of
mrNo :
begin
PlayInstallButton.Enabled := not IsProcessRunning('Steam.exe');
MyExit.Free;
end;
mrYes :
begin
Exec(ExpandConstant('{reg:HKCU\Software\Valve\Steam,SteamPath|}') + '\Steam.exe', '-shutdown', '', SW_SHOW, ewWaitUntilTerminated, ResultCode);
if not (IsProcessRunning('Steam.exe')) then PlayInstallButton.Enabled := True;
MyExit.Free;
end;
end;
end;
AutoRun.ShowModal;
end;
те если вписать в
Exec(ExpandConstant('{reg:HKCU\Software\Valve\Steam,SteamPath|}') + '\Steam.exe', '-shutdown', '', SW_SHOW, ewWaitUntilTerminated, ResultCode);
ErrorCode и сравнить
if (ErrorCode = 0) then MyExit.Free else MsgBox( завршить процесс Да/Нет ...
если я правильно понимаю
(определение процесса взял отсюда http://forum.oszone.net/post-1800689-218.html)
2. достаточно ли завершить процесс так:
Exec('taskkill', '/f /im hl2.exe', '', SW_Hide, ewWaitUntilTerminated, ErrorCode);
или лучше воспользоваться библиотекой istask.dll ?
El Sanchez
04-07-2012, 13:00
А как переделать GetProcessWorkingDirectory, чтобы на юникоде работало? »
Johny777, sergey3695, переделал на ansi/unicode и изменил тип результата функции - теперь возвращает не строку, а массив строк, ведь запущенных процессов с одинаковым именем может быть несколько.
1. в чём разница между ErrorCode и ResultCode »
Johny777, ни в чем, переменные можешь называть как хочешь. Код возврата ResultCode функции Exec сравнивается только с 0, ненулевой код есть код ошибки, расшифровка которого делается с помощью SysErrorMessage(ResultCode).
2. достаточно ли завершить процесс так:
Exec('taskkill', '/f /im hl2.exe', '', SW_Hide, ewWaitUntilTerminated, ErrorCode);
или лучше воспользоваться библиотекой istask.dll ? »
Johny777, без разницы, если делают одно и то же.
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.