CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 13 of 13
  1. #1
    Join Date
    Oct 2009
    Posts
    1

    How to make a single instance application refresh with command line args

    Hi all,

    I'm using a named mutex to ensure that my C# Windows Forms Application is only running in a single instance, on Windows. The program I'm writing is an image viewing program, and it takes in the path to the image to display through command a command line argument.

    I'm needing to know the best way to have my original, first instance of the image viewer program load up any image path that is passed to a new instance of the program. I just want this to be a seamless process - "pass path to image to the image viewer app, if it isn't running then start a new process, if it's already running then use the running one to display the image".

    Right now I'm just killing the original process, and starting up a new one if there was one already running. This works, but it's not pretty. I'd like the one that is already running to just display the newly specified image.

    Any ideas? Thanks in advance.

  2. #2
    Join Date
    Mar 2004
    Location
    33°11'18.10"N 96°45'20.28"W
    Posts
    1,808

    Re: How to make a single instance application refresh with command line args

    heres an article I wrote on that (from my own site) http://sanity-free.org/143/csharp_do...plication.html

    here's one that has some other ideas on the matter (also references my article) http://www.codeproject.com/KB/cs/Sin...eAppMutex.aspx

    in theory you could send the command line in through the same message you post to the message queue, though I'd have to work out how to do that.

  3. #3
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: How to make a single instance application refresh with command line args

    You'll need to use some sort of interprocess communication for the 2nd instance to communicate with the 1st instance. Once the 2nd instance passes the new path data to the 1st instance, it will exit as it does now.

    One way to do this in C# is to use WCF and make a small WCF web service hosted by your process. When the 2nd instance starts up, it simply passes the path info to the web service (which runs in the context of the 1st instance). The 1st instance would just use this info to display the new image.

  4. #4
    Join Date
    Mar 2004
    Location
    33°11'18.10"N 96°45'20.28"W
    Posts
    1,808

    Re: How to make a single instance application refresh with command line args

    here's a sample I just whipped up that does it all (single instance, and passing command line args via a named pipe).

    http://sanity-free.org/misc/SingleInstanceApp.zip

  5. #5
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: How to make a single instance application refresh with command line args

    Here's a sample that passes the data using WCF.

    Code:
    namespace SingleInstanceWcf
    {
      #region Using Directives
     
      using System;
      using System.ServiceModel;
      using System.Threading;
     
      #endregion Using Directives
     
      // Declare a simple WCF service interface
      // to pass data between two instances of 
      // the same application
      [ServiceContract]
      publicinterfaceILauncher
      {
        [OperationContract]
        void OpenImage( string path );
      }
     
      publicclassLauncher : ILauncher
      {
        publicvoid OpenImage( string path )
        {
          Console.WriteLine ( String.Format ( "Image opened from 1st instance {0}", path ) );
        }
      }
     
      classProgram
      {
        staticvoid Main( string [ ] args )
        {
          bool newInstance = false;
          // Restrict the app to a single instance using a named mutex.
          Mutex singleMtx = newMutex ( true, "{8cdaba99-857c-44d7-bfc1-b66b347965c2}", out newInstance );
    
          // Check if we're the 2nd instance. If so, use the WCF service
          // to pass the path data to the 1st instance
          if ( !newInstance )
          {
            if ( args.Length == 0 )
            {
              Console.WriteLine ( "Error: 2nd instance must pass in image path as a cmd parameter" );
              return;
            }
     
            // Connect to the 1st instance using wcf and pass the image path
            using ( ChannelFactory<ILauncher> factory = newChannelFactory<ILauncher> ( "ILauncherServiceConfig" ) )
            {
              ILauncher channel = factory.CreateChannel ( );
              channel.OpenImage ( args [ 0 ] );
            }
     
            // Exit the app after passing the path data to the 1st instance
            return;
          }
     
          //
          // 1st instance code
          //
    
          // Host the WCF service
          ServiceHost host = newServiceHost ( typeof ( SingleInstanceWcf.Launcher ) );
    host.Open ( );
     
          // Wait for 60 seconds before exiting the app
          System.Threading.Thread.Sleep ( 60000 );
     
          // Shutdown the WCF Service
          host.Close ( );
        }
      }
    }

    Attached Files Attached Files

  6. #6
    Join Date
    May 2008
    Posts
    36

    Re: How to make a single instance application refresh with command line args

    Just throw a spanner in the works I dont think mutexs are a great way of implementing single instance application, I know they have failed for me once or twice on the rare occasion.
    I now create a file in some preset common location say (Application.CommonAppDataPath + "\lock.file") an test for a file lock on startup of each instance as for passing command line args there are a few ways least of all sending messages to the processes window this seems to work particularly well.

  7. #7
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: How to make a single instance application refresh with command line args

    A named mutex is the defacto way to limit an app to a single instance. How did it fail "in rare instances" for you? How did you code the mutex to check for the single instance?

  8. #8
    Join Date
    Mar 2004
    Location
    33°11'18.10"N 96°45'20.28"W
    Posts
    1,808

    Re: How to make a single instance application refresh with command line args

    using a semaphore file is definitely one way to produce the single instance application. I think it's less elegant (and far less useful) than using a mutex, but it does solve the denial of service issue that can occur with mutexes.

    unless you just didn't implement it right, mutexes will always work (that's their entire purpose in life is to work).
    Last edited by MadHatter; October 30th, 2009 at 03:38 PM.

  9. #9
    Join Date
    May 2008
    Posts
    36

    Re: How to make a single instance application refresh with command line args

    Fair enough, I know vey little about mutexs except how to implement them in the simple circumstances (ie try to apply mutex,catch an error => another instance is running) so its more likely there was an error in the code.
    One of the times I remember it failing was when the same app was run from two diffrent users, Im guessing mutexs aren't desinged to work across users.

    Usually I use single instances because I dont want data saved on the disk to be corrupted, so the filelock approch will only fail if each instance is looking at a different directory but if thats the case the data isnt shared so it cant be corrputed.

  10. #10
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: How to make a single instance application refresh with command line args

    Quote Originally Posted by gleesonger View Post
    Im guessing mutexs aren't desinged to work across users..
    This isn't correct. Read up on named mutexes and Kernel object namespaces (see the global prefix).

  11. #11
    Join Date
    May 2007
    Posts
    1,546

    Re: How to make a single instance application refresh with command line args

    So what happens if your app crashes the the file isn't deleted? Suddenly the app can't be started up anymore. At least with the mutex approach this can be detected.
    www.monotorrent.com For all your .NET bittorrent needs

    NOTE: My code snippets are just snippets. They demonstrate an idea which can be adapted by you to solve your problem. They are not 100% complete and fully functional solutions equipped with error handling.

  12. #12
    Join Date
    May 2008
    Posts
    36

    Re: How to make a single instance application refresh with command line args

    Quote Originally Posted by Mutant_Fruit View Post
    So what happens if your app crashes the the file isn't deleted?
    No you maintain a file lock, the mere existence of the file doesn't indicate anything, only the failure to obtain the lock indicates a second instance of the application.
    I think firefox uses this method:
    "%appdata%\Roaming\Mozilla\Firefox\Profiles\%profile%\.parentlock"
    This approach as yet to fail for me, and I find it simple to understand and implement.

  13. #13
    Join Date
    Mar 2004
    Location
    33°11'18.10"N 96°45'20.28"W
    Posts
    1,808

    Re: How to make a single instance application refresh with command line args

    I'm pretty sure the reason moz uses this is because they're platform independent, so they have to utilize a common SI methodology to be consistent across the realm.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured