2012-02-04 28 views
5

Estoy trabajando en un instalador de componentes (solo para Delphi XE2) y me gustaría detectar si el Delphi XE2 IDE se está ejecutando. ¿Cómo lo detectarías?¿Cómo puedo detectar si se está ejecutando el Delphi IDE específico?

P.S. Sé sobre el nombre de clase de ventana TAppBuilder, pero necesito detectar también la versión IDE.

+7

Si puede encontrar el identificador de ventana de la ventana principal, puede usar GetWindowThreadProcessId para obtener la identificación del proceso. Luego llame a OpenProcess para obtener un control de proceso. Luego llame a GetModuleFileNameEx para obtener el nombre del archivo exe. Luego use GetFileVersionInfo etc. para leer el recurso de versión del archivo exe. ¡Uf! –

+0

@DavidHeffernan: :-) Respire hondo una y otra vez. Ahí debería sentirse mejor. –

+0

Espero que lo anterior haga el trabajo, pero no me sorprendería en absoluto si alguien pudiera encontrar una manera más fácil. –

Respuesta

7

Estos son los pasos para determinar si el Delphi XE2 se está ejecutando

1) En primer lugar Conoce la ubicación del archivo de bds.exe partir de la entrada App en la clave de registro \Software\Embarcadero\BDS\9.0 que puede estar localizado en el HKEY_CURRENT_USER o HKEY_LOCAL_MACHINE Tecla de raíz.

2) Luego, usando la función CreateToolhelp32Snapshot puede verificar si existe un exe con el mismo nombre ejecutándose.

3) Finalmente, utilizando el PID de la última entrada procesada, puede resolver la ruta completa del archivo del Exe (utilizando la función GetModuleFileNameEx) y luego comparar los nombres nuevamente.

Comprobar este código de ejemplo

{$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. 

recursos Addtional. Detecting installed delphi versions

1

Comprobar DebugHook <> 0. El lado negativo es que en la actualidad si su aplicación se construye con paquetes, DebugHook devolverá 0. Pero normalmente esto es que sería una prueba muy elegante y simple. Funciona muy bien en D2009, me acabo de dar cuenta de que tiene el error de dependencia del paquete en XE2 (http://qc.embarcadero.com/wc/qcmain.aspx?d=105365).

+0

Tenga en cuenta que [QualityCentral ahora se ha cerrado] (https://community.embarcadero.com/blogs/entry/quality-keeps-moving-forward), por lo que ya no puede acceder a los enlaces 'qc.embarcadero.com' . Si necesita acceder a datos antiguos de control de calidad, consulte [QCScraper] (http://www.uweraabe.de/Blog/2017/06/09/how-to-save-qualitycentral/). –

Cuestiones relacionadas