因此,我能够在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
这一事实有关。如果这是问题,您是否需要在执行命令行之前传递一些值。
提前致谢,
答案 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?