zoukankan      html  css  js  c++  java
  • 防止程序重复执行 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.

  • 相关阅读:
    Longest Subsequence CodeForces
    Alyona and towers CodeForces
    Electric Charges CodeForces
    Array GCD CodeForces
    笔记(模拟)
    城堡 (spfa+cheng)
    YOU ARE MY SUNSHINE
    AC日记——潜伏者 洛谷 P1071 (模拟)
    AC日记——神奇的幻方 洛谷 P2615(大模拟)
    AC日记——机器翻译 洛谷 P1540
  • 原文地址:https://www.cnblogs.com/shangdawei/p/3060435.html
Copyright © 2011-2022 走看看