C # Several ways to let an application run only one instance

Source: Internet
Author: User

A judge whether there is a same instance already running 1 according to "Mutex" to determine whether there is the same instance running///<returns> an existing instance running returns true otherwise false</returns>
public bool Isrunningprocessbymutex ()
{
BOOL CreateNew;
using (System.Threading.Mutex Mutex = new System.Threading.Mutex (True, Application.productname, out CreateNew))
{
return!createnew;
}
}


Feature: Cannot return the Process of the previous (already running) instance

2 According to the "process name" to determine whether the same instance is running, if it is already running, return the running instance///<param Name= "runningprocess" > Previous instance process</param>
<returns> returned True if an instance is running, otherwise false</returns>
private static bool Getrunningprocessbyprocessname (out Process runningprocess)
{
BOOL returnvalue = false;
Runningprocess = null;

Process current = Process.getcurrentprocess ();
Process[] processes = Process.getprocessesbyname (current. ProcessName);
foreach (process process in processes)
{
if (process. Id! = Current. ID)
{
if (process. ProcessName = = Current. ProcessName)
{
runningprocess = process;
ReturnValue = true;
Break
}
}
}
Return returnvalue;
}


Features: 1) Different programs may have the same process name;
2) If you run an instance and then modify the file name to run another instance, this method fails.

3 based on "process name and path" to determine if there is the same instance running, if it is already running, return the running instance private static bool Getrunningprocessbyprocessfullname (out process runningprocess)
{
//... Other than process zoom, the same Method 2
if (process. Mainmodule.filename = =
Assembly.getexecutingassembly (). Location.replace ("/", "\ \"))
}


Features: Modify the file name or change the path of the files, this method is invalid.

4 determine if the same instance is running according to the signature of the Assembly, and if it is already running, return the running instance///<param Name= "runningprocess" > Previous instance process</param>
<returns> returned True if an instance is running, otherwise false</returns>
private static bool Getrunningprocessbyassemblyname (out Process runningprocess)
{
BOOL returnvalue = false;
Runningprocess = null;

AssemblyName Currentassemblyname =
Assemblyname.getassemblyname (assembly.getexecutingassembly (). Location);
AssemblyName processassemblyname = new AssemblyName ();

Process current = Process.getcurrentprocess ();
Process[] processes = process.getprocesses ();
foreach (process process in processes)
{
Eliminating some other process can speed up the point.
if (process. Id! = Current. Id &&
Process. ProcessName! = "System" &&
Process. ProcessName! = "Csrss" &&
Process. ProcessName! = "Svchost" &&
Process. ProcessName! = "Services" &&
Process. ProcessName! = "SMSs" &&
Process. ProcessName! = "Winlogon" &&
Process. ProcessName! = "Explorer" &&
Process. ProcessName! = "PDS" &&
Process. ProcessName! = "ALG" &&
Process. ProcessName! = "MSDTC" &&
Process. ProcessName! = "SPOOLSV" &&
Process. ProcessName! = "LSASS" &&
Process. ProcessName! = "Idle" &&
Process. ProcessName! = "IEXPLORE" &&
Process. ProcessName! = "SQL Server" &&
Process. ProcessName! = "Notepad" &&
Process. ProcessName! = "360tray" &&
Process. ProcessName! = "Xdict"
)
{
Try
{
Gets the assembly of the file
Processassemblyname = Assemblyname.getassemblyname (process. Mainmodule.filename);
}
catch (Exception)
{
Processassemblyname = null;
}

The public key of the assembly is obtained through Getpublickey (), the Assembly needs to be signed, otherwise Getpublickey () returns NULL.
if (processassemblyname! = null &&
Comparebytes (Currentassemblyname.getpublickey (),
Processassemblyname.getpublickey ()))
{
runningprocess = process;
ReturnValue = true;
Break
}
}
}
Return returnvalue;
}

Compares two byte arrays for equality
private static bool Comparebytes (byte[] bytes1, byte[] bytes2)
{
if (bytes1 = = NULL | | bytes2 = = NULL)
return false;

if (bytes1. Length! = Bytes2. Length)
return false;

for (int i = 0; i < bytes1. Length; i++)
{
if (bytes1[i]! = Bytes2[i])
return false;
}
return true;
}


Features: 1). exe file renamed or path changed, this method is working properly
2) The Assembly needs to be signed. There is a problem: the speed is slightly slower

5 using global atoms to determine if there are identical instances running public bool Isrunningprocessbyatom ()
{
BOOL ReturnValue = true;
No Atom Atom_test is found, the process is not yet running, adding the atom
if (Globalfindatom ("atom_test") = = 0)
{
Globaladdatom ("Atom_test");
ReturnValue = false;
}

Return returnvalue;
}

[System.Runtime.InteropServices.DllImport ("kernel32.dll")]
public static extern UInt32 Globaladdatom (String lpstring); Adding atoms
[System.Runtime.InteropServices.DllImport ("kernel32.dll")]
public static extern UInt32 Globalfindatom (String lpstring); Find atoms
[System.Runtime.InteropServices.DllImport ("kernel32.dll")]
public static extern UInt32 Globaldeleteatom (UInt32 natom); Delete Atom


Features: When exiting the program, remember to release the added atoms, or it will be released until the shutdown.

Set the window of the specified process to the active window 1 if the window is minimized, set as the Restore window; otherwise, the window will be set as the active window, displayed to the foreground///The window of the specified process is active
private static void setforegroundprocess (process process)
{
BOOL Isicon = isiconic (process. Mainwindowhandle);
Whether the window has been minimized
if (Isicon)
{
Restore window
Showwindowasync (process. Mainwindowhandle, Sw_restore);
}
Else
{
If the desired window appears in normal mode, you can set the following settings first
Showwindowasync (process. Mainwindowhandle, SW_SHOWNORMAL);
Set the window as the foreground window
SetForegroundWindow (process. Mainwindowhandle);
}
}2 related Windows API functions that are displayed according to the Window Handle Control window///restore a minimized program and activate it
<param name= "hWnd" > Window handle </param>
<returns> nonzero indicates success, 0 indicates failure </returns>
[System.Runtime.InteropServices.DllImport ("User32.dll")]
private static extern bool Openicon (IntPtr hWnd);

Whether the window has been minimized
[System.Runtime.InteropServices.DllImport ("User32.dll")]
private static extern bool Isiconic (IntPtr hWnd);

Set the window as the foreground window of the system
[System.Runtime.InteropServices.DllImport ("User32.dll")]
private static extern int SetForegroundWindow (IntPtr hWnd);

Similar to ShowWindow, only then the ShowWindow command is posted to the specified window and then processed asynchronously.
This allows you to control the visibility of windows that belong to another process.
Without worrying about when another process hangs, your application will also implicate the return value
<param name= "Cmdshow" > Specify a command for the visual aspect of the window </param>
<returns> returns True (not 0) if it is visible before the window, otherwise false (0) </returns>
[System.Runtime.InteropServices.DllImport ("User32.dll")]
private static extern bool Showwindowasync (IntPtr hWnd, int cmdshow);

Related constants
Private Const int sw_hide = 0; Hide window, active state to make a window
Private Const int SW_SHOWNORMAL = 1; Displays a window with its original size and position, and moves it to the active state
Private Const int sw_showminimized = 2; Minimize the window and activate it
Private Const int sw_showmaximized = 3; Maximizes the window and activates it
Private Const int sw_shownoactivate = 4; Displays a window with the nearest size and position without changing the active window
Private Const int sw_restore = 9; Displays a window with its original size and position, and moves it to the active state
Private Const int sw_showdefault = 10; Displayed according to the style when the window is created by default
#endregion Three code examples that implement the following features

1) The program can only run one instance.
2) If the program already exists and is minimized, restore the program.
3) If the program already exists and is not minimized (maximized or normal), then display (Note: not restore!) ) that program.

static void Main ()
{
Process runningprocess = null;
BOOL isrunning = Getrunningprocessbyprocessfullname (out runningprocess);
if (isrunning)
{
There is already an instance running
Setforegroundprocess (runningprocess);
}
Else
{
No instances are running
Application.Run (New Form1 ());
}
}


You can also use the mutex method to determine whether the same instance is running, if there is, take the instance, other processing methods as above.

Other ideas: first with the mutex method, if the program has run, then use SendMessage to send a message to the program, in the program to override the WndProc method, in this method to process the message. The handle in SendMessage can be used with the System.Diagnostics.Process.GetProcessesByName (process name) [0]. Mainwindowhandle obtained.

C # Several ways to let an application run 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.