Application Architecture in Windows Forms 2.0—Single-Instance Detection and Management
| CSharp-Online.NET:Articles |
| C# Articles |
|
© 2006 Pearson Education, Inc. |
Single-Instance Detection and Management
You could build a custom single-instance application using custom code that incorporates threading and .NET remoting. However, the VB.NET runtime library, Microsoft. VisualBasic.dll, contains a class that provides such an implementation for you: WindowsFormsApplicationBase, located in the Microsoft.VisualBasic.ApplicationServices namespace. WindowsFormsApplicationBase does not inherit from the Application class in System.Windows.Forms, but WindowsFormsApplicationBase is designed to replace the use of the Application class to run and manage an application’s lifetime, as you’ll see shortly.
If you are using C#, you add a reference to this assembly by right-clicking the project and selecting Add Reference from the context menu. From the .NET tab of the subsequently loaded Add Reference dialog, select Microsoft.VisualBasic.dll. When this DLL is referenced, you derive from WindowsFormsApplicationBase before extending your custom class with support for single-instance applications and passing command line arguments:
// SingleInstanceApplication.cs using Microsoft.VisualBasic.ApplicationServices; ... class SingleInstanceApplication : WindowsFormsApplicationBase {...}
Next, you configure SingleInstanceApplication to support single-instance applications. Set the SingleInstanceApplication class’s IsSingleInstance property (implemented by the base WindowsFormsApplicationBase class) to true:
// SingleInstanceApplication.cs class SingleInstanceApplication : WindowsFormsApplicationBase { // Must call base constructor to ensure correct initial // WindowsFormsApplicationBase configuration public SingleInstanceApplication() { // This ensures the underlying single-SDI framework is employed, // and OnStartupNextInstance is fired this.IsSingleInstance = true; } }
IsSingleInstance is false by default, and the constructor is a great place to change this situation. To incorporate this into your application, replace the standard application start-up logic from your application’s entry point. Then, use the following code to create an instance of your custom WindowsFormsApplicationBase type:
// Program.cs static class Program { [STAThread] static void Main(string[] args) { Application.EnableVisualStyles(); SingleInstanceApplication application = new SingleInstanceApplication(); application.Run(args); } }
WindowsFormsApplicationBase exposes the Run method—the Application.Run method analog—which you invoke to open the main application form. Additionally, WindowsFormsApplicationBase.Run expects a string array containing command line arguments; passing null causes an exception to be thrown.
To specify which form is the main application form, you override WindowsFormsApplicationBase.OnCreateMainForm and set WindowsFormsApplicationBase.MainForm appropriately:
// SingleInstanceApplication.cs class SingleInstanceApplication : WindowsFormsApplicationBase { ... protected override void OnCreateMainForm() { this.MainForm = new MainForm(); } }
As a final flourish, you can expose your custom WindowsFormsApplicationBase type via a static instantiation-helper method and thereby cut down on client code:
// SingleInstanceApplication.cs class SingleInstanceApplication : WindowsFormsApplicationBase { static SingleInstanceApplication application; internal static SingleInstanceApplication Application { get { if( application == null ) { application = new SingleInstanceApplication(); } return application; } } ... } // Program.cs static class Program { ... [STAThread] static void Main(string[] args) { Application.EnableVisualStyles(); SingleInstanceApplication.Application.Run(args); } }
The effect of SingleInstanceApplication is to restrict an application to only one instance, no matter how many times it is executed. This single-instance scheme works fine as is, but it works better when the first instance of the application has a need to get command line arguments from any subsequent instances. Multiple-SDI and single-MDI applications are examples of applications that use this kind of processing.
|

