c# 守护进程,WPF程序自守护

简介: 原文:c# 守护进程,WPF程序自守护 版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/lwwl12/article/details/79035246 如何防止wpf程序异常关闭,守护进程是暂时能想到的最好方式。
原文: 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窗体用于展示守护进程状态,也可使用其他方式,有更好方式欢迎留言。

目录
相关文章
|
1月前
|
缓存 负载均衡 安全
在Python中,如何使用多线程或多进程来提高程序的性能?
【2月更文挑战第17天】【2月更文挑战第50篇】在Python中,如何使用多线程或多进程来提高程序的性能?
|
3月前
|
C# 开发者
C# 9.0中的模块初始化器:程序启动的新控制点
【1月更文挑战第14天】本文介绍了C# 9.0中引入的新特性——模块初始化器(Module initializers)。模块初始化器允许开发者在程序集加载时执行特定代码,为类型初始化提供了更细粒度的控制。文章详细阐述了模块初始化器的语法、用途以及与传统类型初始化器的区别,并通过示例代码展示了如何在实际项目中应用这一新特性。
|
3月前
|
编译器 C# 开发者
C# 9.0中的顶级语句:简化程序入口的新特性
【1月更文挑战第13天】本文介绍了C# 9.0中引入的顶级语句(Top-level statements)特性,该特性允许开发者在不使用传统的类和方法结构的情况下编写简洁的程序入口代码。文章详细阐述了顶级语句的语法、使用场景以及与传统程序结构的区别,并通过示例代码展示了其在实际应用中的便捷性。
|
4月前
|
负载均衡 JavaScript 算法
Node.js 多进程的概念、原理、优势以及如何使用多进程来提高应用程序的性能和可伸缩性
Node.js 多进程的概念、原理、优势以及如何使用多进程来提高应用程序的性能和可伸缩性
41 1
|
1天前
|
Java Shell Linux
【linux进程控制(三)】进程程序替换--如何自己实现一个bash解释器?
【linux进程控制(三)】进程程序替换--如何自己实现一个bash解释器?
|
1月前
|
Java C# 开发工具
第一个C#程序
第一个C#程序
12 0
|
1月前
|
Shell Linux 调度
【Linux】—— 进程程序替换
【Linux】—— 进程程序替换
|
1月前
|
数据采集 存储 C#
抓取Instagram数据:Fizzler库带您进入C#程序的世界
在当今数字化的世界中,数据是无价之宝。社交媒体平台如Instagram成为了用户分享照片、视频和故事的热门场所。作为开发人员,我们可以利用爬虫技术来抓取这些平台上的数据,进行分析、挖掘和应用。本文将介绍如何使用C#编写一个简单的Instagram爬虫程序,使用Fizzler库来解析HTML页面,同时利用代理IP技术提高采集效率。
抓取Instagram数据:Fizzler库带您进入C#程序的世界
|
1月前
|
Java Linux Shell
进程的程序替换(exec函数)【Linux】
进程的程序替换(exec函数)【Linux】
|
2月前
|
监控 Unix Linux
socket监控进程,并对程序执行有关操作。
socket监控进程,并对程序执行有关操作。