• 防止程序重复执行 Controling the number of application instances


    http://delphi.about.com/library/weekly/aa100703a.htm

    {
      Article:
    
      Controling the number of application instances
    
      http://delphi.about.com/library/weekly/aa100703a.htm
    
      In this article you'll learn how to "run-once enable"
      a Delphi application that can check for its previous
      (running) instance. Along the process, several techniques
      of implementing such a check will be discussed; as well
      as how to bring your already running application to the
      foreground, if a user tries to run it "one more time". By
      the end of the article you'll have a copy-to-go code to
      control the behavior of your application's multiple instances:
      with the option to limit the number of running instances.
    }
    
    unit uCheckPrevious;
    
    interface
    
    uses Windows, SysUtils;
    
    function RestoreIfRunning( const AppHandle : THandle;
      MaxInstances : integer = 1 ) : boolean;
    
    implementation
    
    type
      PInstanceInfo = ^TInstanceInfo;
    
      TInstanceInfo = packed record
        PreviousHandle : THandle;
        RunCounter : integer;
      end;
    
    var
      MappingHandle : THandle;
      InstanceInfo : PInstanceInfo;
      MappingName : string;
    
      RemoveMe : boolean = True;
    
    function RestoreIfRunning( const AppHandle : THandle;
      MaxInstances : integer = 1 ) : boolean;
    begin
      Result := True;
    
      MappingName := StringReplace( ParamStr( 0 ), '\', '',
        [ rfReplaceAll, rfIgnoreCase ] );
    
      MappingHandle := CreateFileMapping( $FFFFFFFF, nil, PAGE_READWRITE, 0,
        SizeOf( TInstanceInfo ), PChar( MappingName ) );
    
      if MappingHandle = 0 then
        RaiseLastOSError
      else
      begin
        if GetLastError <> ERROR_ALREADY_EXISTS then
        begin
          InstanceInfo := MapViewOfFile( MappingHandle, FILE_MAP_ALL_ACCESS, 0, 0,
            SizeOf( TInstanceInfo ) );
    
          InstanceInfo^.PreviousHandle := AppHandle;
          InstanceInfo^.RunCounter := 1;
    
          Result := False;
        end
        else // already runing
        begin
          MappingHandle := OpenFileMapping( FILE_MAP_ALL_ACCESS, False,
            PChar( MappingName ) );
          if MappingHandle <> 0 then
          begin
            InstanceInfo := MapViewOfFile( MappingHandle, FILE_MAP_ALL_ACCESS, 0, 0,
              SizeOf( TInstanceInfo ) );
    
            if InstanceInfo^.RunCounter >= MaxInstances then
            begin
              RemoveMe := False;
    
              if IsIconic( InstanceInfo^.PreviousHandle ) then
                ShowWindow( InstanceInfo^.PreviousHandle, SW_RESTORE );
              SetForegroundWindow( InstanceInfo^.PreviousHandle );
            end
            else
            begin
              InstanceInfo^.PreviousHandle := AppHandle;
              InstanceInfo^.RunCounter := 1 + InstanceInfo^.RunCounter;
    
              Result := False;
            end
          end;
        end;
      end;
    end; (* RestoreIfRunning *)
    
    initialization
    
    // nothing special here
    // we need this section because we have the
    // finalization section
    
    finalization
    
    // remove this instance
    if RemoveMe then
    begin
      MappingHandle := OpenFileMapping( FILE_MAP_ALL_ACCESS, False,
        PChar( MappingName ) );
      if MappingHandle <> 0 then
      begin
        InstanceInfo := MapViewOfFile( MappingHandle, FILE_MAP_ALL_ACCESS, 0, 0,
          SizeOf( TInstanceInfo ) );
    
        InstanceInfo^.RunCounter := -1 + InstanceInfo^.RunCounter;
      end
      else
        RaiseLastOSError;
    end;
    
    if Assigned( InstanceInfo ) then
      UnmapViewOfFile( InstanceInfo );
    if MappingHandle <> 0 then
      CloseHandle( MappingHandle );
    
    end. (* unit uCheckPrevious *)
    program XXX;
    
    uses
      Forms,
      ...
      uCheckPrevious in 'uCheckPrevious.pas';
    
    {$R *.RES}
    
    begin
      if not uCheckPrevious.RestoreIfRunning( Application.Handle ) then
      begin
        Application.Initialize;
        Application.Title := 'Hex Editor';
        Application.CreateForm( TMain, Main );
        Application.Run;
      end;
    
    end.

  • 相关阅读:
    Fbpanel-轻巧的面板措施
    Skype for Linux 1.4 Alpha 公布
    KFTPgrabber 0.8.1
    Ardour:专业的数字音频任务站
    Cinelerra:视频编纂软件
    V2EX::ING 与 INGC
    HandBrake:DVD 转换工具
    XML Copy Editor:XML 编纂器
    Abraca:XMMS2 的客户端
    KMess:MSN Messenger for KDE
  • 原文地址:https://www.cnblogs.com/shangdawei/p/3060435.html
Copyright © 2020-2023  润新知