如何确保C#的应用程序只被打开一次

http://stackoverflow.com/questions/184084/how-to-force-c-sharp-net-app-to-run-only-one-instance-in-windows

复制代码
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;
            }
         }
      }
   }
}
复制代码

上面代码的MyApplicationName需要确保是唯一识别的

 

VS调试程序的时候

string appName;
appName = Process.GetCurrentProcess().ProcessName;//ZITaker.vshost

appName = Process.GetCurrentProcess().MainModule.FileName;//D:\Software\ZBMYun\SourceCode\ZITaker\ZITaker\bin\Debug\ZITaker.vshost.exe

appName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;//ZITaker

appName = System.Reflection.Assembly.GetExecutingAssembly().Location;//D:\Software\ZBMYun\SourceCode\ZITaker\ZITaker\bin\Debug\ZITaker.exe

 

直接执行exe的时候

string appName;
appName = Process.GetCurrentProcess().ProcessName;//ZITaker

appName = Process.GetCurrentProcess().MainModule.FileName;//D:\Software\ZBMYun\SourceCode\ZITaker\ZITaker\bin\Debug\ZITaker.exe

appName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;//ZITaker

appName = System.Reflection.Assembly.GetExecutingAssembly().Location;//D:\Software\ZBMYun\SourceCode\ZITaker\ZITaker\bin\Debug\ZITaker.exe

 

从上面可以看出System.Reflection.Assembly.GetExecutingAssembly().Location适合作为程序的唯一识别码

http://stackoverflow.com/questions/4313756/creating-a-mutex-throws-a-directorynotfoundexception    //遇到找不到文件路径的错误

My mutex name had \ in it, which windows was interpreting as a path character. Running:

将路径名中的反斜杠替换成_就可以了

 

正确的做法:

string appName;
appName = System.Reflection.Assembly.GetExecutingAssembly().Location;
appName = appName.Replace(Path.DirectorySeparatorChar, '_');
using (Mutex mutex = new Mutex(true, appName, out createdNew))

 

 

 

appName = Process.GetCurrentProcess().MainModule.FileName;//D:\Software\ZBMYun\SourceCode\ZITaker\ZITaker\bin\Debug\ZITaker.vshost.exe
ZBM.ZITaker.Log.OperationLog.Instance.WriteLog(appName, ZBM.ZITaker.Log.LogType.UI);
appName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;//ZITaker
ZBM.ZITaker.Log.OperationLog.Instance.WriteLog(appName, ZBM.ZITaker.Log.LogType.UI);
appName = System.Reflection.Assembly.GetExecutingAssembly().Location;//D:\Software\ZBMYun\SourceCode\ZITaker\ZITaker\bin\Debug\ZITaker.exe
ZBM.ZITaker.Log.OperationLog.Instance.WriteLog(appName, ZBM.ZITaker.Log.LogType.UI);

最终版本

复制代码
using System;
using System.Windows.Forms;//Application
using System.Diagnostics;//Process
using System.Threading;//Mutex
using System.Runtime.InteropServices;//DllImport
using System.IO;//Path

static class Program
    {
        [DllImport("User32.dll")]
        //This function puts the thread that created the specified window into the foreground and activates the window.
        private static extern bool SetForegroundWindow(IntPtr hWnd);

        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            try
            {
                bool createdNew;
                string appName;
                appName = System.Reflection.Assembly.GetExecutingAssembly().Location;
appName = appName.Replace(Path.DirectorySeparatorChar, '_');
using (Mutex mutex = new Mutex(true, appName, out createdNew)) { if (createdNew) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Main()); } else { Process current = Process.GetCurrentProcess(); foreach (Process process in Process.GetProcessesByName(current.ProcessName)) { if (process.Id != current.Id) { SetForegroundWindow(process.MainWindowHandle); break; } } } } } catch (Exception ex) { } } }
复制代码

 

 

 

http://www.cnblogs.com/xiashengwang/archive/2012/08/29/2662366.html

这篇文章中也提到了Mutex实现一次只打开一个应用程序

作者:Chuck Lu    GitHub    
posted @   ChuckLu  阅读(4127)  评论(2编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示