Several ways to start a program with only one instance

Source: Internet
Author: User

We use the "PowerWord" found that in the "PowerWord" has been running the case, click on the "Kingsoft PowerWord" icon, then it will not run another "PowerWord", but will have "PowerWord" to activate, always can only run a "PowerWord" example.
In our program if you want to achieve similar "Kingsoft PowerWord" function, it is necessary to solve two problems, the first is to determine that the program has an instance running, followed by activating the running application instance, and exiting the second application instance.
For the first question, we can determine that an instance of this program is running by setting up a named mutex object or a named Beacon object to detect a mutex or Beacon object when the program starts, such as a mutex object or a Beacon object already exists.
The second question is how to find an application instance that is already running, and if we can find a pointer to the main window of the running instance, we can invoke SetForegroundWindow to activate the instance. We can find the main window of the running instance in two forms, one of which is to find a handle to the running window by calling FindWindowEx, which is used more, and this article finds a handle to the running window in another way. By calling SetProp to set a tag for the Application main window, GetDesktopWindow can get a handle to the desktop window in the Windows environment, and the main window of all applications can be considered a child window of that window. Then we can use the GetWindow function to get the handle of these windows. Then use the Win32 SDK function Getprop to find out whether the main window of each application contains the tags we set, so we can find the first instance of the main window we are looking for.
The following demo code is a single document application, for example, the project name is a mutex.
1. In the Application class InitInstance () function, determine if an application instance is already running.
BOOL cmutexapp::initinstance ()
{
Creates a named Beacon object.
HANDLE Hsem=createsemaphore (null,1,1, "Restoration");
if (HSEM)//Beacon object was created successfully.
{
The Beacon object already exists, and the program already has an instance running.
if (Error_already_exists==getlasterror ())
{
CloseHandle (Hsem); Closes the semaphore handle.

Gets a child window of the desktop window.
HWND Hwndprev=::getwindow (:: GetDesktopWindow (), gw_child);

while (:: IsWindow (Hwndprev))
{
Determine if the window has our pre-set tag, and if so, it is the window we are looking for and activates it.
if (:: Getprop (Hwndprev, "Restoration"))
{
If the main window is minimized, its size is restored.
if (:: Isiconic (Hwndprev))
:: ShowWindow (Hwndprev,sw_restore);

Activates the main window of the application.
:: SetForegroundWindow (Hwndprev);
return FALSE; Exits the instance.
}
Continue looking for the next window.
Hwndprev =:: GetWindow (Hwndprev,gw_hwndnext);
}

AfxMessageBox ("There is already an instance running, but can't find its main window!") ");
}
}
Else
{
AfxMessageBox ("Create Beacon object failed, program quits!") ");
return FALSE;
}

AfxEnableControlContainer ();

Standard initialization
If you is not using these features and wish to reduce the size
of your final executable, you should remove from the following
The specific initialization routines you does not need.

#ifdef _afxdll
Enable3dcontrols (); Call the When using the MFC in a shared DLL
#else
Enable3dcontrolsstatic (); Linking to MFC statically
#endif

The change of the registry key under which our settings is stored.
Todo:you should modify this string to be something appropriate
such as the name of your company or organization.
Setregistrykey (_t ("Local appwizard-generated Applications"));

LoadStdProfileSettings (); Load standard INI file options (including MRU)

Register the application ' s document templates. Document templates
Serve as the connection between documents, frame windows and views.

Csingledoctemplate* pdoctemplate;
Pdoctemplate = new CSingleDocTemplate (
Idr_mainframe,
Runtime_class (Cmutexdoc),
Runtime_class (CMainFrame),//main SDI frame window
Runtime_class (Cmutexview));
AddDocTemplate (pdoctemplate);

Parse command line to standard shell commands, DDE, File Open
CCommandLineInfo Cmdinfo;
ParseCommandLine (Cmdinfo);

Dispatch commands specified on the command line
if (! ProcessShellCommand (Cmdinfo))
return FALSE;

The one and only window have been initialized, so show and update it.
M_pmainwnd->showwindow (Sw_show);
M_pmainwnd->updatewindow ();

return TRUE;
}
2. Set the lookup tag in the OnCreate () function of the framework class.
int CMainFrame::OnCreate (lpcreatestruct lpcreatestruct)
{
if (cframewnd::oncreate (lpcreatestruct) = =-1)
return-1;

if (!m_wndtoolbar.createex (this, Tbstyle_flat, Ws_child | ws_visible | Cbrs_top
| Cbrs_gripper | Cbrs_tooltips | cbrs_flyby | Cbrs_size_dynamic) | |
!m_wndtoolbar.loadtoolbar (IDR_MAINFRAME))
{
TRACE0 ("Failed to create toolbar\n");
return-1; Fail to create
}

if (!m_wndstatusbar.create (this) | |
!m_wndstatusbar.setindicators (indicators,
sizeof (indicators)/sizeof (UINT))
{
TRACE0 ("Failed to create status bar\n");
return-1; Fail to create
}

Todo:delete These three lines if you don ' t want the toolbar to
Be dockable

M_wndtoolbar.enabledocking (Cbrs_align_any);
EnableDocking (Cbrs_align_any);
DockControlBar (&m_wndtoolbar);


Sets the lookup token.
:: SetProp (M_hwnd, "Restoration", (HANDLE) 1);

return 0;
}
3, in the program exit is to delete the set of tags, in the framework class in response to the WM_DESTROY message, processing.
void Cmainframe::ondestroy ()
{
Cframewnd::ondestroy ();

Todo:add your message Handler code here
Removes the set of tags.
:: Removeprop (M_hwnd, "Restoration");
}
At this point, the ability to run only one instance of an application is complete.

  several ways to start a program with only one instance Sometimes, we ask a program to launch only one instance in the system. Windows Medea player, for example, can only start an instance of Windows with its own playback software. The reason is simple, if you start several instances at the same time, but play different files, then the sound and image will cause confusion. In design mode, there is a singleton pattern, which is to have only one instance of the class. (about singleton mode, you can see my "re-reading" Design Patterns "study notes (iii)--singleton mode of Doubt").
For the program, we can only detect a setting when the program starts, if the program does not start, update the settings to the program has started, and then start the program normally, if the program has started, then terminate the program start. Restore the settings to a program that did not start when the program exited. According to the above ideas, we can easily think of the following two ways:
One, the document law
Create a file on your hard disk and set a value in the file to determine if the program has started.
Two, registration form method
Creates a key in the registry that determines whether to start the program, based on the key value of the key.
However, both of the above methods have I/O operations. I don't think that's the best way. Here are two ways to do this without I/O. The idea is the same as above, when the process starts to detect whether a setting continues to start the process. Because you want to determine whether the same program has started an instance, that is, there will be two processes to access the same settings, so this setting should be able to boast process access, such as the above two methods of the file and the registry. When we are developing with VC, we can also use the file mapping and mutex amount. The following is a detailed description:
VC will automatically create an app class when creating a project. For example, if your project name is Starlee, then the class name of the App class is Cstarleeapp. The two methods of the class are called separately when the process starts and exits: InitInstance () and ExitInstance (). So, all of our code is added to these two methods.
Third, file mapping method
First, add a member variable to the App class:HANDLE m_hfilemapping;

Then, add the following code to the front of the InitInstance () method of the App class:

m_hfilemapping = createfilemapping (null, NULL, page_readonly, 0, "Starlee");

//Detect if Filemapping has been created
//If you have already created it, terminate the start of the process
if ((m_hfilemapping! = NULL) && (GetLastError () = = error_already_exists))
{
CloseHandle (m_hfilemapping);
    
MessageBox (NULL, "The process has started", "Error", MB_OK);

return FALSE;
}

Finally, add the following code to the ExitInstance () method of the App class:

if (m_hfilemapping! = NULL)
CloseHandle (m_hfilemapping);

four, Mutex method
First, add a member variable to the App class:

HANDLE M_hmutex;

Then, add the following code to the front of the InitInstance () method of the App class:

M_hmutex = CreateMutex (NULL, TRUE, "Starlee");

//Detect if a mutex has been created
//If you have already created it, terminate the start of the process
if ((M_hmutex! = NULL) && (GetLastError () = = error_already_exists))
{
ReleaseMutex (M_hmutex);

MessageBox (NULL, "The process has started", "Error", MB_OK);
 
return FALSE;
}

Finally, add the following code to the ExitInstance () method of the App class:

if (M_hmutex! = NULL)
{
ReleaseMutex (M_hmutex);
CloseHandle (M_hmutex);
}

The above two methods of thinking and code to add the same steps, of course, the same effect, the choice of any method can be used to enable the process to start only one instance.

Several ways to start a program with only one instance

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.