0

这是我阅读的文章http://kristofverbiest.blogspot.com/2008/11/creating-single-instance-application.html,按照文章的步骤,我有以下代码,我几乎可以肯定它可以'不起作用,它不能:

static class Program
{
    static Mutex mutex;
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        bool alreadyRun;
        mutex = new Mutex(false, Guid.NewGuid().ToString().Replace("-", ""), out alreadyRun);
        if (!alreadyRun) return;                            
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());            
    }
}

文章说传入的 Mutex 名称可以是随机的,MyAppName 只是为了方便调试(所以我把它省略了),'Local//' 也被省略了。我想知道它是如何工作的?alreadyRun只要随机 GUID 字符串是唯一的(我的意思是之前没有创建任何具有该名称的互斥体),该构造函数就会成功并变为真。alreadyRun这意味着,成为虚假的可能性很小。事实上,我已经多次尝试上面的代码,并且我可以根据自己的喜好运行我的应用程序的许多实例。

在为 mutex name 尝试了一个像“unique”这样的固定字符串之后,它就可以工作了。但是,如果有其他应用程序创建另一个同名的互斥锁,这将不起作用。我现在最终得到了这个解决方案:

  • 我们不能使用随机字符串,我们必须使用固定字符串,而且这个字符串应该又长又复杂,就像你的密码,你的 id 确保任何其他应用程序使用相同名称的机会很小。这是一个我肯定会说的例子,任何其他人(甚至是机器)几乎没有机会想到:ilove.netilovejava1234forever56789thismyid_itisevenlongerlongerlonger_howlongcanitbe_maybe8000characters?_canitbeso?

请解释一下这篇文章(看起来像是来自专业博主),并给我使用 Mutex 的任何其他解决方案(我已经厌倦了 using GetProcessesByName,到目前为止它并不好)。谢谢!

4

2 回答 2

0

阅读您发送的文章,您没有正确遵循它:

“互斥锁的名称应包含 GUID,以确保没有其他应用程序使用相同的名称。如果您不知道如何创建 GUID,请单击此处。”

不是每个实例的新 GUID。一旦使字符串唯一,就创建一个 GUID。

你可以使用类似的东西

static class Program
{
    static Mutex mutex;

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        var guid = ((System.Runtime.InteropServices.GuidAttribute)(System.Reflection.Assembly.GetEntryAssembly().GetCustomAttributes(typeof(System.Runtime.InteropServices.GuidAttribute), false).Single())).Value;

        bool alreadyRun;
        mutex = new Mutex(false, "App_Name" + guid.ToString(), out alreadyRun);
        if (!alreadyRun) return;        
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());        }
}

然后,如果您希望同时运行另一个版本的应用程序,只需给它一个新的 GUID。如果需要,您可以根据文章为 Local\ 添加前缀。

这是一张图片在此处输入图像描述

于 2013-05-21T12:24:18.057 回答
0

创建互斥体不需要名称,但如果您打算跨进程边界使用它,则应该有一个名称,例如,表明应用程序的一个实例已经在运行。

在您的代码中,每次应用程序启动时您都会创建一个不同的名称。此名称不会与任何其他互斥锁的名称匹配,因此代码将通过。

尝试将名称设置为不同但明确的名称。

这个 MSDN 页面上的注释很好地解释了事情。

于 2013-05-21T12:30:12.940 回答