C# winform 判断 exe程序是否正常运行,守护进程(支持C++非托管代码报错处理)

通常需要长时间连续允许的C# exe程序,要保持无人守护,则需要有守护进程(另外一个exe程序定时检查)

常用办法 是通过 Process对象找到对应的进程是否存在即可判断

获取对应的进程:

1.启动后保存ProcessID

 var target = Process.Start(exePath, "auto");
 var targetProcessId = target.Id;
 // 获取指定ID的进程
 var process = Process.GetProcessById(targetID);

 if(process==null)
 {
    // 进程不存在 已退出 ,需要重启
    // 重启代码
 }

2.通过EXE的允许目录获取

        //通过exe的允许路径 查找对应的进程
        private Process FindMainProcessByPath(string exePath)
        {
            foreach (var p in Process.GetProcesses())
            {
                try
                {
                    if (p.MainModule.FileName == exePath)
                    {
                        if (p.Id != Process.GetCurrentProcess().Id)
                        {
                            target = p;
                            break;
                        }
                    }
                }
                catch (Exception ex)
                { }
            }
            return target;
        }
        var exePath="C:\\xxxxxxxx.exe";
        var process=FindMainProcessByPath(exePath);
        if(process==null)
        {
            // 进程不存在 已退出 ,需要重启
            // 重启代码
        }

但是如果是进程卡死 ,进程是不会退出的,通过该方法是无法判断程序是否还在正常允许,需要增加如下逻辑

        /// <summary>
        /// 判断指定进程状态(是否正常运行)
        /// </summary>
        /// <param name="p"></param>
        /// <returns>
        /// 进程状态正常:true
        /// 进程卡死:false
        /// </returns>
        public bool checkProcess(Process p)
        {
            //判断进程是否响应(进程是否整体卡死)
            if (p.Responding)
            {
                //指定进程的总线程数
                int thSumCount = p.Threads.Count;
                //指定进程的无响应线程数
                int suspendCount = 0;
                foreach (ProcessThread t in p.Threads)
                {
                    //进程处于等待状态
                    if (t.ThreadState == System.Diagnostics.ThreadState.Wait)
                    {
                        //等待原因为挂起
                        if (t.WaitReason == ThreadWaitReason.Suspended)
                            suspendCount++;
                    }
                }
                //除了一个异常报错的对话框线程,其他线程都挂起了,说明进程已经卡死
                if (thSumCount > 1 && thSumCount == suspendCount + 1)
                {
                    PLogger.Info("target thread(" + thSumCount + "/" + suspendCount + ") is Responding");
                    return false;
                }
                //进程及其中线程响应中
                return true;
            }
            else
            {
                return false;
            }
        }

这里判断进程是否卡死的通过2个逻辑:

1        process.Responding = false 时 为进程不响应

2        进程下的存在多个线程,仅1个线程在响应

第二点是为了处理 C++的非托管代码报错导致的程序卡死报错

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值