Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在mono下强制应用程序的单个实例?_Mono_Delphi Prism_Single Instance_Oxygene - Fatal编程技术网

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

如何在mono下强制应用程序的单个实例?,mono,delphi-prism,single-instance,oxygene,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.Enabl

因此,我能够在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下运行此代码根本不起作用。我可以运行多个副本。我不知道这是否与我在终端上像mono MyPro.exe一样启动应用程序有关。如果这是问题所在,那么在执行命令行之前是否需要传递一些值


提前感谢,

您可能需要使用MONO\u enable\u SHM环境变量启用共享句柄:

MONO_ENABLE_SHM=1 mono MyPro.exe

Adrian的解决方案适用于metm。
胡乱猜测:两次调用都需要MONO_ENABLE_SHM吗?

您需要在MONO中启用共享内存,正如Adrian Faciu所提到的,以使您的方法工作,但是这不是最好的方法。首先,默认情况下禁用MONO_ENABLE_SHM是有原因的,即使我现在不记得确切的原因

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

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

一种带锁的锁。打开一个已知的端口。与上述方法相比,它的优点是不需要进行任何清理,也不存在竞赛条件。缺点是您需要一个固定/已知的端口,而其他一些程序可能恰好同时使用该端口


阿德里安,我确实试过你的建议,但没用。正如我所说,我必须打开两个不同的终端才能启动我程序的两个不同副本。所以,也许这就是你的建议不起作用的原因。或者,考虑到unix的方式,也就是在一个公共的directoryloreb中有锁文件,如果所有其他方法都失败了,我不确定你是否在这两种调用中都需要锁文件,但无论如何我都尝试过这两种调用。不过,它还是不起作用。我甚至认为可能是因为它都是大写字母,而试着用所有小写字母。再一次,它没有起作用。我不知道这是否有助于进一步阐明这一问题,但我正试图在mono下的PCLinuxOS上这样做。@Earlz,正如论坛和在线留言板上的其他人所建议的那样,这就是我现在看到的。Debian x86_64这里fwiw,我的互斥体名为mymutex。@Earlz,如果我可以问你的话,您是如何在Linux上启动程序的?直接单击可执行文件本身或从终端启动。显然,我在终端上使用MONO_ENABLE_SHM选项,发现MONO正在识别它。因为当我拼错它时,mono认为它是无法识别的命令。如果是这样的话,那么为什么程序不能按预期运行呢。请给我一步一步的说明你是如何测试这个单声道选项的。谢谢。Rolf Bjarne Kvinge,我已经看过了基于文件的锁。然而,它有一个主要缺点。如果您在没有管理员权限(如删除文件)的用户帐户上运行程序,该怎么办?大多数情况下,您使用的是用户帐户,而不是管理员帐户。在实现了基于文件的锁之后,我遇到了这个问题。我的程序能够创建该文件,但在正常关闭时无法将其删除。@digitalanalog:如果您需要锁定以跨用户帐户,则需要将该文件放置在所有用户帐户都可以对C:\System\Temp进行读/写访问的某个位置,但可能还有其他/更好的位置。Rolf,也许有一种更直接的方法可以通过托管代码实现这一点,但到目前为止,我还没有发现它。所以,我发现基于文件的锁非常容易实现。我能够弄明白为什么它没有在我的Linux系统上删除该文件。现在,它的工作如预期。谢谢你的帮助。