代码之家  ›  专栏  ›  技术社区  ›  Tono Nam

阻止运行Mono应用程序的多个实例

  •  0
  • Tono Nam  · 技术社区  · 5 年前

    我知道如何防止在Windows上运行给定应用程序的多个实例:

    Prevent multiple instances of a given app in .NET?

    但是,在使用mono开发的Linux下,此代码不起作用。它编译并运行,但不工作。在使用mono的Linux下,如何防止它?

    这是我尝试过的,但代码DEO不能在Linux下仅在Windows上工作。

        static void Main()
        {
            Task.Factory.StartNew(() =>
            {
                try
                {
                    var p = new NamedPipeServerStream("SomeGuid", PipeDirection.In, 1);
                    Console.WriteLine("Waiting for connection");
                    p.WaitForConnection();
                }
                catch
                {
                    Console.WriteLine("Error another insance already running");
                    Environment.Exit(1); // terminate application
                }
            });
            Thread.Sleep(1000);
    
    
            Console.WriteLine("Doing work");
            // Do work....
            Thread.Sleep(10000);            
        }
    
    1 回复  |  直到 5 年前
        1
  •  0
  •   Tono Nam    5 年前

    我想出了这个答案。调用此方法并传递唯一的ID

        public static void PreventMultipleInstance(string applicationId)
        {
            // Under Windows this is:
            //      C:\Users\SomeUser\AppData\Local\Temp\ 
            // Linux this is:
            //      /tmp/
            var temporaryDirectory = Path.GetTempPath();
    
            // Application ID (Make sure this guid is different accross your different applications!
            var applicationGuid = applicationId + ".process-lock";
    
            // file that will serve as our lock
            var fileFulePath = Path.Combine(temporaryDirectory, applicationGuid);
    
            try
            {
                // Prevents other processes from reading from or writing to this file
                var _InstanceLock = new FileStream(fileFulePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
                _InstanceLock.Lock(0, 0);
                MonoApp.Logger.LogToDisk(LogType.Notification, "04ZH-EQP0", "Aquired Lock", fileFulePath);
    
                // todo investigate why we need a reference to file stream. Without this GC releases the lock!
                System.Timers.Timer t = new System.Timers.Timer()
                {
                    Interval = 500000,
                    Enabled = true,
                };
                t.Elapsed += (a, b) =>
                {
                    try
                    {
                        _InstanceLock.Lock(0, 0);
                    }
                    catch
                    {
                        MonoApp.Logger.Log(LogType.Error, "AOI7-QMCT", "Unable to lock file");
                    }
                };
                t.Start();
    
            }
            catch
            {
                // Terminate application because another instance with this ID is running
                Environment.Exit(102534); 
            }
        }