前言

在有些特殊项目中,软件可能是无人值守的,如果程序莫名其妙挂了或者进程被干掉了等等,这时开发一个看门狗程序是非常有必要的,它就像一只打不死的小强,只要程序非正常退出,它就能立即再次将被看护的程序启动起来。

代码实现

Tips:文末有完整源代码,就不一步一步写了

1、创建一个Dog类,主要用于间隔性扫描被看护程序是否还在运行

开了个定时器,每5秒去检查1次,如果没有找到进程则使用Process启动程序

public class Dog
{private Timer timer = new Timer();private string processName ;private string filePath;//要监控的程序的路径public Dog(){timer.Interval = 5000;timer.Tick += timer_Tick;}public void Start(string filePath){this.filePath = filePath;this.processName = Path.GetFileNameWithoutExtension(filePath);timer.Enabled = true;}/// <summary>/// 定时检测系统是否在运行/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void timer_Tick(object sender, EventArgs e){try{Process[] myproc = Process.GetProcessesByName(processName);if (myproc.Length == 0){Log.Info("检测到看护程序已退出,开始重新激活程序,程序路径:{0}",filePath);ProcessStartInfo info = new ProcessStartInfo{WorkingDirectory = Path.GetDirectoryName(filePath),FileName = filePath,UseShellExecute = true};Process.Start(info);Log.Info("看护程序已启动");}}catch (Exception){}}
}

2、在程序入口接收被看护程序的路径,启动Dog扫描

static class Program
{static NotifyIcon icon = new NotifyIcon();private static Dog dog = new Dog();/// <summary>/// 应用程序的主入口点。/// </summary>[STAThread]static void Main(string[] args){if (args == null || args.Length == 0){MessageBox.Show("启动参数异常", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);return;}string filePath = args[0];if(!File.Exists(filePath)){MessageBox.Show("启动参数异常", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);return;}Process current = Process.GetCurrentProcess();Process[] processes = Process.GetProcessesByName(current.ProcessName);//遍历与当前进程名称相同的进程列表 foreach (Process process in processes){//如果实例已经存在则忽略当前进程 if (process.Id != current.Id){//保证要打开的进程同已经存在的进程来自同一文件路径if (process.MainModule.FileName.Equals(current.MainModule.FileName)){//已经存在的进程return;}else{process.Kill();process.WaitForExit(3000);}}}icon.Text = "看门狗";icon.Visible = true;Log.Info("启动看门狗,看护程序:{0}",filePath);dog.Start(filePath);Application.Run();}
}

3、简单实现个日志记录器(使用第三方库也行,建议看护程序最好不要有任何依赖),也可直接使用我下面这个,很简单,无任何依赖

public class Log
{//读写锁,当资源处于写入模式时,其他线程写入需要等待本次写入结束之后才能继续写入private static ReaderWriterLockSlim LogWriteLock = new ReaderWriterLockSlim();//日志文件路径public static string logPath = "logs\\dog.txt";//静态方法todo:在处理话类型之前自动调用,去检查日志文件是否存在static Log(){//创建文件夹if (!Directory.Exists("logs")){Directory.CreateDirectory("logs");}}/// <summary>/// 写入日志./// </summary>public static void Info(string format, params object[] args){try{LogWriteLock.EnterWriteLock();string msg = args.Length > 0 ? string.Format(format, args) : format;using (FileStream stream = new FileStream(logPath, FileMode.Append)){StreamWriter write = new StreamWriter(stream);string content = String.Format("{0} {1}",DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),msg);write.WriteLine(content);//关闭并销毁流写入文件write.Close();write.Dispose();}}catch (Exception e){}finally{LogWriteLock.ExitWriteLock();}}
}

至此,看护程序已经搞定。接着在主程序(被看护程序)封装一个启停类

4、主程序封装看门狗启停类

public static class WatchDog
{private static string processName = "WatchDog";  //看护程序进程名(注意这里不是被看护程序名,你可以试一下换成主程序名字会使什么效果)private static string appPath = AppDomain.CurrentDomain.BaseDirectory; //系统启动目录/// <summary>/// 启动看门狗/// </summary>public static void Start(){try{string program = string.Format("{0}{1}.exe", appPath, processName);ProcessStartInfo info = new ProcessStartInfo{WorkingDirectory = appPath,FileName = program,CreateNoWindow = true,UseShellExecute = true,Arguments = Process.GetCurrentProcess().MainModule.FileName  //被看护程序的完整路径};Process.Start(info);}catch (Exception){}}/// <summary>/// 停用看门狗/// </summary>public static void Stop(){Process[] myproc = Process.GetProcessesByName(processName);foreach (Process pro in myproc){pro.Kill();pro.WaitForExit(3000);}}
}

原理也很简单,其中有两点需要注意:

  • processName字段表示看护程序,不是被看护程序,如果写反了,嗯...(你可以试下效果)‘

  • Arguments参数是被看护程序的完整路径,因为一般情况下,是由被看护程序启动看护程序,所以我们可以直接使用Process.GetCurrentProcess().MainModule.FileName获取到被看护程序的完整路径

5、在主程序入口点启动看门狗

public partial class App : Application
{[STAThread]static void Main(){//程序启动前调用看护程序WatchDog.Start();Application app = new Application();MainWindow mainWindow = new MainWindow();app.Run(mainWindow);}
}

Winform、普通WPF、Prism等入口点都不太一样,根据项目实际情况灵活处理即可

最后在需要正常退出程序的地方(也就是主程序关闭按钮或其它想要正常退出程序的地方)停止看门狗程序

效果

以下视频来源于

Dotnet9

源代码

https://github.com/luchong0813/WatchDogDemo

后续

如果是别人的 建议使用nssm把别人的程序 封装成服务由wondows去管理,可以去看我以前发表的如何用零代码将应用封装成服务-NSSM,如果是自己的 需要弹框跟用户反馈或交互,那就说明不是无人值守,可以不用看门狗。

在类似地铁进站通道、机场安检通道、口岸出入境通道等等都有一个引导程序,这种比较依赖图形界面的可以尝试使用看门狗程序,看门狗程序不依赖第三方库且代码量较少,一般不会跑飞。

转自:傲慢与偏见luc

链接:cnblogs.com/chonglu/p/16913746.html

- EOF -

技术群:添加小编微信dotnet999

公众号:dotnet讲堂

C# 简单制作一个看门狗程序相关推荐

  1. 如何制作一个微信小程序【微信小程序是怎么做的】

    为什么现在这么多人使用微信小程序呢?因为微信小程序除了便捷易开发,公司企业可以用来做小程序展示官网,商家也可以做小程序商城,甚至个人也可以拥有自己的小程序.那么如何制作一个微信小程序?微信小程序是怎么 ...

  2. 不用写一行代码,就能用ivx制作一个“微信小程序“,超牛逼

    今天需要为大家介绍一款神器ivx. 它是通用无代码开发平台,是面向新一代全栈开发人员的通过不编写代码的方式实现快速开发的软件开发平台,提供图形化逻辑编排编程语言.抽象组件.集成开发环境等能力,能够支持 ...

  3. c语言软件看门狗程序,X25045看门狗电路硬件连接图及C语言看门狗程序

    采用89C51单片机和X25045组成的看门狗电路,X25045硬件连接图如图2所示.X25045芯片内包含有一个看门狗定时器,可通过软件预置系统的监控时间.在看门狗定时器预置的时间内若没有总线活动, ...

  4. 关于PLC看门狗程序编写

    本文将对S7-300 和 s7-400 运用DP/DP coupler 看门狗通讯进行看门狗程序进行设计 程序条件:S7-300采用常规S7编程    S4-400采用CFC编程 1.看门狗设计原理 ...

  5. 看门狗子程序 c语言,X25045看门狗电路硬件连接图及C语言看门狗程序

    采用89C51单片机和X25045组成的看门狗电路,X25045硬件连接图如图2所示.X25045芯片内包含有一个看门狗定时器,可通过软件预置系统的监控时间.在看门狗定时器预置的时间内若没有总线活动, ...

  6. 用MFC制作一个倒计时小程序

    用MFC制作一个倒计时小程序 1.思路: 1)初始步骤1:新建一个工程,选择MFC AppWizard(exe),工程名命名为CdTimer,选择基于对话框形式的应用程序,将此主对话框用于显示剩余的时 ...

  7. linux 内核定时器(低精度) — 外部看门狗程序

    文章目录 1 内核定时器介绍 2 定时器数据结构及函数 3 外部看门狗驱动使用定时器函数 1 内核定时器 Linux 内核中有大量的函数需要时间管理,比如周期性的调度程序.延时程序等.硬件定时器 提供 ...

  8. Ubuntu下看门狗程序以及基于.destop文件实现的开机自启动

    首先说一下Ubuntu下看门狗程序,这个程序是用在我项目中的,用来保证核心程序能够实现崩溃自启动,这对于程序的稳定运行至关重要. 话不多少,直接上代码: (1)新建看门狗程序 daemon_uploa ...

  9. c语言看门狗的作用,51单片机 c语言看门狗程序怎么写

    51单片机 c语言看门狗程序怎么写 51单片机 c语言看门狗程序怎么写 看门狗在51单片机电路里的作用是防止程序 "跑飞"."死机"后,系统不动作,而采取复位的 ...

最新文章

  1. CCF-GAIR 2020 全球人工智能和机器人峰会今日开幕
  2. 安卓学习-界面-ui-Toast
  3. np.nonzero()函数的解析
  4. javaweb学习总结(十一)——使用Cookie进行会话管理
  5. (原)产品化:架构、过程管理
  6. Video : 将使用AD认证的SharePoint网站配置为表单方式登录
  7. 162. Find Peak Element
  8. ubuntu下MySQL的安装使用与卸载-程序编译
  9. 我的敏捷生活(1)--where am I
  10. v中国瓶装水市场营销状况与销售动态分析报告2022-2027年
  11. ionic html5 上传图片,ionic文件选择与ionic文件上传
  12. CSS3和jQuery实现花瓣网固定顶部位置悬浮菜单效果
  13. py读取xlsx文件
  14. 值得收藏:程序员必去的社区与网站
  15. [Linux] WIN7下Virtualbox虚拟Ubuntu共享文件夹设置
  16. java 正整数类型_Java 整数类型
  17. GCN学习:用PyG实现自定义layers的GCN网络及训练(五)
  18. 各向异性渲染(一)基础理论
  19. 使用安卓原生系统刷机,修改
  20. 接口测试管理平台手册

热门文章

  1. 屏蔽优酷广告手动修改方法 (xp win7均有效)
  2. 苹果:iOS比安卓更安全!安卓恶意软件感染率是iPhone几十倍?
  3. 【AI名利场】2018年投资趋势:70%机构押注人工智能,“应用场景”成关键词
  4. #创新应用#文件大师:小身躯大智慧!
  5. lcd屏幕是rgb565时 rgb24转rgb16
  6. 项目总结之ios手机中input框中粘贴短信验证码keyup事件无效
  7. 软硬结合解决电脑运维困境,让SMB IT管理从小而杂到小而精
  8. EZ CD Audio Converter v9.4.0.1 CD转换抓轨工具便携版
  9. 张瀚荣 如何用UE4制作3D动作游戏
  10. telegram怎么查社工库_《第五人格》律师日记怎么过 律师日记推演二通关介绍