Single-Instance Applications and C#

In response to a question about C# and single-instance apps I thought I'd show how to create a single-instance app in C# using the VB app model class. The VB app model class does the heavy lifting for a number of things, including single-instance behavior. The model was designed by the VB team and consequently has the VB customer primarily in mind. So the VB project designer does a lot of the leg work for you if you are building a VB windows forms app and makes it easy to configure, handle the app model events, etc. C# doesn't natively support the application model but that doesn't mean you can't use C# to enjoy the benefits--it just means you have to do a bunch of stuff manually. Here's a bare bones single-instance C# application. I started with a new C# Windows forms app and replaced the contents of program.cs with the following (note that you'll also need a reference to Microsoft.VisualBasic.dll):

using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace WindowsApplication1
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] commandLine)
{
Application.SetCompatibleTextRenderingDefault(false);
App myApp = new App();
myApp.Run(commandLine);
}
}

    /// <summary>
/// We inherit from WindowsFormApplicationBase which contains the logic for the application model, including
/// the single-instance functionality.
/// </summary>
class App : Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase
{
public App()
{
this.IsSingleInstance = true; // makes this a single-instance app
this.EnableVisualStyles = true; // C# windowsForms apps typically turn this on. We'll do the same thing here.
this.ShutdownStyle = Microsoft.VisualBasic.ApplicationServices.ShutdownMode.AfterMainFormCloses; // the vb app model supports two different shutdown styles. We'll use this one for the sample.
}

        /// <summary>
/// This is how the application model learns what the main form is
/// </summary>
protected override void OnCreateMainForm()
{
this.MainForm = new Form1();
}

        /// <summary>
/// Gets called when subsequent application launches occur. The subsequent app launch will result in this function getting called
/// and then the subsequent instances will just exit. You might use this method to open the requested doc, or whatever
/// </summary>
/// <param name="eventArgs"></param>
protected override void OnStartupNextInstance(Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventArgs eventArgs)
{
base.OnStartupNextInstance(eventArgs);
System.Windows.Forms.MessageBox.Show("An attempt to launch another instance of this app was made");
}
}
}

In the code sample above I could have handled the myApp.StartupNextInstance event instead of overriding OnStartupNextInstance(). No biggy either way, I just went for the easy override here. Whether you override or handle the event you'll get called on the main thread. If you do override OnStartupNextInstance() you'll want to defer to the base class as in addition to firing the StartupNextInstance event it also sets the focus to your original instance.

When you launch this app the first time you'll see Form1. If you launch it again while the first instance is running you'll see the message about a subsequent instance being launched as OnStartupNextInstance() gets called. The subsequent instance will just quietly exit while the original instance keeps running.

You can get a feel for other things you can do with the app model by looking at how VB configures it. Create a new VB windows app and go to the project designer via the solution explorer by double-clicking the "My Project" node. If you show all files in the solution explorer, you can also examine the Application.Designer.VB file which is under the My Project / Application.myapp node.

Legal blather: Use of included script samples are subject to the terms specified at https://www.microsoft.com/info/cpyright.htm