5

我目前正在尝试在卸载时进行验证。在 Pascal 脚本函数中,在 Inno Setup 中,我想搜索特定进程,如果可能的话,使用通配符。然后,遍历所有查找结果,获取镜像名称和镜像路径名称,以检查即将卸载的程序是否与正在运行的程序相同。

有没有办法做到这一点?

4

2 回答 2

8

这是 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;
于 2014-01-28T14:39:41.110 回答
1

如果不行,请按如下方式更改。

(旧) for I := 0 to High(ProcessList) 做

(new) for I := 0 to (GetArrayLength(ProcessList) - 1) 做

于 2018-11-09T02:39:25.430 回答