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

目录
相关文章
|
5月前
|
缓存 C# Windows
C#程序如何编译成Native代码
【10月更文挑战第15天】在C#中,可以通过.NET Native和第三方工具(如Ngen.exe)将程序编译成Native代码,以提升性能和启动速度。.NET Native适用于UWP应用,而Ngen.exe则通过预编译托管程序集为本地机器代码来加速启动。不过,这些方法也可能增加编译时间和部署复杂度。
345 2
|
3月前
|
算法 Java 测试技术
Benchmark.NET:让 C# 测试程序性能变得既酷又简单
Benchmark.NET是一款专为 .NET 平台设计的性能基准测试框架,它可以帮助你测量代码的执行时间、内存使用情况等性能指标。它就像是你代码的 "健身教练",帮助你找到瓶颈,优化性能,让你的应用跑得更快、更稳!希望这个小教程能让你在追求高性能的路上越走越远,享受编程带来的无限乐趣!
187 13
|
4月前
|
前端开发 C# Windows
在WPF程序中实现PropertyGrid功能
【11月更文挑战第15天】PropertyGrid 是一个用户界面组件,用于直观地查看和编辑对象属性。在 WPF 中可通过组合 Expander 和 DataGrid 实现基本功能,或使用第三方库 PropertyTools 获得更强大特性,包括属性验证和类型特定编辑器。
249 3
|
5月前
|
设计模式 程序员 C#
C# 使用 WinForm MDI 模式管理多个子窗体程序的详细步骤
WinForm MDI 模式就像是有超能力一般,让多个子窗体井然有序地排列在一个主窗体之下,既美观又实用。不过,也要小心管理好子窗体们的生命周期哦,否则一不小心就会出现一些意想不到的小bug
452 0
C# WPF 中 外部图标引入iconfont,无法正常显示问题 【小白记录】
本文介绍了在C# WPF应用程序中引入外部iconfont图标时可能遇到的显示问题及其解决方法:1) 检查资源路径和引入格式是否正确,确保字体文件引用格式为“#xxxx”,并正确指向字体文件位置;2) 确保图标资源被包含在程序集中,通过设置字体文件的生成操作为Resource(资源)来实现。
C# WPF 中 外部图标引入iconfont,无法正常显示问题 【小白记录】
|
6月前
|
编解码 C# 数据库
C# + WPF 音频播放器 界面优雅,体验良好
【9月更文挑战第18天】这是一个用 C# 和 WPF 实现的音频播放器示例,界面简洁美观,功能丰富。设计包括播放/暂停按钮、进度条、音量控制滑块、歌曲列表和专辑封面显示。功能实现涵盖音频播放、进度条控制、音量调节及歌曲列表管理。通过响应式设计、动画效果、快捷键支持和错误处理,提升用户体验。可根据需求扩展更多功能。
208 3
|
6月前
|
C# 容器
C#中的命名空间与程序集管理
在C#编程中,`命名空间`和`程序集`是组织代码的关键概念,有助于提高代码的可维护性和复用性。本文从基础入手,详细解释了命名空间的逻辑组织方式及其基本语法,展示了如何使用`using`指令访问其他命名空间中的类型,并提供了常见问题的解决方案。接着介绍了程序集这一.NET框架的基本单位,包括其创建、引用及高级特性如强名称和延迟加载等。通过具体示例,展示了如何创建和使用自定义程序集,并提出了针对版本不匹配和性能问题的有效策略。理解并善用这些概念,能显著提升开发效率和代码质量。
266 4
|
5月前
|
XML 存储 安全
C#开发的程序如何良好的防止反编译被破解?ConfuserEx .NET混淆工具使用介绍
C#开发的程序如何良好的防止反编译被破解?ConfuserEx .NET混淆工具使用介绍
282 0
|
5月前
|
安全 API C#
C# 如何让程序后台进程不被Windows任务管理器强制结束
C# 如何让程序后台进程不被Windows任务管理器强制结束
161 0
|
5月前
|
API C#
C#实现Winform程序右下角弹窗消息提示
C#实现Winform程序右下角弹窗消息提示
261 0

相关实验场景

更多