Tech Off Thread

32 posts

Forum Read Only

This forum has been made read only by the site admins. No new threads or comments can be added.

Single instance application

Back to Forum: Tech Off
  • User profile image
    mot256

    I need to know how you guys prevent another instance of the same application to startup in C#? Without using a mutex…

    I know VB (at least VB.NET) has a nice event you can hook into. Not that I’m a fan of VB, except for this event and the easy way you can display a splash screen… 

    Is there not some collection, list or method I can look into?

    I currently use a mutex, but this is way to much code for the simple task that it must do…

  • User profile image
    Yggdrasil

    mot256 wrote:
    I need to know how you guys prevent another instance of the same application to startup in C#? Without using a mutex…

    I know VB (at least VB.NET) has a nice event you can hook into. Not that I’m a fan of VB, except for this event and the easy way you can display a splash screen… 

    Is there not some collection, list or method I can look into?

    I currently use a mutex, but this is way to much code for the simple task that it must do…



    I think Mutexes are good solution - how is it too much code when you can create and check a mutex with one line of code each?
    Another common method is to lock a handle to a file or just create some sort of semaphore file to say you're online.


    As always, Raymond Chen has some thoughts on this:
    A single-instance program is its own denial of service

  • User profile image
    PerfectPhase

    Why not just check the process list for the app? 

  • User profile image
    mot256

    PerfectPhase wrote:
    Why not just check the process list for the app? 

    I'll love to know how?

  • User profile image
    mot256

    Yggdrasil wrote:
    
    I think Mutexes are good solution - how is it too much code when you can create and check a mutex with one line of code each?

    I got some examples from the net. How would you do it?

    Yggdrasil wrote:
    
    Another common method is to lock a handle to a file or just create some sort of semaphore file to say you're online.

    Nah... thought of it though...

    Yggdrasil wrote:
    
    As always, Raymond Chen has some thoughts on this:
    A single-instance program is its own denial of service

    Interesting... but not a problem for me right now...

  • User profile image
    PerfectPhase

    mot256 wrote:
    
    PerfectPhase wrote: Why not just check the process list for the app? 

    I'll love to know how?


    http://msdn2.microsoft.com/en-us/library/system.diagnostics.process.getprocessesbyname.aspx

  • User profile image
    mot256

    PerfectPhase wrote:
    
    mot256 wrote:
    PerfectPhase wrote: Why not just check the process list for the app? 

    I'll love to know how?


    http://msdn2.microsoft.com/en-us/library/system.diagnostics.process.getprocessesbyname.aspx


    This will not work. Nothing prevents the user from renaming the EXE. And another thing is that the process name has ".vshost" appended to it if you run it from the IDE (thus running the same EXE from Windows Explorer, the name will not match).

  • User profile image
    figuerres

    mot256 wrote:
    I need to know how you guys prevent another instance of the same application to startup in C#? Without using a mutex…

    I know VB (at least VB.NET) has a nice event you can hook into. Not that I’m a fan of VB, except for this event and the easy way you can display a splash screen… 

    Is there not some collection, list or method I can look into?

    I currently use a mutex, but this is way to much code for the simple task that it must do…




    simple;  hijacck the VB library that does the work!

    details to follow .... just a minute....

  • User profile image
    figuerres

    snips from an app I have: ==============================
    using Microsoft.VisualBasic.ApplicationServices;
    /// /// The main entry point for the application. ///
    [STAThread]
    static void Main() {
    // Unhandled exceptions will be delivered to our ThreadException handler
    Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(AppThreadException);
    // ensure only a single instance of this app runs. SingleInstanceApplication app = new SingleInstanceApplication(); app.StartupNextInstance += new StartupNextInstanceEventHandler(OnAppStartupNextInstance); }
    /// /// Event handler for processing when the another application instance tries
    /// to startup. Bring the previous instance of the app to the front and /// process any command-line that's needed.
    /// /// Object sending this message.
    /// Event argument for this message. static void OnAppStartupNextInstance(object sender, StartupNextInstanceEventArgs e)
    {
    // if the window is currently minimized, then restore it.
    if (mainForm.WindowState == FormWindowState.Minimized) {
     mainForm.WindowState = FormWindowState.Maximized;
    }
     // activate the current instance of the app, so that it's shown. mainForm.Activate();
    }
     private static void AppThreadException(object source, System.Threading.ThreadExceptionEventArgs e)
    {
    // An unhandled exception occured somewhere in our application. Let
    // the 'Global Policy' handler have a try at handling it.
    try {
    ExitFlag = true;
    new .LogError().LogIt(e.Exception);
    new .LogError().EmailIt(e.Exception);
    ApplicationExceptionForm AEF = new ApplicationExceptionForm(); AEF.Ex = e.Exception; AEF.LogPath =Application.CommonAppDataPath +"\\" + Properties.Settings.Default.LogFileName; AEF.ShowDialog();
     // Something has gone very wrong - exit the application. Application.Exit();
    } catch (Exception ex)
    { new .LogError().LogIt(ex);
    // Something has gone wrong during HandleException (e.g. incorrect configuration of the block).
    // Exit the application
    string errorMsg = "An unexpected exception occured while calling HandleException. ";
    errorMsg += "Please check the event log for details about the exception." + Environment.NewLine + Environment.NewLine; MessageBox.Show(errorMsg, "Application Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
    Application.Exit();
    } }

  • User profile image
    figuerres

    wow is that ugly!

    the fancy code  paste was worse, it had extra lines in the edit window.... yow!

    ok so you use the vb lib and use it's methods and setup a handler.

    in the handler do what you need to do.


    you also see there how I add a global error trap to log fatal errors and email them back to me.

    it's a corp. type app so they know I get that data etc....

    no secret stuff etc... in that part.

    so far this seems to work very well in the app I am using it in.

  • User profile image
    mot256

    figuerres wrote:
    
    using Microsoft.VisualBasic.ApplicationServices;

    The assembly (microsoft.visualbasic.dll) where this namespace resides, does it get installed with .NET FW 2? Or with VS?


  • User profile image
    Sven Groot

    mot256 wrote:
    
    figuerres wrote: 
    using Microsoft.VisualBasic.ApplicationServices;

    The assembly (microsoft.visualbasic.dll) where this namespace resides, does it get installed with .NET FW 2? Or with VS?



    It's part of the core .Net Framework, no need to worry.

  • User profile image
    mot256

    Sven Groot wrote:
    
    mot256 wrote:
    figuerres wrote: 
    using Microsoft.VisualBasic.ApplicationServices;

    The assembly (microsoft.visualbasic.dll) where this namespace resides, does it get installed with .NET FW 2? Or with VS?



    It's part of the core .Net Framework, no need to worry.


    Thanx guys! This will work then!

  • User profile image
    mot256

    mot256 wrote:
    
    Thanx guys! This will work then!

    I guess not... the SingleInstanceApplication class does not seem to be part of the Microsoft.VisualBasic.ApplicationServices namespace... well not in .NET 2 anyway... Sad

  • User profile image
    mot256

    Anyway, mixing VB and C# is like mixing CLX and VCL in the same app in Delphi... not good!

  • User profile image
    Sven Groot

    mot256 wrote:
    
    mot256 wrote: 
    Thanx guys! This will work then!


    I guess not... the SingleInstanceApplication class does not seem to be part of the Microsoft.VisualBasic.ApplicationServices namespace... well not in .NET 2 anyway...


    That's because you have to create it yourself. Here's a more complete example:

    using Microsoft.VisualBasic.ApplicationServices;

    class SingleInstanceApplication : WindowsFormsApplicationBase
    {
       public SingleInstanceApplication()
       {
          IsSingleInstance = true;
          MainForm = new Form1();
          EnableVisualStyles = true;
          Startup += new StartupEventHandler(SingleInstanceApplication_Startup);
          StartupNextInstance += new StartupNextInstanceEventHandler(SingleInstanceApplication_StartupNextInstance);
       }

       void SingleInstanceApplication_StartupNextInstance(object sender, StartupNextInstanceEventArgs e)
       {
          MessageBox.Show("Second instance.");
       }
       
       void SingleInstanceApplication_Startup(object sender, StartupEventArgs e)
       {
          MessageBox.Show("First instance.");
       }

       [STAThread]
       static void Main(string[] args)
       {
          Application.SetCompatibleTextRenderingDefault(false);
          SingleInstanceApplication app = new SingleInstanceApplication();
          app.Run(args);
       }
    }

    I don't think this is really "mixing VB and C#" since you're only using a VB library, not any VB code.

  • User profile image
    Ion Todirel

    mot256 wrote:
    Anyway, mixing VB and C# is like mixing CLX and VCL in the same app in Delphi... not good!
    what you could do is this and for
    mot256 wrote:
    This will not work. Nothing prevents the user from renaming the EXE.
    that you could use FileSystemWatcher (and a anonymous delegate for Renamed event) to watch if someone will change filename of the executable, i don't know how much overhead this will make?, so may be stupid. And put all code in a "public static bool IsSingleInstance { get { ... } }" property, that would be nice, minimal changes...

  • User profile image
    littleguru

    Interesting. I did that today. I used a Mutex and used FindWindow and ShowWindow (p/invoke) to bring the other app in front... A mutex so easy to use and works great.

    The classes here are great. I remember that you could set a "property" in VB6 to avoid multiple startups of an app.

Conversation locked

This conversation has been locked by the site admins. No new comments can be made.