Lucas Sosna
Lucas Sosna

Reputation: 63

C# only one instance of program - open few files

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.

Upvotes: 2

Views: 419

Answers (2)

Lucas Sosna
Lucas Sosna

Reputation: 63

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();
        }
    }
}

Upvotes: 1

Vivek Bernard
Vivek Bernard

Reputation: 2073

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
    }

Upvotes: 0

Related Questions