zoukankan      html  css  js  c++  java
  • delphi程序如何防止多实例启动

    1,前言

    delphi程序运行经常需要采用单实例方式,以免多个实例相互影响。那么,如何防止多实例启动呢?

    通常最为常用的是以下两种:

    • 采用mutex互斥量
    • 采用主窗口标题检测

    实践发现,无论以上哪种方式,都有坑需要避免。

    2,互斥量检测

    互斥量检测法,是在delphi程序启动时,创建某个唯一标识的互斥量,如果创建返回的结果是“互斥量已存在”,那么就说明windows系统内存中已经运行了该程序,此时程序退出,就实现了单例运行。

    伪代码如下:

    program RPMClient;
    
    uses
      Forms,
      dialogs,
      Ufunc in 'Ufunc.pas',
      Umain in 'uMain.pas' {fMain};
    
    {$R *.res}
    
    begin
      Application.Initialize;
    
      if AppIsRunning then begin
        //showMessage('程序已经启动,请勿重复启动!');
        application.Terminate;
        exit;
      end;
    
      Application.CreateForm(TfMain, fMain);
      Application.Run;
    end.

    其中的函数AppIsRunning 是关键,实现代码如下:

    function AppIsRunning: Boolean;
    var
      hmutex:hwnd;
      errno:integer;
    begin
      Result := False;
    
        hmutex:=createmutex(nil,false,pchar('RPMClient'));
        errno:=getlasterror;
        if errno=error_already_exists then
        begin
        Result := True;
        end;
    end;

    显然,以上代码非常常规,没有亮点。但是,如果不注意却可能留下隐患。

    注意其中的createmutex函数的第三个参数,采用的是pchar('RPMClient'),一个指向字符串常量的指针。

    如果将其改为指向变量的指针,则无法实现单例控制。如下述代码,采用Application.Title代替字符串常量,写法上似乎优雅一点,但是实践发现内存中会出现多实例。

    hmutex:=createmutex(nil,false,pchar(Application.Title));

    3,主窗口标题检测

    笔者也采用过FindWindow函数执行主窗口标题检测,来避免多实例启动。写法上,类似下面:

    function AppIsRunning: Boolean;
    var
      hWnd : THandle;
    begin
    
      hWnd:=FindWindow(nil,PChar('RPMClient'));//搜索窗口  API 在windows单元
      Result := hWnd<>0;
    end;

    该方法也很常规,在windows 7下运行正常,但是实践发现,在windows10操作系统中,内存中会出现多个实例。

    4,总结

    最终,笔者采用了createmutex函数执行单例控制,注意第三个参数采用字符串常量即可。在windows7和10下,均正常。

    为什么FindWindow在win10下不能正常检测呢?笔者不明白,猜测有可能是win10有时会把应用变为后台进程的缘故。

    至于createmutex为什么第三个参数不能是变量指针,笔者也不明白,猜测有可能是变量指针比常量指针更耗时,导致启动时来不及控制?

    总之,单例控制方法多且简单,但是如何使用还是有不少具体细节的,稍不注意就出现bug。笔者总结以上现象,以供同行借鉴。

  • 相关阅读:
    Python 学习日记 第七天
    Python 学习日记 第六天
    Python 学习日记 第五天
    Python 学习日记 第四天
    Redis 中的数据类型及基本操作
    Asp.net mvc 中View 的呈现(二)
    Asp.net mvc 中View的呈现(一)
    Asp.net mvc 中Action 方法的执行(三)
    Asp.net mvc 中Action 方法的执行(二)
    Asp.net mvc 中Action 方法的执行(一)
  • 原文地址:https://www.cnblogs.com/jackkwok/p/15659950.html
Copyright © 2011-2022 走看看