Sometimes you want to run an instance of a program for the first time, and sometimes you may only need to run the latest instance. Here are the two examples of these two methods.
How can you make sure there is only one .NET program running on your machine? Multitasking operating systems are useful in many ways, but sometimes you only need to run an instance in a certain time, for example, if the program needs to use a lot of resources or to access a certain resource. In this case, you may want to confirm that when another instance is started, it checks if another instance is running. If so, turn itself. In this article, I will tell you how to implement it, and how only the latest program instance is allowed in the relevant case. Please download the program source code ftp://ftp.wdj.com/pub/webzip/newsletters/20030815dnn.zip/Wub/webzip/newsletters/20030815dnn.zip
The easiest way is to use Mutex objects. For example, in the following code, a MUTEX object is created in the Form's constructor and then try to access it. If Waitone () returns true, the current thread already has Mutex, if the false is returned, Mutex has been owned by another thread.
Using system;
Using system.windows.forms;
Using system.threading;
Class app: form
{
Mutex mutex;
App ()
{
TEXT = "Single Instance!";
Mutex = new mutex (false, "single_instance_mutex");
IF (! Mutex.waitone (0, false)
{
Mutex.close ();
Mutex = NULL;
}
}
Protected Override Void Dispose (Bool Disposing)
{
IF (Disposing)
Mutex.releasemutex ();
Base.dispose (Disposing);
}
Static void main ()
{
App APP = New App ();
IF (App.Mutex! = NULL) Application.Run (app);
Else MessageBox.show ("Instance Already Running");
}
}
In the above code, method Dispose () is not strict, because the garbage collector will dispose and Release Mutex objects when the program ends. But I still add it, because Form needs a long time to release (Dispose), and another form (form) instance will start.
This method only allows the first process instance to run. But what if you just want to run the latest instance? That is to say, if I launched a new process instance, and I have already running it, then we need to stop the thread before. For example, the display properties dialog for the screen saver. This dialog box displays a small preview window. When the user clicks the preview button, another screen saver instance is started and the full screen is displayed. When the full-screen instance is stopped (for example, you move the mouse), another screen save instance will start running in a small preview window. Obviously, when the full-screen instance begins, the preview of the screensold window process will end.
One implementation method is to access a named event core object for each instance. If the event object is not triggered, then this instance continues to run; if the event is triggered, the program instance Will end. The application can periodically test the event to see if it has been triggered. When a new instance is started, it will set an event (to close any other instance) and then reset the event to keep it running. This scheme is well operating in addition to a small problem: .NET Framework does not allow you to name a core event (kernel Event). Here is an implementation class public class namedEventHelper
{
[DLLIMPORT ("kernel32")]]
Static Extern Uint CreateEvent (
Uint Sec, Bool ManualReset, Bool InitialState, String Name;
Static INTPTR CREATEEVENT (Bool ManualReset, Bool InitialState, String Name)
{
Return New INTPTR (CreateEvent (0, ManualReset, InitialState, Name);
}
[DLLIMPORT ("kernel32")]]
Static Extern Bool CloseHandle (INTPTR HANDLE);
Public Static ManualReveTevent CreateNameDevent (
Bool InitialState, String Name
{
ManualReveTevent MRE = New ManualRetevent (false);
CloseHandle (MRE.HANDLE);
Mre.handle = CreateEvent (True, InitialState, Name);
Return MRE;
}
}
In the above code, the static method CreateNameDevent () creates a ManualResetEvent object and releases the current (underlying) Win32 handle (Handle). Then create a named event and initialize the ManualResetEvent object using the handle of this new event. This event object can be used in communication between two applications.
The weakness of this solution is an application must see if it has ended. One solution is to run a background thread to manage events
ManualReveTevent MRE;
MRE = NameDeventHelper.createNameDevent (false, "las_instance_only");
// stop the other instances
MRE.SET ();
// Reset the Event SO That We can run
MRE.RESET ();
// Create a monitor thread
Thread T = New Thread (New ThreadStart (Monitor));
// Make Sure That Thiead Cannot Keep The App Alive
T.isbackground = Trued;
T.Start ();
// the monitor () Method Looks Like this:
Void Monitor ()
{
Mre.waitone ();
Application.exit ();
}
If the program has a form, another method is to tell other windows to close this new program instance. If this is a Win32 application, this program can simply call FindWindowSex () and passed into a specific window class parameter, and then send a WM_CLOSE message. But you can't do this for Windows Form, because most forms (Forms) have the same class name, as I said in a newsletter. In the next newsletter, I will explain another way to solve such problems.