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.

7
  • question is hard to understand....static void main is already single instance Commented Sep 17, 2014 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. Commented Sep 17, 2014 at 18:51
  • @Tim It's not a console application - it shows windows based on args. Commented Sep 17, 2014 at 18:55
  • 2
    Read this and ditch your current code: hanselman.com/blog/… Commented Sep 17, 2014 at 19:01
  • 1
    This answer refers to the same approach: stackoverflow.com/a/19326/682404. Commented Sep 17, 2014 at 19:07

2 Answers 2

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();
        }
    }
}
Sign up to request clarification or add additional context in comments.

Comments

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
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.