我正在开发一个组件安装程序(仅适用于 Delphi XE2),我想检测 Delphi XE2 IDE 是否正在运行。你将如何检测它?
PS 我知道TAppBuilder
窗口类名称,但我还需要检测 IDE 版本。
我正在开发一个组件安装程序(仅适用于 Delphi XE2),我想检测 Delphi XE2 IDE 是否正在运行。你将如何检测它?
PS 我知道TAppBuilder
窗口类名称,但我还需要检测 IDE 版本。
这些是确定 Delphi XE2 是否正在运行的步骤
1) 首先从注册表项中的条目中读取bds.exe文件的位置,该条目 可以位于 HKEY_CURRENT_USER 或 HKEY_LOCAL_MACHINE 根键中。App
\Software\Embarcadero\BDS\9.0
2)然后使用CreateToolhelp32Snapshot功能可以检查是否存在同名的exe正在运行。
3)最后使用最后处理的条目的PID,您可以解析Exe的完整文件路径(使用该GetModuleFileNameEx
函数),然后再次比较名称。
检查此示例代码
{$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.
检查 DebugHook <> 0。不利的一面是,目前如果您的应用程序是使用包构建的,DebugHook 将返回 0。但通常这将是一个非常优雅和简单的测试。在 D2009 中效果很好,我只是注意到它在 XE2 中存在包依赖错误(http://qc.embarcadero.com/wc/qcmain.aspx?d=105365)。