原文:c# 守护进程,WPF程序自守护

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/lwwl12/article/details/79035246

如何防止wpf程序异常关闭,守护进程是暂时能想到的最好方式。最好是能够一次编码就把守护进程的事情做完。

思路:程序打开时,首先打开守护进程;由守护进程打开主程序;守护进程与主程序间互相守护,任何一个挂了都能自动重启。

实现:Mutex互斥量,守护进程和主程序分别使用不同的互斥量,既可以防止重复打开软件,又可以检测程序是否在运行。

话不多说,直接上代码:

    /// <summary>
/// App.xaml 的交互逻辑
/// </summary>
public partial class App : Application
{
/// <summary>
/// 主进程互斥量
/// </summary>
private static System.Threading.Mutex mutex_main; /// <summary>
/// 守护进程互斥量
/// </summary>
private static System.Threading.Mutex mutex_deamon; /// <summary>
/// 是否为主进程
/// </summary>
private static bool isMain = false; /// <summary>
/// 打开监视定时器
/// </summary>
public void RunMonitorTimer()
{
System.Timers.Timer timer = new System.Timers.Timer();
timer.Elapsed += timer_Elapsed;
timer.Interval = 2000;
timer.Start();
} /// <summary>
/// 打开程序
/// </summary>
/// <param name="arg">参数不为null时打开主进程,否则打开守护进程</param>
public void RunProcess(string arg = null)
{
/* 运行程序,不带参数,打开守护进程 */
Process m_Process = new Process();
m_Process.StartInfo.FileName = Process.GetCurrentProcess().MainModule.FileName;
m_Process.StartInfo.Arguments = arg;
m_Process.Start();
} protected override void OnStartup(StartupEventArgs e)
{
//根据参数判断开启主进程还是守护进程,守护进程不带参数,主进程带参数
if (e.Args.Length < 1)
{
Application.Current.ShutdownMode = System.Windows.ShutdownMode.OnExplicitShutdown; //守护进程互斥量
mutex_deamon = new System.Threading.Mutex(true, "MUTEX_DEAMON");
if (mutex_deamon.WaitOne(0, false))
{
RunMonitorTimer(); // 显示一个自定义窗体,非主窗体,用于阻塞进程,窗体关闭后,守护进程将关闭
WndDeamon wnd = new WndDeamon();
wnd.ShowDialog(); this.Shutdown();
}
else
{
MessageBox.Show("程序已经在运行!", "提示");
this.Shutdown();
}
}
else
{
isMain = true;
mutex_main = new System.Threading.Mutex(true, "MUTEX_MAIN");
if (mutex_main.WaitOne(0, false))
{
RunMonitorTimer(); base.OnStartup(e);
Application.Current.ShutdownMode = ShutdownMode.OnMainWindowClose;
}
else
{
Application.Current.ShutdownMode = System.Windows.ShutdownMode.OnExplicitShutdown;
MessageBox.Show("程序已经在运行!", "提示");
this.Shutdown();
}
}
} void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (!isMain)
{
if (mutex_main == null)
{
mutex_main = new System.Threading.Mutex(true, "MUTEX_MAIN");
}
if (mutex_main.WaitOne(0, false))
{
//必须释放mutex,否则将导致mutex被占用,主程序不能允许
mutex_main.Dispose();
mutex_main = null; RunProcess("main");
}
}
else
{
if (mutex_deamon == null)
{
mutex_deamon = new System.Threading.Mutex(true, "MUTEX_DEAMON");
}
if (mutex_deamon.WaitOne(0, false))
{
mutex_deamon.Dispose();
mutex_deamon = null; RunProcess();
}
}
}
}

app.xaml中添加上述代码即可,只需定义WndDeamon.xaml窗体用于展示守护进程状态,也可使用其他方式,有更好方式欢迎留言。

c# 守护进程,WPF程序自守护的更多相关文章

  1. Linux 守护进程二(激活守护进程)

    //守护进程--读文件 #include <stdio.h> #include <stdlib.h> #include <string.h> #include &l ...

  2. Linux守护进程实现程序只运行一次

    1.守护进程 守护进程(Daemon)是一种运行在后台的特殊进程,它独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件. 2.让程序只运行一次 如果让程序只运行一次,有很多方法,此处的一种 ...

  3. Java实现Linux下服务器程序的双守护进程

    作者:Vinkn 来自http://www.cnblogs.com/Vinkn/ 一.简介 现在的服务器端程序很多都是基于Java开发,针对于Java开发的Socket程序,这样的服务器端上线后出现问 ...

  4. linux下的守护进程daemon

    什么是守护进程?其实感觉守护进程并没有什么明确的定义,只是守护进程有一些特征,这是它需要遵循的. 守护进程的第一个特征是长时间在后台运行的程序,并且主要是为了提供某种服务,而为了能够让服务尽可能随时都 ...

  5. Linux守护进程

    什么是守护进程? 守护进程是生存期长的一种进程,它们常常在系统引导装入时启动,仅在系统关闭时在终止.它们没有控制终端并且在后台运行.Linux 系统中有很多守护进程用以执行系统的日常事物,而且服务器程 ...

  6. [转]❲阮一峰❳Linux 守护进程的启动方法

    ❲阮一峰❳Linux 守护进程的启动方法 "守护进程"(daemon)就是一直在后台运行的进程(daemon). 本文介绍如何将一个 Web 应用,启动为守护进程. 一.问题的由来 ...

  7. Linux 普通进程 后台进程 守护进程

    一.普通进程与后台进程 默认情况下,进程是在前台运行的,这时就把shell给占据了,我们无法进行其它操作.对于那些没有交互的进程,很多时候,我们希望将其在后台启动,可以在启动参数的时候加一个'& ...

  8. Server Develop (七) Linux 守护进程

    守护进程 守护进程,也就是通常说的Daemon进程,是Linux中的后台服务进程.它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.守护进程常常在系统引导装 ...

  9. Linux 守护进程和超级守护进程(xinetd)

    一 .Linux守护进程 Linux 服务器在启动时需要启动很多系统服务,它们向本地和网络用户提供了Linux的系统功能接口,直接面向应用程序和用户.提供这些服务的程序是由运行在后台的守护进程来执行的 ...

随机推荐

  1. JSON入门之二:org.json的基本用法 分类: C_OHTERS 2014-05-14 11:25 6001人阅读 评论(0) 收藏

    java中用于解释json的主流工具有org.json.json-lib与gson,本文介绍org.json的应用. 官方文档: http://www.json.org/java/ http://de ...

  2. 群晖synology的Video Station无法通过浏览器在线播放视频

    群晖synology的Video Station无法通过浏览器在线播放视频 http://www.hangge.com/blog/cache/detail_419.html

  3. js进阶正则表达式15验证身份证号(|符号的使用:var reg=/^\d{17}[\d|X]$|^\d{15}$/)(str的方法substr)

    js进阶正则表达式15验证身份证号(|符号的使用:var reg=/^\d{17}[\d|X]$|^\d{15}$/)(str的方法substr) 一.总结 1.|符号的使用:var reg=/^\d ...

  4. base64码通过http传输 +号变 空格 问题解决

    通过七牛云base64上传图片,通过官方示例上传成功后,根据示例改了一个controller. 通过前端往后端传base64码形式进行测试.死活不通过,七牛报400. 仔细排查后发现,示例转换的bas ...

  5. Android中HandlerThread的使用及源代码解析

    关于Hanlder的基本使用能够參见博文<Android中Handler的使用>,假设想了解Handler.Looper.Thread等的相互关系以及内部实现原理能够參见博文<深入源 ...

  6. 微信小程序开发实战视频教程

    微信小程序开发实战视频教程发布  有全套的 pan.baidu.com/s/1o8GuJOY 密码:2dbo 腾讯终于发布了没有APPid,无需申请也可以进行微信小程序开发的视频教程了,我在在第一时间 ...

  7. php取两位小数的几种方法

    php取两位小数的几种方法 一.总结 一句话总结: 1.round   四舍五入 2.sprintf   c语言方式 3.number_format 千分位数字格式化的那个函数 二.php取两位小数的 ...

  8. leveldb学习:skiplist

    leveldb中的memtable仅仅是一个封装类,它的底层实现是一个跳表. 跳表是一种基于随机数的平衡数据结构.其它的平衡数据结构还有红黑树.AVL树.但跳表的原理比它们简单非常多.跳表有点像链表, ...

  9. java使用mongoDB和freemarker注意事项

    mongoDB和关系数据库的差异最大的优势就是表结构不正确,说:.弱事务.mongoDB以牺牲换来的交易进行更快的访问速度,有人说mongoDB对于内存太贪婪,事实上,它不会.随着windows版本, ...

  10. NOIP模拟1717 总结

    总结 T1: 有x个人在a时b分来,c时d分离开,求所有时刻中人数的最大值. 差分裸题,当然也可以写线段树. 第一题一般来说思维都不会太复杂,如果打的时间很长,便要调整自己的思路,要保证A掉. T2: ...