[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 256
  • Last Modified:

Prevent application runs twice..

Hi Experts, how can I do that ? So if user run my application at the second time, the last application will terminate immediately.
I want the code and an explaination 'cos I'm a new Delphian here... :)
I hope giving you 75 points is enough for this question.


Blurp slurp ...

XNokia 6110
0
XNokia
Asked:
XNokia
  • 2
1 Solution
 
RBertoraCommented:
Hi this should help you
Rob ;-)

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

    function IsPrevInst: Boolean;
    var
      semName,
      appClass: PChar;
      hSem    : THandle;
      hWndMe1,hWndMe2  : HWnd;
      appTitle: Array[0..MAX_PATH] of Char;
    begin
      // Init
      Result := FALSE;
      GetMem(semName,15);
      GetMem(appClass,15);
      StrPCopy(semName,'SemaphoreName');
      StrPCopy(appClass,'TApplication');
      StrPCopy(appTitle,ExtractFileName(Application.Title));

      // Create a Semaphore in memory.  If this is the
      // first instance, then hSem's value should be 0.
      hSem := CreateSemaphore(nil,0,1,semName);

      // Check to see if the semaphore exists
      if (hSem <> 0) and (GetLastError() = ERROR_ALREADY_EXISTS) then
        begin
          CloseHandle(hSem);

          // Get the currently executing window's handle then change
          // its title so we can look for the other instance
          hWndMe1 := FindWindow(appClass,appTitle);
          SetWindowText(hWndMe1,'ZZZZZZZ');

          // Search for the other instance of this window then bring
          // it to the top of the Z-order stack.  We find it by
          // matching the Application Class and Application Title.
          hWndMe2 := FindWindow(appClass,appTitle);
          if (hWndMe2 <> 0) then
            begin
  // keep the old instance of the application and close the new one
  // uncomment the line 1 and 2, and comment line 3 and 4
  //    {1}          BringWindowToTop(hWndMe);
  //    {2}        ShowWindow(hWndMe,SW_SHOWNORMAL);
  // if you want to close the old instance of the application an keep the new one
  // uncomment line 3 and 4 keep line 1 and 2 commented!!
        {3}        sendmessage(hWndMe2,WM_Close,0,0);
        {4}        SetWindowText(hWndMe1,appTitle);
            end;

          Result := TRUE;
        end;

      // Destroy PChars
      FreeMem(semName,15);
      FreeMem(appClass,15);
    end;


procedure TForm1.FormCreate(Sender: TObject);
begin
  if isprevinst then beep;
end;

end.
0
 
LischkeCommented:
Hi XNokia,

do you only need to know whether a previous instance of your application is already running or do you want to pass command line parameters of the second instance to the first one before terminating the second instance?

If you don't need to pass command lines around then there are several easy posibilities. One is to register a global ID with the system on startup of the first instance and a check for this ID to know whether a specific instance is not the first one.

Use on startup (e.g. in the project source (*.dpr file)):

  MyAtom := GlobaFindAtom('MyUniqueString');

to check whether your ID has already been registered. If MyAtom is zero then the ID is not registered yet and the instance is the first one. In this case it calls

  MyAtom := GlobalAddAtom('MyUniqueString');

to register now the ID and on program termination you need to call:

  GlobalDeleteAtom(MyAtom);

If MyAtom returned from GlobalFindAtom is <> 0 then there's already a running instance and the second one needs to quit.


A second possibility to force only one instance is to use FindWindow. A starting application would look for its own main window before it is created in the starting application. If the window is already there then there's also an already running first instance and the window can be used to bring the first instance to front.

A third way is the use of a file mapping, which is very elegant and which can be used to pass command line parameters (my preferred solution).

Ciao, Mike
0
 
XNokiaAuthor Commented:
Thanx to Rob and Mike.

Rob, your answer is long but good, so I can modified the code to not just send WM_CLOSE but my built-in message... That helps so much...

And to Mike, your GlobalAddAtom is good and effective... and the third way you're saying that I must use AssignFile(f,'temp.txt') to make a flag ( If I'm not wrong ? 'Cos dunno what you mean about file mapping ). But those help much...

And the points wil be ......






te teet teeet...










For Rob !! Cos you answered at the 1'st time ...
Congratulation you're awarded 75 points... heheheh ( just like quiz )


XNokia 9110 - Connecting Popeye
0
 
LischkeCommented:
:-)) No, no, file mapping has nothing to do with AssignFile etc. See CreateFileMapping in the Win32.hlp. This maps a part of a file (even the system swap file) into the memory for direct (random) access...

Ciao, Mike
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now