Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何检测特定的Delphi IDE是否正在运行?_Delphi_Ide_Delphi Xe2_Version Detection - Fatal编程技术网

如何检测特定的Delphi IDE是否正在运行?

如何检测特定的Delphi IDE是否正在运行?,delphi,ide,delphi-xe2,version-detection,Delphi,Ide,Delphi Xe2,Version Detection,我正在开发一个组件安装程序(仅适用于Delphi XE2),我想检测Delphi XE2 IDE是否正在运行。你将如何检测它 另外,我知道TAppBuilder窗口类名,但我还需要检测IDE版本。以下是确定Delphi XE2是否正在运行的步骤 1) 首先从\Software\Embarcadero\bds\9.0注册表项中的App条目读取bds.exe文件的位置,该注册表项可以位于HKEY_当前用户或HKEY_本地_机器根键中 2) 然后使用该函数可以检查是否存在同名的exe正在运行 3) 最

我正在开发一个组件安装程序(仅适用于Delphi XE2),我想检测Delphi XE2 IDE是否正在运行。你将如何检测它


另外,我知道
TAppBuilder
窗口类名,但我还需要检测IDE版本。

以下是确定Delphi XE2是否正在运行的步骤

1) 首先从
\Software\Embarcadero\bds\9.0
注册表项中的
App
条目读取bds.exe文件的位置,该注册表项可以位于HKEY_当前用户或HKEY_本地_机器根键中

2) 然后使用该函数可以检查是否存在同名的exe正在运行

3) 最后,使用最后处理的条目的PID,您可以解析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.
{$APPTYPE控制台}
{$R*.res}
使用
登记处,
PsAPI,
TL32,
窗户,
SysUtils;
函数ProcessFileName(dwProcessId:DWORD):字符串;
变量
H模块:基数;
开始
结果:='';
hModule:=OpenProcess(进程查询信息或进程虚拟机读取,False,dwProcessId);
如果hModule为0,则
尝试
设置长度(结果,最大路径);
如果GetModuleFileNameEx(hModule,0,PChar(Result),MAX_PATH)>0,那么
SetLength(结果,StrLen(PChar(结果)))
其他的
结果:='';
最后
闭合手柄(hModule);
结束;
结束;
函数IsAppRunning(常量文件名:字符串):布尔值;
变量
红衣主教;
EntryParentProc:tprocesentry32;
开始
结果:=假;
hSnapshot:=CreateToolhelp32Snapshot(TH32CS\u SNAPPROCESS,0);
如果hSnapshot=无效的句柄值,则
出口
尝试
EntryParentProc.dwSize:=SizeOf(EntryParentProc);
如果先处理32(hSnapshot、EntryParentProc),则
重复
如果CompareText(ExtractFileName(FileName),EntryParentProc.szexFile)=0,则
如果CompareText(ProcessFileName(EntryParentProc.th32ProcessID),FileName)=0,则
开始
结果:=真;
打破
结束;
直到不是下一步(hSnapshot、EntryParentProc);
最后
闭合手柄(hSnapshot);
结束;
结束;
函数RegReadStr(const RegPath,RegValue:string;var Str:string;
常量RootKey:HKEY):布尔值;
变量
注册:树木学;
开始
尝试
Reg:=TRegistry.Create;
尝试
Reg.RootKey:=RootKey;
结果:=Reg.OpenKey(RegPath,True);
如果结果是这样的话
Str:=Reg.ReadString(RegValue);
最后
注册免费;
结束;
除了
结果:=假;
结束;
结束;
函数RegKeyExists(const RegPath:string;const RootKey:HKEY):布尔;
变量
注册:树木学;
开始
尝试
Reg:=TRegistry.Create;
尝试
Reg.RootKey:=RootKey;
结果:=Reg.KeyExists(RegPath);
最后
注册免费;
结束;
除了
结果:=假;
结束;
结束;
函数GetDelphiXE2LocationExeName:string;
常数
Key='\Software\Embarcadero\BDS\9.0';
开始
结果:='';
如果存在注册表项(注册表项,HKEY_当前用户),则
开始
RegReadStr(键“应用程序”,结果,HKEY_当前用户);
出口
结束;
如果存在注册表项(注册表项、HKEY\U本地\U机器),则
RegReadStr(键“应用”,结果,HKEY_本地_机器);
结束;
变量
Bds:字符串;
开始
尝试
Bds:=GetDelphiXE2LocationExeName;
如果Bds为“”,则
开始
如果正在运行(Bds),则
Writeln('Delphi XE2 IDE正在运行')
其他的
Writeln('Delphi XE2 IDE未运行')
结束
其他的
Writeln('未找到Delphi XE2 IDE');
除了
关于E:Exception-do
Writeln(E.ClassName,“:”,E.Message);
结束;
Readln;
结束。
额外资源。

检查调试钩0。 缺点是,如果你的应用程序是用软件包构建的,DebugHook将返回0。
但通常这将是一个非常优雅和简单的测试。在D2009中工作得很好,我刚刚注意到它在XE2中有包依赖性错误(http://qc.embarcadero.com/wc/qcmain.aspx?d=105365).

如果可以找到主窗口的窗口句柄,可以使用GetWindowThreadProcessId获取进程id。然后调用OpenProcess获取进程句柄。然后调用GetModuleFileNameEx以获取exe文件名。然后使用GetFileVersionInfo等读取exe文件的版本资源。呸@大卫·费弗南::-)深呼吸,一次又一次。这应该会让你感觉更好。我希望上面的内容能起到作用,但如果有人能找到一个更简单的方法,我一点也不会感到惊讶。请注意,这样你就不能再访问
qc.embarcadero.com
链接了。如果您需要访问旧的QC数据,请查看。对于我来说,在win 10 x64中,我认为在以下注册表路径上检查更安全:“\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Embarcadero\BDS\xx.xx”是delphi版本的编号,例如:“\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Embarcadero\BDS\20.0”如果是Rio版本。