Это примерная задача для WMI и языка WQL. Получение списка запущенных процессов через WMI равно более надежным, чем Windows API. Ниже пример показывает, как запросить Win32_Process
класс с оператором LIKE
:
[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program
DefaultGroupName=My Program
[Code]
type
TProcessEntry = record
PID: DWORD;
Name: string;
Description: string;
ExecutablePath: string;
end;
TProcessEntryList = array of TProcessEntry;
function GetProcessList(const Filter: string;
out List: TProcessEntryList): Integer;
var
I: Integer;
WQLQuery: string;
WbemLocator: Variant;
WbemServices: Variant;
WbemObject: Variant;
WbemObjectSet: Variant;
begin
Result := 0;
WbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
WbemServices := WbemLocator.ConnectServer('localhost', 'root\CIMV2');
WQLQuery :=
'SELECT ' +
'ProcessId, ' +
'Name, ' +
'Description, ' +
'ExecutablePath ' +
'FROM Win32_Process ' +
'WHERE ' +
'Name LIKE "%'+ Filter +'%"';
WbemObjectSet := WbemServices.ExecQuery(WQLQuery);
if not VarIsNull(WbemObjectSet) and (WbemObjectSet.Count > 0) then
begin
Result := WbemObjectSet.Count;
SetArrayLength(List, WbemObjectSet.Count);
for I := 0 to WbemObjectSet.Count - 1 do
begin
WbemObject := WbemObjectSet.ItemIndex(I);
if not VarIsNull(WbemObject) then
begin
List[I].PID := WbemObject.ProcessId;
List[I].Name := WbemObject.Name;
List[I].Description := WbemObject.Description;
List[I].ExecutablePath := WbemObject.ExecutablePath;
end;
end;
end;
end;
procedure InitializeWizard;
var
S: string;
I: Integer;
Filter: string;
ProcessList: TProcessEntryList;
begin
MsgBox('Now we try to list processes containing "sv" in their names...',
mbInformation, MB_OK);
Filter := 'sv';
if GetProcessList(Filter, ProcessList) > 0 then
for I := 0 to High(ProcessList) do
begin
S := Format(
'PID: %d' + #13#10 +
'Name: %s' + #13#10 +
'Description: %s' + #13#10 +
'ExecutablePath: %s', [
ProcessList[I].PID,
ProcessList[I].Name,
ProcessList[I].Description,
ProcessList[I].ExecutablePath]);
MsgBox(S, mbInformation, MB_OK);
end;
end;
Это работает очень хорошо. Единственное, что я получаю исполняемый путь в следующем формате: «PROGRA ~ 1 \ 243 ~ 1.106 \ prog.exe». Могу ли я сделать что-то, чтобы иметь полный путь, как показано в диспетчере задач, вместо компактного пути с ~ 1? Как ни странно, для второй папки ~ 1 находится в середине имени папки, возможно, из-за точек в имени ... – Amaranth
Это похоже на имя файла 8.3. Попробуйте вызвать функцию ['ExpandFileName'] (http://jrsoftware.org/ishelp/topic_isxfunc_expandfilename.htm), чтобы развернуть ее до полного пути. – TLama
Это не сработало, но не беспокойтесь, я нашел способ, который работал для меня (это немного сложнее, хотя). http://www.vincenzo.net/isxkb/index.php?title=GetLongPathName_() Спасибо за вашу большую помощь :) – Amaranth