C#只有一个程序实例 - 打开几个文件

时间:2014-09-17 18:45:49

标签: c# file instance

我做了Matt Davis的示例:What is the correct way to create a single-instance application?

但是,我有一个打开文件的应用程序。我有这段代码:

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

在程序运行时如何打开下一个文件。第一个文件自动打开。相反,下一次单击只会在屏幕顶部显示应用程序窗口。

2 个答案:

答案 0 :(得分:1)

问题解决了,谢谢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();
        }
    }
}

答案 1 :(得分:0)

这是一个实用类,我为了类似的目的而写了一段时间。 (我猜GlobalMutexHelper的名字在这种情况下是多余的,名字有点卡住:) ..反正)

由于它实现了IDisposable,你可以像这样使用它

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

 //Code goes here

}

没有必要将它作为IDisposable实现,但在我的情况下,我需要它是方便的 有时“单一实例”必须依赖于其他因素。

 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
    }