6

I'm trying to make a single instance WPF application using the hints on:

What is the correct way to create a single-instance application?

This ultimately requires changes to Main(). In WPF, Main() seems to be auto-generated. I'd rather not modify autogenerated code. Is there a way to suppress Main from being auto-generated?

(alternatively, if you know of a better single app instance pattern for WPF that doesn't rely on modifying auto-generated code, please suggest it)

Community
  • 1
  • 1
jglouie
  • 11,987
  • 6
  • 45
  • 64

4 Answers4

11

From the blog: http://bengribaudo.com/blog/2010/08/26/136/wpf-where-is-your-static-main-method

The following two methods will avoid the duplicate Main collision:

  1. Tell the compiler that your static Main() method should be the execution entry point—Set your project’s “Startup object” setting to the class containing your static Main() method (right-click on the project in Solution Explorer, choose “Properties,” then look for the “Startup object” setting under the “Application” tab). (This was also mentioned by Bahri Gungor)

  2. Turn off auto-generation of App.g.cs’s static Main() method—In Solution Explorer, right click on App.xaml, choose “Properties,” then change the “Build Action” from “ApplicationDefinition” to “Page”.

jglouie
  • 11,987
  • 6
  • 45
  • 64
4

Actually, in a default WPF project, the application startup object is the App class (code-behind for app.xaml).

You can write your own class, create the startup code however you like, and start your application like this:

public class Startup
{
    [STAThread]
    public static void Main(string[] args)
    {
        // Check for existing instance (mutex or w/e) here

        //
        App app = new App();
        app.Run();
    }
}

You can change the startup object in your project file.

Bahri Gungor
  • 2,289
  • 15
  • 16
  • Where in the project file is this? – jglouie Feb 29 '12 at 19:07
  • Found it... it's set to (not set) which I guess defaults to App class? – jglouie Feb 29 '12 at 19:09
  • On the Application Tab (C#), Startup Object. – Bahri Gungor Feb 29 '12 at 19:09
  • Yes, the default for a WPF project is the App class. – Bahri Gungor Feb 29 '12 at 19:10
  • @LemonBeagle Using OnStartup event handler in the App class means the WPF application startup code is already running. Many of these answers have you put the code in that event handler and then kill the application, rather than making the check before the App is instantiated, as I suggest. I prefer the cleaner structured approach. – Bahri Gungor Feb 29 '12 at 19:18
  • +1 for this approach @BahriGungor. I found a blog with that and another method of preventing the Main collision. – jglouie Feb 29 '12 at 19:25
1

I wouldn't use the mutex approach for creating a single instance WPF app. I would use the answer described here - https://stackoverflow.com/a/19326/248164.

This is also the approach described in Pro WPF in C# 2010.

Community
  • 1
  • 1
devdigital
  • 33,892
  • 9
  • 95
  • 119
  • Yikes- this relies on the VB assembly?? – jglouie Feb 29 '12 at 19:18
  • Yes, not a huge issue, just one extra dependency to deploy with your app. – devdigital Feb 29 '12 at 19:19
  • Don't be confused by the `Microsoft.VisualBasic`. That isn't part of the VB runtime, but is rather a part of the .net runtime. See http://stackoverflow.com/questions/226517/is-the-microsoft-visualbasic-namespace-true-net-code – N_A Feb 29 '12 at 19:24
  • I'll spend more time explaining its inclusion during code reviews than it's worth in benefits. I do appreciate the alternate suggestion though – jglouie Feb 29 '12 at 19:27
0

I don't knowif it is your question, but I create the mutex in OnStartup. I dont touch the Main().

protected override void OnStartup(StartupEventArgs e) {            
        base.OnStartup(e);            
        m_singleInstanceMutex = new Mutex(false, SINGLE_INSTANCE_MUTEX_ID);
        ...

Important is, that you delete your StartupUri in the XAML-Declarion of your App.xaml. This prevents the runtime to automatically open the specified resource.

HCL
  • 35,003
  • 26
  • 158
  • 207
  • This is an interesting approach. Do you need to check if you can acquire the mutex prior to calling the base.OnStartup(e)? – jglouie Feb 29 '12 at 19:04