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 に答える