3

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

4

6 回答 6

3

您可以创建一个非常非常小的控制文件,任何格式的文件,txt 或 XML 在此文件标志中添加

任何实例启动,如果标志为真,则退出应用程序,否则,将标志设置为真

并且在将标志设置为 true 的应用程序退出时,将标志恢复为 false

但这将锁定应用程序,以防锁定标志的应用程序正常关闭。

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


编辑:

使用文件来控制标志,当应用程序正常关闭时发出:

这可以TimeStamp与标志一起使用来修复,如果TimeStamp超过某个时间,这意味着没有人在使用应用程序,因此允许使用它,这涉及TimeStamp在应用程序运行时的每个时间段更新它,就像心跳一样

于 2013-06-12T04:26:09.917 回答
1

编辑:根据大众的需求,我会指出这个答案是为了回应提问者提到的互斥锁,所以我假设他/她想限制每台机器的用户数量。如果他/她想限制网络中的总使用量,那么这不是这样做的方法。

这是我目前正在使用的:

  // 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;
  }
于 2013-06-12T04:18:40.753 回答
1

如果您的操作系统和/或网络文件系统支持这一点,您可以在网络文件服务器上创建一个空文件(如果它尚不存在),并在应用程序启动时请求独占写入访问权限。

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

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

即使您的应用程序异常终止,操作系统也会清理进程并释放文件句柄,从而允许您的应用程序的另一个实例申请文件锁定。

(再次重申:这可能不适用于所有操作系统和网络文件服务器协议;我认为这应该适用于 Windows 网络和 Samba 文件服务器。)

于 2013-06-13T08:56:03.203 回答
0

好的,我会再试一次,现在已经提供了额外的信息。

我不确定这是否可行,但为什么不在服务器上有一个文件用作“一次一个锁定文件”。在程序开始时,打开此文件进行写入。如果它有效,那应该在它上面放置一个排他锁。如果它不起作用,则表明另一个程序当前打开了文件以进行写入,并且您说“对不起,程序当前正在另一台机器上运行”。如果它确实有效,那么只要程序正在运行,您就可以保持文件打开以进行写入。可能不需要显式关闭文件,这应该在程序终止或崩溃时自动发生。

于 2013-06-12T19:47:02.960 回答
0

如果您不想使用互斥锁,那么您可以编写应用程序代码来检查机器上的所有进程,如果已经找到相同的进程,则退出应用程序

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

但是这个解决方案有自己的缺点,因为你只用他的名字比较进程......

于 2013-06-12T05:10:17.947 回答
0

使用命名互斥体。这是正常的做法。从您的程序中创建一个命名互斥体(确保名称是唯一的)。构造函数将告诉您是创建了新的互斥体还是使用out bool createdNew参数打开了现有的互斥体。如果此标志为假,则该程序的一个实例已经在运行。

于 2013-06-12T04:07:49.263 回答