代码之家  ›  专栏  ›  技术社区  ›  jinsungy

如何强制C#.net应用程序在Windows中仅运行一个实例?[副本]

  •  59
  • jinsungy  · 技术社区  · 16 年前

    可能重复:
    What is the correct way to create a single instance application?

    4 回复  |  直到 7 年前
        1
  •  109
  •   Mark Lakata    12 年前

    我更喜欢类似于下面的互斥解决方案。这样,如果应用程序已经加载,它就会重新关注它

    using System.Threading;
    
    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool SetForegroundWindow(IntPtr hWnd);
    
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
       bool createdNew = true;
       using (Mutex mutex = new Mutex(true, "MyApplicationName", out createdNew))
       {
          if (createdNew)
          {
             Application.EnableVisualStyles();
             Application.SetCompatibleTextRenderingDefault(false);
             Application.Run(new MainForm());
          }
          else
          {
             Process current = Process.GetCurrentProcess();
             foreach (Process process in Process.GetProcessesByName(current.ProcessName))
             {
                if (process.Id != current.Id)
                {
                   SetForegroundWindow(process.MainWindowHandle);
                   break;
                }
             }
          }
       }
    }
    
        2
  •  24
  •   Shadow Wizard    13 年前

    要强制在.net(C#)中只运行一个程序,请在程序.cs文件:

    public static Process PriorProcess()
        // Returns a System.Diagnostics.Process pointing to
        // a pre-existing process with the same name as the
        // current one, if any; or null if the current process
        // is unique.
        {
            Process curr = Process.GetCurrentProcess();
            Process[] procs = Process.GetProcessesByName(curr.ProcessName);
            foreach (Process p in procs)
            {
                if ((p.Id != curr.Id) &&
                    (p.MainModule.FileName == curr.MainModule.FileName))
                    return p;
            }
            return null;
        }
    

    [STAThread]
        static void Main()
        {
            if (PriorProcess() != null)
            {
    
                MessageBox.Show("Another instance of the app is already running.");
                return;
            }
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form());
        }
    
        3
  •  9
  •   Martin Plante    16 年前

    这是我在申请中使用的:

    static void Main()
    {
      bool mutexCreated = false;
      System.Threading.Mutex mutex = new System.Threading.Mutex( true, @"Local\slimCODE.slimKEYS.exe", out mutexCreated );
    
      if( !mutexCreated )
      {
        if( MessageBox.Show(
          "slimKEYS is already running. Hotkeys cannot be shared between different instances. Are you sure you wish to run this second instance?",
          "slimKEYS already running",
          MessageBoxButtons.YesNo,
          MessageBoxIcon.Question ) != DialogResult.Yes )
        {
          mutex.Close();
          return;
        }
      }
    
      // The usual stuff with Application.Run()
    
      mutex.Close();
    }
    
        4
  •  2
  •   Thyrador    12 年前

    在搞乱互斥之后(没有按我所希望的那样工作),我让它按如下方式工作:

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool SetForegroundWindow(IntPtr hWnd);
    
        public Main()
        {
            InitializeComponent();
    
            Process current = Process.GetCurrentProcess();
            string currentmd5 = md5hash(current.MainModule.FileName);
            Process[] processlist = Process.GetProcesses();
            foreach (Process process in processlist)
            {
                if (process.Id != current.Id)
                {
                    try
                    {
                        if (currentmd5 == md5hash(process.MainModule.FileName))
                        {
                            SetForegroundWindow(process.MainWindowHandle);
                            Environment.Exit(0);
                        }
                    }
                    catch (/* your exception */) { /* your exception goes here */ }
                }
            }
        }
    
        private string md5hash(string file)
        {
            string check;
            using (FileStream FileCheck = File.OpenRead(file))
            {
                MD5 md5 = new MD5CryptoServiceProvider();
                byte[] md5Hash = md5.ComputeHash(FileCheck);
                check = BitConverter.ToString(md5Hash).Replace("-", "").ToLower();
            }
    
            return check;
        }
    

    它只按进程id检查md5和。

    你可以重命名它,或者对你的文件做你想做的事情。如果md5散列相同,它不会打开两次。

    有人能给我一些建议吗?我知道答案是肯定的,但也许有人在寻找一个互斥的替代方案。