原文: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窗体用于展示守护进程状态,也可使用其他方式,有更好方式欢迎留言。
05-13 21:05