2014-01-27 6 views
4

В настоящее время я пытаюсь выполнить проверку в момент удаления. В функции сценария Pascal, в Inno Setup, я хочу искать конкретные процессы, если это возможно, с использованием дикой карты. Затем проведите все результаты поиска, получите имя изображения и имя пути изображения, чтобы проверить, будет ли программа, которая должна быть удалена, такая же, как и работающая.Inno Setup Pascal Script для поиска текущего процесса

Есть ли способ сделать это?

ответ

6

Это примерная задача для 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; 
+0

Это работает очень хорошо. Единственное, что я получаю исполняемый путь в следующем формате: «PROGRA ~ 1 \ 243 ~ 1.106 \ prog.exe». Могу ли я сделать что-то, чтобы иметь полный путь, как показано в диспетчере задач, вместо компактного пути с ~ 1? Как ни странно, для второй папки ~ 1 находится в середине имени папки, возможно, из-за точек в имени ... – Amaranth

+0

Это похоже на имя файла 8.3. Попробуйте вызвать функцию ['ExpandFileName'] (http://jrsoftware.org/ishelp/topic_isxfunc_expandfilename.htm), чтобы развернуть ее до полного пути. – TLama

+0

Это не сработало, но не беспокойтесь, я нашел способ, который работал для меня (это немного сложнее, хотя). http://www.vincenzo.net/isxkb/index.php?title=GetLongPathName_() Спасибо за вашу большую помощь :) – Amaranth