C#判断当前启动程序进程是否存在

本文介绍了如何使用 Mutex 控制应用程序的单例运行,并提供了一种检查当前是否存在相同进程的方法。此外,还给出了以管理员权限启动应用程序的示例。

原文:

http://blog.youkuaiyun.com/haylhf/article/details/7842087

System.Threading.Mutex mutex;//注意,此变量要定义为成员变量,而不是局部变量

  bool CheckMultiInstance()
        {
            bool createdNew = true;

            mutex = new System.Threading.Mutex(true, "_TEST_Mutex_", out createdNew);//这种在系统多用户下,每个用户能启动一个程序进程

mutex = new System.Threading.Mutex(true, "Global\\_TEST_Mutex_", out createdNew);//这种在系统中,不管几个用户,只能存在一个这样的程序进程


            if (!createdNew)
            {
               MessageBox.Show("Program is already running.");
            }
            return createdNew;
        }


        /// <summary>
        /// Is exist same process
        /// </summary>
        /// <returns></returns>
        public static Process GetExistProcess()
        {
            try
            {
                var current = Process.GetCurrentProcess();
                var pArrayy = System.Diagnostics.Process.GetProcessesByName(current.ProcessName);

                if (pArrayy == null || pArrayy.Length == 0)
                {
                    return null;
                }
                foreach (var item in pArrayy)
                {
                    try
                    {

                       /**** 这种判断方法,有BUG,当第一次以管理员启动,第二次不以管理员启动时,将会有访问被拒绝的异常抛出

                        if (!item.ProcessName.ToUpper().Contains(current.ProcessNameToUpper()))
                        {
                            continue;
                        }
                        if (item.Id != current.Id && item.MainModule.ModuleName.ToUpper() == current.MainModule.ModuleName.ToUpper())
                        {
                            return item;
                        }  

                       **** */    

                       ///改成一下方法可解决权限问题

                          if(item.MainWindowHandle!=Intptr.Zero)///此时已存在的进程主窗口句柄是有值的,而第二次的APP虽然起来了,但是窗口还没有Show出来,是没有主窗口句柄的

                          {

                              return   item;

                           }
                    }

                    catch (Exception er)
                    {
                        LogHelper.WriteException(er);
                        continue;
                    }
                
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteException(ex);
            }
            return null;

        }

 

补充以管理员权限启动:

 

 

   privatevoidToShowExeAsAdmin()

        {

      try

            {

        stringstartPath="test.exe";

        if (File.Exists(startPath))

                {

                    ProcessStartInfostartInfo=newProcessStartInfo();

 

                    startInfo.FileName=startPath;

 

                    startInfo.UseShellExecute=true;

 

                    startInfo.Verb="runas";// 用admin权限启动新进程 

 

                    System.Diagnostics.Process.Start(startInfo);//use admin

               }

            }

      catch (Exceptionex)

            {

                LogHelper.WriteException(ex);

            }

        }

 

C#中,可以使用不同的方法获取当前程序进程相关信息。 ### 获取系统当前进程 可运行如下代码来获取系统当前进程的信息,更多细节可参考博文:https://cplusplus.blog.youkuaiyun.com/article/details/137371935 [^1]。 ### 获取运行程序进程ID 以下代码展示了通过窗口名称获取运行程序进程ID的方法: ```csharp using System; using System.Runtime.InteropServices; class Program { [DllImport("User32.dll", CharSet = CharSet.Auto)] public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID); [DllImport("user32.dll", EntryPoint = "FindWindow")] private extern static IntPtr FindWindow(string lpClassName, string lpWindowName); static void Main(string[] args) { IntPtr hwnd = FindWindow(null, "计算器"); if (hwnd != IntPtr.Zero) { int calcID; // 获取进程ID GetWindowThreadProcessId(hwnd, out calcID); } } } ``` 此代码通过`FindWindow`函数找到指定名称的窗口句柄,再使用`GetWindowThreadProcessId`函数获取该窗口对应的进程ID [^2]。 ### 获取当前活动窗口进程进程ID、程序路径 以下代码可以获取当前活动窗口的进程进程ID和程序路径: ```csharp using System; using System.Diagnostics; using System.Threading; using System.Runtime.InteropServices; using System.Windows.Forms; namespace GetActiveWindowProcess // 获取活动窗口进程信息 { class Program { [DllImport("User32.dll")] public static extern IntPtr GetForegroundWindow(); // 获取活动窗口句柄 [DllImport("User32.dll", CharSet = CharSet.Auto)] public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID); // 获取线程ID static void Main(string[] args) { Thread.Sleep(3000); // 睡眠3s,用来选择活动窗口 IntPtr hWnd = GetForegroundWindow(); // 获取活动窗口句柄 int calcID = 0; // 进程ID int calcTD = 0; // 线程ID calcTD = GetWindowThreadProcessId(hWnd, out calcID); Process myProcess = Process.GetProcessById(calcID); MessageBox.Show("进程名:" + myProcess.ProcessName + "\n" + "进程ID:" + calcID + "\n" + "程序路径:" + myProcess.MainModule.FileName); // 在MessageBox中显示获取的信息 Console.ReadKey(); } } } ``` 代码先通过`GetForegroundWindow`获取当前活动窗口的句柄,再使用`GetWindowThreadProcessId`获取该窗口对应的进程ID,最后通过`Process.GetProcessById`获取进程对象,从而得到进程名、进程ID和程序路径 [^3]。 ### 获取当前程序各种属性 下面代码展示了获取当前程序各种属性的方法: ```csharp using System; using System.Reflection; using System.Diagnostics; // 方法类 class ProgramInfo { // 获取程序集名称 public string ToFriendlyName = AppDomain.CurrentDomain.FriendlyName; // 获取当前程序运行目录 public string ToBaseDirectory = AppDomain.CurrentDomain.BaseDirectory; // 获取当前进程程序)名 public string ToName = Assembly.GetExecutingAssembly().GetName().Name; // 获取当前程序集版本 public string ToVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(); } class Program { static void Main() { // 调用方法 ProgramInfo myInfo = new ProgramInfo(); Debug.Print("程序(集)名:" + myInfo.ToFriendlyName); Debug.Print("程序运行目录:" + myInfo.ToBaseDirectory); Debug.Print("进程程序)名:" + myInfo.ToName); Debug.Print("程序(集)版本:" + myInfo.ToVersion); } } ``` 此代码通过`AppDomain.CurrentDomain`和`Assembly.GetExecutingAssembly`获取程序集名称、程序运行目录、进程名和程序集版本等信息 [^4]。 ### 判断当前启动程序进程是否存在 以下代码展示了判断当前启动程序进程是否存在的逻辑: ```csharp // 假设 current 是当前进程对象 // 假设 item 是遍历的进程对象 if (!item.ProcessName.ToUpper().Contains(current.ProcessName.ToUpper())) { continue; } if (item.Id != current.Id && item.MainModule.ModuleName.ToUpper() == current.MainModule.ModuleName.ToUpper()) { return item; } ``` 该代码通过比较进程名和模块名来判断是否存在相同的进程 [^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值