5

コンポーネントインストーラー(Delphi XE2のみ)に取り組んでおり、DelphiXE2IDEが実行されているかどうかを検出したいと思います。どのようにそれを検出しますか?

PSウィンドウクラス名は知っていTAppBuilderますが、IDEバージョンも検出する必要があります。

4

2 に答える 2

8

これらは、Delphi XE2 が実行されているかどうかを判断する手順です。

1) 最初 に、HKEY_CURRENT_USER または HKEY_LOCAL_MACHINE ルート キーにあるレジストリ キーのエントリからbds.exeファイルの場所を読み取ります。App\Software\Embarcadero\BDS\9.0

2) 次に、CreateToolhelp32Snapshot関数を使用して、実行中の同じ名前の exe が存在するかどうかを確認できます。

3) 最後に、最後に処理されたエントリの PID を使用して、(GetModuleFileNameEx関数を使用して) Exe の完全なファイル パスを解決し、名前を再度比較できます。

このサンプルコードを確認してください

{$APPTYPE CONSOLE}

{$R *.res}

uses

  Registry,
  PsAPI,
  TlHelp32,
  Windows,
  SysUtils;

function ProcessFileName(dwProcessId: DWORD): string;
var
  hModule: Cardinal;
begin
  Result := '';
  hModule := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, dwProcessId);
  if hModule <> 0 then
    try
      SetLength(Result, MAX_PATH);
      if GetModuleFileNameEx(hModule, 0, PChar(Result), MAX_PATH) > 0 then
        SetLength(Result, StrLen(PChar(Result)))
      else
        Result := '';
    finally
      CloseHandle(hModule);
    end;
end;

function IsAppRunning(const FileName: string): boolean;
var
  hSnapshot      : Cardinal;
  EntryParentProc: TProcessEntry32;
begin
  Result := False;
  hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  if hSnapshot = INVALID_HANDLE_VALUE then
    exit;
  try
    EntryParentProc.dwSize := SizeOf(EntryParentProc);
    if Process32First(hSnapshot, EntryParentProc) then
      repeat
        if CompareText(ExtractFileName(FileName), EntryParentProc.szExeFile) = 0 then
          if CompareText(ProcessFileName(EntryParentProc.th32ProcessID),  FileName) = 0 then
          begin
            Result := True;
            break;
          end;
      until not Process32Next(hSnapshot, EntryParentProc);
  finally
    CloseHandle(hSnapshot);
  end;
end;

function RegReadStr(const RegPath, RegValue: string; var Str: string;
  const RootKey: HKEY): boolean;
var
  Reg: TRegistry;
begin
  try
    Reg := TRegistry.Create;
    try
      Reg.RootKey := RootKey;
      Result      := Reg.OpenKey(RegPath, True);
      if Result then
        Str := Reg.ReadString(RegValue);
    finally
      Reg.Free;
    end;
  except
    Result := False;
  end;
end;

function RegKeyExists(const RegPath: string; const RootKey: HKEY): boolean;
var
  Reg: TRegistry;
begin
  try
    Reg := TRegistry.Create;
    try
      Reg.RootKey := RootKey;
      Result      := Reg.KeyExists(RegPath);
    finally
      Reg.Free;
    end;
  except
    Result := False;
  end;
end;


function GetDelphiXE2LocationExeName: string;
Const
 Key = '\Software\Embarcadero\BDS\9.0';
begin
  Result:='';
    if RegKeyExists(Key, HKEY_CURRENT_USER) then
    begin
      RegReadStr(Key, 'App', Result, HKEY_CURRENT_USER);
      exit;
    end;

    if RegKeyExists(Key, HKEY_LOCAL_MACHINE) then
      RegReadStr(Key, 'App', Result, HKEY_LOCAL_MACHINE);
end;


Var
 Bds : String;

begin
  try
     Bds:=GetDelphiXE2LocationExeName;
     if Bds<>'' then
     begin
       if  IsAppRunning(Bds) then
        Writeln('The Delphi XE2 IDE Is running')
       else
        Writeln('The Delphi XE2 IDE Is not running')
     end
     else
     Writeln('The Delphi XE2 IDE Is was not found');
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.

追加のリソース。 Detecting installed delphi versions

于 2012-02-04T19:18:10.800 に答える
1

DebugHook <> 0 を確認してください。現在、アプリがパッケージでビルドされている場合、DebugHook は 0 を返すという欠点があります。しかし、通常、これは非常にエレガントでシンプルなテストになります。D2009 では問題なく動作しますが、XE2 (http://qc.embarcadero.com/wc/qcmain.aspx?d=105365) にパッケージ依存性のバグがあることに気付きました。

于 2012-06-01T20:48:47.407 に答える