我的程序如何判断Delphi是否正在运行?

9

我听说一些自定义组件作者使用一个RTL例程来检查Delphi是否在运行,以设置共享软件的限制。 有人知道这个例程是什么吗? 检查明显的名称,如“DelphiRunning”或“IsDelphiRunning”,没有发现任何有用的信息。

3个回答

20

2个不同的想法
- Delphi正在运行
- 应用程序在调试器下运行

测试 Delphi是否在运行 的常见方法是检查已知IDE窗口的存在,这些窗口具有特定的类名,例如TAppBuilder或TPropertyInspector。
据我所知,这两者都适用于所有版本的Delphi。

如果您想知道您的应用程序是否以调试器方式运行,即通过“运行”(F9)从IDE正常启动或已经运行并连接到调试器,则只需测试DebugHook全局变量即可。
请注意,“从程序中分离”不会删除DebugHook值,但“附加到进程”会设置它。

function IsDelphiRunning: Boolean;
begin
  Result := (FindWindow('TAppBuilder', nil) > 0) and
    (FindWindow('TPropertyInspector', 'Object Inspector') > 0);
end;

function IsOrWasUnderDebugger: Boolean;
begin
  Result := DebugHook <> 0;
end;
如果目标是限制应用程序开发期间使用试用版本,则两者都存在缺陷: - 应用程序中可以包括具有适当类名/标题的隐藏窗口 - 可以在代码中手动设置DebugHook

+1,但如果出现“- DebugHook可以在代码中手动设置”的情况该怎么办?简而言之,这两个缺陷都有解决方法吗? - PresleyDias
1
@PresleyDias,然后你开始玩猫捉老鼠的游戏......需要记住的一件事是,手动设置 DebugHook 如果应用程序遇到 DebugBreakasm int 3 end 并且没有真正的调试器,则可能导致应用程序崩溃... - Francesca
哦,好的 :P ... 那么如果它导致应用程序崩溃,那也没关系。 - PresleyDias

4
你可以在组件代码中使用DebugHook <> 0。 DebugHook是一个全局变量(如果我没记错的话,它在Systems单元中),由Delphi / RAD Studio IDE设置,无法从其他任何地方设置。
还有其他技术(例如TAppBuilder的FindWindow()),但DebugHook会省去所有这些工作。

DebugHook 只有在 IDE 内按下 F9 时才会报告为 true。如果在 IDE 中按下 Ctrl + Shift + F9,则不会报告为 true。 - Michael Riley - AKA Gunny
1
@MichaelRiley-AKAGunny:当然是这样的。Ctrl+Shift+F9是“无调试运行”,很明显不会设置DebugHook。但是如果你没有在调试器的控制下运行,那么你就不是在IDE中运行,对吧? - Ken White

1
这是一个来自www.delphitricks.com/source-code/misc/check_if_delphi_is_running.html的代码片段。
function WindowExists(AppWindowName, AppClassName: string): Boolean; 
var 
  hwd: LongWord; 
begin 
  hwd    := 0; 
  hwd    := FindWindow(PChar(AppWindowName), PChar(AppClassName)); 
  Result := False; 
  if not (Hwd = 0) then {window was found if not nil} 
    Result := True; 
end; 

function DelphiLoaded: Boolean; 
begin 
  DelphiLoaded := False; 
  if WindowExists('TPropertyInspector', 'Object Inspector') then 
    if WindowExists('TMenuBuilder', 'Menu Designer') then 
      if WindowExists('TAppBuilder', '(AnyName)') then 
        if WindowExists('TApplication', 'Delphi') then 
          if WindowExists('TAlignPalette', 'Align') then 
            DelphiLoaded := True; 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
  if DelphiLoaded then 
  begin 
    ShowMessage('Delphi is running'); 
  end; 
end; 


function DelphiIsRunning: Boolean; 
begin 
  Result := DebugHook <> 0; 
end;

3
复制并粘贴的恐怖。这段代码片段应该被清理或遗忘。真的。 - Francesca

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接