2

I did everything from Example: What is the correct way to create a single-instance application? by Matt Davis.

However, I have an application to open files. I have this code:

    static Mutex mutex = new Mutex(true, "{MyApplicationTest}");
    [STAThread]
    static void Main(string[] args)
    {
        if (mutex.WaitOne(TimeSpan.Zero, true))
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(args.Length == 0 ? new Form1(string.Empty) : new Form1(args[0]));
            mutex.ReleaseMutex();
        }
        else
        {
            NativeMethods.PostMessage(
            (IntPtr)NativeMethods.HWND_BROADCAST,
            NativeMethods.WM_SHOWME,
            IntPtr.Zero,
            IntPtr.Zero);
        }

How does open the next file in the case when the program is already running. The first file automatically opens. In contrast, the next click will only appearance of the application window on top of the screen.

Community
  • 1
  • 1
  • question is hard to understand....static void main is already single instance – Steve Sep 17 '14 at 18:48
  • You mention click and window application, but the code you posted is a console app. Agree with @Steve - your question is not understandable as written. – Tim Sep 17 '14 at 18:51
  • @Tim It's not a console application - it shows windows based on `args`. – xxbbcc Sep 17 '14 at 18:55
  • 2
    Read this and ditch your current code: http://www.hanselman.com/blog/TheWeeklySourceCode31SingleInstanceWinFormsAndMicrosoftVisualBasicdll.aspx – xxbbcc Sep 17 '14 at 19:01
  • 1
    This answer refers to the same approach: http://stackoverflow.com/a/19326/682404. – xxbbcc Sep 17 '14 at 19:07
  • Main only runs when the program first starts running. I don't see any sort of loop to handle multiple arguments. Is that what you intended? – KC-NH Sep 17 '14 at 19:19
  • Problem solved, thanks xxbbcc - http://www.hanselman.com/blog/TheWeeklySourceCode31SingleInstanceWinFormsAndMicrosoftVisualBasicdll.aspx – Lucas Sosna Sep 18 '14 at 18:11

2 Answers2

1

Problem solved, thanks xxbbcc http://www.hanselman.com/blog/TheWeeklySourceCode31SingleInstanceWinFormsAndMicrosoftVisualBasicdll.aspx

using System;
using System.Windows.Forms;
using Microsoft.VisualBasic.ApplicationServices;

namespace SuperSingleInstance
{
    static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            string[] args = Environment.GetCommandLineArgs();
            SingleInstanceController controller = new SingleInstanceController();
            controller.Run(args);
        }
    }

    public class SingleInstanceController : WindowsFormsApplicationBase
    {
        public SingleInstanceController()
        {
            IsSingleInstance = true;

            StartupNextInstance += this_StartupNextInstance;
        }

        void this_StartupNextInstance(object sender, StartupNextInstanceEventArgs e)
        {
            Form1 form = MainForm as Form1; //My derived form type
            form.LoadFile(e.CommandLine[1]);
        }

        protected override void OnCreateMainForm()
        {
            MainForm = new Form1();
        }
    }
}
0

Here is a Utility Class That I wrote a while back for a similar purpose. (I guess the name GlobalMutexHelper is kind of redundant in this case, the name kind of stuck :)..anyways)

Since it implements IDisposable you can use it like so

using(var Mutexhelper=new GlobalMutexHelper("reasonably unique Name"))
{

 //Code goes here

}

Its not necessary that this be implemented as an IDisposable but in my case I need it to be handy as sometimes the "Single Instanceness" had to be dependent on other factors.

 internal class GlobalMutexHelper : IDisposable
        {
        #region Constants and Fields

        /// <summary>
        /// The access rule.
        /// </summary>
        private readonly MutexAccessRule accessRule =
            new MutexAccessRule(
                new SecurityIdentifier(WellKnownSidType.WorldSid, null), 
                MutexRights.FullControl, 
                AccessControlType.Allow);

        /// <summary>
        /// The obj.
        /// </summary>
        private readonly Mutex obj;

        /// <summary>
        /// The sec settings.
        /// </summary>
        private readonly MutexSecurity secSettings = new MutexSecurity();

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="GlobalMutexHelper"/> class.
        /// </summary>
        /// <param name="mutexname">
        /// The mutexname.
        /// </param>
        /// <exception cref="TimeoutException">
        /// </exception>
        /// <exception cref="Exception">
        /// </exception>
        public GlobalMutexHelper(string mutexname)
        {
            if (mutexname.Trim() != string.Empty)
            {
                this.secSettings.AddAccessRule(this.accessRule);
                bool isNew;
                this.obj = new Mutex(true, "Global\\SomeUniqueName_" + mutexname, out isNew);
                this.obj.SetAccessControl(this.secSettings);
                if (!isNew)
                {
                    if (this.obj.WaitOne())
                    {
                        Console.WriteLine("Signalled");
                    }
                    else
                    {
                        throw new TimeoutException("Timedout while waiting for Mutex");
                    }
                }
            }
            else
            {
                throw new Exception("The mutex name cannot be empty");
            }
        }

        #endregion


        #region Public Methods and Operators

        /// <summary>
        /// The dispose.
        /// </summary>
        public void Dispose()
        {
            this.obj.ReleaseMutex();
            this.obj.Dispose();
        }

        #endregion
    }
Vivek Bernard
  • 2,063
  • 3
  • 26
  • 43