如何在mono下强制执行应用程序的单个实例?

时间:2012-11-06 15:14:27

标签: mono delphi-prism single-instance oxygene

因此,我能够在Windows上强制执行我的应用程序的单个实例,如下所示。

[STAThread]
class method Program.Main(args: array of string);
begin
  var mutex := new Mutex(true, "{8F6F0AC4-B9A1-45fd-A8CF-72F04E6BDE8F}");
  if mutex.WaitOne(Timespan.Zero, true) then
  begin
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.ThreadException += OnThreadException;
    lMainForm := new MainForm;
    lMainForm.ShowInTaskbar := true;
    lMainForm.Visible := false;

    Application.Run(lMainForm);
  end
  else
    MessageBox.Show("Another copy running!!!");
end;

但是,在Linux下运行相同的应用程序,这个代码根本不起作用。我能够运行多个副本。我不知道是否与我在终端上启动应用程序mono MyPro.exe这一事实有关。如果这是问题,您是否需要在执行命令行之前传递一些值。

提前致谢,

3 个答案:

答案 0 :(得分:3)

您可能需要使用MONO_ENABLE_SHM环境变量启用共享句柄:

MONO_ENABLE_SHM=1 mono MyPro.exe

答案 1 :(得分:3)

你需要像Adrian Faciu所提到的那样在单声道中启用共享内存以使你的方法工作,但这不是最好的方法(首先它是默认禁用的原因,即使我现在不记得了确切原因)。

我过去曾使用过两种解决方案:

  • 基于文件的锁定。创建一个已知文件,将pid写入该文件。在应用程序启动时检查文件是否存在,如果存在,请阅读pid并检查是否有任何正在运行的进程与该pid(以便它可以从崩溃中恢复)。并在退出时删除该文件(在首先创建它的实例中)。缺点是如果几个实例几乎同时启动,则启动时会出现竞争条件。您可以通过文件锁定来改进这一点,但是您可能必须使用P / Invokes在Linux上执行正确的文件锁定(我不完全确定托管API会执行您期望的操作)。

  • 基于袜子的锁。打开一个已知端口。优于上述的优点是您不需要进行任何清理,也没有竞争条件。缺点是您需要一个固定/已知端口,而其他一些程序可能会同时使用该确切端口。

答案 2 :(得分:1)

Adrian的解决方案适合我(tm)。 狂野猜测:您是否需要两次调用中的MONO_ENABLE_SHM?