Run two or more instances

Source: Internet
Author: User
Run two or more instances Delphi/Windows SDK/API
Http://www.delphi2007.net/DelphiAPI/html/delphi_20061116093635223.html
How to avoid Program Are two or more instances running at the same time?

Reference: http://www.zahui.com/html/2/5251.htm

Use mutex object to run the program only once
"How can I keep my program open repeatedly at runtime ?" I often see a friend asking this question on the forum. This article describes this problem in detail and provides a more comprehensive solution.

Although this is no longer a new problem, here is a brief description of this technology: It is indeed a very useful technology, you may often notice that after running a considerable number of programs, When you click "run" again, it will only return to the original window without running two programs. Just as when you open another project file externally when running Delphi, Delphi simply replaces your current project rather than running two Delphi files. The advantage is obvious: You don't have to worry that your program may be maliciously run multiple times by other software and the memory is swallowed up to become a machine. The following is a description:

Friends who are familiar with Win32 programming (especially multithreading programming), I believe they are already quite familiar with mutex objects, and they are often used as technical means for inter-thread synchronization. Here we use it to prevent repeated program running. We just briefly mention the mutex object and do not conduct in-depth research: the mutex object uses the program created for the first time as the main program, in this way, we only need to check whether the mutex object has a main program to determine whether the program has run. Here we need to involve an API function: waitforsingleobject. The first parameter of this function is the mutex object used for detection, the first parameter indicates the retention time before the function returns the result. If the function returns wait_timeout, it indicates that the mutex object already has a main program. Modified project file Code (Note: The following code appears in the project file, rather than in the unit file, and is modified on the basis of the simplest default project created by Delphi)

VaR

Mymutex: hwnd;

Begin

Mymutex: = createmutex (nil, false, 'hkonecopy'); // createmutex creates a mutex object and gives it a unique name.

If waitforsingleobject (mymutex, 0) <> wait_timeout then // The program has not been run

Begin

Application. initialize;

Application. createform (tform1, form1 );

Application. Run;

End;

End;

The following work is to improve this program. We hope that the program can not be run repeatedly, but also that when the user clicks the executable file again, the running program can make some responses. Here we want it to become the upper-level activity window to remind the user that the program has been run. To achieve this goal, we must first obtain the window handle of the running program so that setforegroundwindow (handle) can be used to make the program window start and activate. To get this handle, we must use the Windows enumeration function enumwindows to traverse the Windows window list. This function can use a callback function as a parameter, this callback function is used to call each system window until the last window or callback function returns false. This callback function requires two parameters (handle, Cardinal, only pay attention to the first handle parameter, which indicates the window handle currently traversed by the enumeration function ). We only need to write this function and continuously compare the name of the currently traversed window class with the name of the main window class of our program, and compare the name of the window executable file and the name of our program until the same one is found. Save the window handle and add the appropriate comments to the following code:

Function enumwndproc (hwnd: thandle; Param: Cardinal): bool; stdcall;

// For API callback functions, use the traditional parameter passing method stdcall in windows.

VaR

Classname, winmoudlename: string;

Wininstance: thandle;

Begin

Result: = true;

Setlength (classname, 100 );

Getclassname (hwnd, pchar (classname), length (classname); // obtain the Class Name of the current traversal window

Classname: = pchar (classname); // Add the terminator after the string to determine whether the string ends.

If classname = tform1.classname then // comparison

Begin

Wininstance: = getwindowlong (hwnd, gwl_hinstance); // obtain the instance of the current traversal window

Setlength (winmoudlename, 100 );

Getmodulefilename (wininstance, pchar (winmoudlename), length (winmoudlename ));

// Obtain the program file name for the current traversal window

Winmoudlename: = pchar (winmoudlename );

If winmoudlename = moudlename then // moudlename is the project global variable, and the program file name

Begin

Findhid: = hwnd; // The findhid is the link found when the global variable of the Project is saved.

Result: = false; // The traversal ends after it is found.

End;

End;

End;

The following are all project files:

VaR

Hmutex, findhid: hwnd;

Moudlename: string;

Begin

Hmutex: = createmutex (nil, false, 'hkonecopy ');

If waitforsingleobject (hmutex, 0) <> wait_timeout then

Begin

...... // Skip the code above

End

Else

Begin

Set length (moudlename, 100 );

Getmodulefilename (hinstance, pchar (moudlename), length (moudlename ));

// Obtain the program file name

Moudlename: = pchar (moudlename );

Enumwindows (@ enumwndproc, 0); // call the enumeration Function

If findhid <> 0 then

Setforegroundwindow (findhid );

End;

End.

To make our program more perfect, so that it can display more features during repeated operations (for example, the replacement project file in Delphi is the current open project ), you can also send user messages to the window handle you find, and then process the messages in the window's message processing function. You will surely make our programs more dizzy!

References:

Delphi developer Guide

Program project1;

Uses
Forms, windows,
Unit1 in 'unit1. pa' {form1 };

VaR
Hmutex: thandle;

{$ R *. Res}

Begin
Hmutex: = openmutex (mutex_all_access, true, 'testmutex ');
If hmutex <> 0 then
Begin
Application. Terminate;
End;
Application. initialize;
Createmutex (mutex_all_access, false, 'testmutex ');
Application. createform (tform1, form1 );
Application. Run;
End.

modify the above Code and add an exit.
hmutex: = openmutex (mutex_all_access, true, 'testmutex ');
If hmutex <> 0 then
begin
application. terminate;
exit;
end;
application. initialize;
createmutex (nil, false, 'testmutex ');
application. createform (tform1, form1);
application. run;

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.