2013-06-12 49 views
3

我有一个共享驱动器中的c#应用程序可执行文件。这允许有权访问共享驱动器的用户(3)打开可执行文件。现在要求不超过人可以同时运行可执行文件。我环顾四周,解决方案似乎是使用互斥,我不太明白。是否有任何其他解决方案/解决此问题的方法。防止应用程序的多个实例

+2

你是什么意思“比人不多”?一个在整个地球上/一个在本地网络/一个在单个机器上/一个在单一帐户上? –

+0

一个在本地网络上。 –

回答

0

使用命名的互斥体。这是做这件事的正常方法。从你的程序中创建一个有名的互斥体(确保这个名字是唯一的)。构造函数会告诉你新建互斥体是否已创建,或使用参数out bool createdNew打开了现有的互斥体。如果此标志为false,则该程序的一个实例已在运行。

1

编辑:应广大用户要求,我会指出,这答案是响应互斥的questionioner的提,所以我假设他/她想要限制每个机器的用户数。如果他/她想要限制网络中的总使用量,那么这不是做到这一点的方法。

这里就是我目前使用:

// Mutex object used to determine if there are multiple instances of this program running. 
    // Note that this is a reference to a .Net Mutex object, not the Windows mutex itself. 
    private static Mutex _onlyOneInstanceMutex; 



    /// <summary> 
    /// Method to test that there is not another instance of the program already running on this 
    /// machine, or at least in this Terminal Services session or Windows Vista/Windows 7 
    /// concurrent sessions session. If there is, a message box-style localized error message is 
    /// displayed and the value false is returned. This implies that this method should only be 
    /// used in WinForms programs. 
    /// 
    /// This implementation uses a .Net Mutex object in public storage to prevent it from being 
    /// garbage-collected. The name of the associated Windows mutex is simply the program name as 
    /// provided by the caller. Neither the .Net Mutex object nor the Windows mutex are ever 
    /// explicitly released; they remain in existence, perhaps in an "abandoned" state, until the 
    /// process that created them terminates. 
    /// </summary> 
    /// <returns>false if another instance running, otherwise true</returns> 
    [SuppressMessage("Microsoft.Reliability", "CA2004:RemoveCallsToGCKeepAlive", 
        Justification = "Not sure if this is correct or not.")] 
    public static bool TestOnlyOneInstance(string programName) 
    { 
    // Funny construct to prevent the Mutex from being garbage collected 
    GC.KeepAlive(_onlyOneInstanceMutex); 

    // Test if we are the first instance, and if so create the Windows mutex, making it 
    // impossible for subsequent instances to successfully create their mutex 
    bool firstInstance; 
    _onlyOneInstanceMutex = new Mutex(false, programName, out firstInstance); 
    if (firstInstance) 
     return true; 

    // Display a (possibly localized) error message, then return 
    string errorMessage = MLocalizer.GetString("Error1", 
      "Another instance of this program is already running on this machine.") + 
     "\n" + MLocalizer.GetString("Error2", 
            "You cannot run two instances at the same time.") + 
     "\n" + MLocalizer.GetString("Error3", "Please use the other instance."); 
    MessageBox.Show(errorMessage, programName, MessageBoxButtons.OK, MessageBoxIcon.Error); 
    return false; 
    } 
+0

防止在一台计算机上进行多个副本,而不在多台计算机上进行多个副本。 – Corey

+0

@Corey:是的,我知道。但问题不明确,提问者甚至提到了互斥。 – RenniePet

+1

@RenniePet - “这个答案的问题XXXXXX解释是否[不]覆盖YYYYY和ZZZZ解释:”如果你知道有很多方法来读取问题,请考虑增加。 –

3

您可以创建一个非常非常小的控制文件,一个文件,任何格式,TXT或XML 添加在这个文件中旗

任何实例开始时,如果标志为true,退出应用程序 否则,该标志设置为true

并在您的应用程序谁是标志设置为true的出口,恢复了标志设置为false

但是,这将在锁定的情况下的应用程序,谁锁定标志被关闭了,正常的应用程序。

所以最好的方法是使用互斥,或创建您的应用程序连接到一个共同的地方小型服务器应用程序,并在使用文件,设置标志以同样的方式使用它;这样,即使应用程序以非正常方式关闭,服务器也能够检测到该状态,并且仍然释放标志状态以允许其他实例启动。


编辑:

使用文件控制标志,问题,当应用程序关闭了 - 通常为:,

这可以使用TimeStamp旗一起被固定,如果TimeStamp是超过一定时间较旧的,这意味着没有一个被使用的应用程序,因此它被允许使用它,这涉及,而在应用程序运行,就像一个心跳更新此TimeStamp每个时间段

+0

其实,如果你有一个本地文件服务器和协议(如SMB)支持的话,你可以要求独占文件进行访问(即提上了文件锁)。即使操作系统终止应用程序“正常运行”,文件锁也应该被删除。所以这不是文件的存在或内容,而是重要的锁。 – stakx

+0

听起来不错,我不知道SMB(服务器消息块)协议之前和它的功能,如果它存在于我使用的环境中,并且我需要应用该问题的场景,当然我不会构建我的自己的锁。您的评论应该是其中一个答案顺便说一句@stakx – simsim

+0

完成。但我没有广泛测试这种情况。但是我记得,Microsoft Office使用文件锁定机制来防止多个用户同时编辑同一个文档,所以我相信它可以在Windows网络上完成。 – stakx

0

,如果你不想使用互斥,那么你可以在应用程序代码,检查机器上的所有进程,如果同样的过程中就已经发现了,然后退出应用程序

System.Diagnostic.Process.GetProcesses(); // get a array of processes 

但这种解决方案有自己的优缺点写,因为你只有他的名字比较过程...

0

OK,我会再次尝试,现在更多的咨询无论已提供。

我不知道,如果这是可行的,但为什么没有被作为一种“一次一个锁定文件”的服务器上的文件。在程序开始时,打开此文件进行写入。如果它有效的话,那就应该放置一个排它锁。如果它不起作用,则表明另一个程序当前有该文件可以写入,并且您说“对不起,程序正在另一台机器上运行”。如果它确实起作用,那么只要程序正在运行,您就可以保持文件的写入状态。可能没有必要明确关闭文件,这应该在程序结束时自动发生,或者崩溃。

1

如果你的操作系统和/或网络文件系统的支持这一点,你可以创建一个网络文件服务器上的一个空文件(如果不存在的话),并要求独占写访问时,您的应用程序开始。

如果您的应用程序没有被授予独占写访问,这意味着你的应用程序可能已经在其他地方的网络上运行。 (这里有一些误报的风险:也许有人只是出于好奇才在编辑器中打开文件,或者有人更改了文件的权限。)

当应用程序终止时,它应该关闭文件句柄,从而释放对文件的独占锁定。

即使你的应用程序异常终止,操作系统将清理过程,从而释放文件句柄,让您的应用程序要求的文件锁的另一个实例。

(还是那句话:这可能并不适用于所有的操作系​​统和网络文件服务器协议的工作;我认为这应该在Windows网络和Samba文件服务器工作。)

相关问题