Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >在操作系统重启后恢复应用程序的工作状态

在操作系统重启后恢复应用程序的工作状态

作者头像
walterlv
发布于 2018-09-18 03:21:47
发布于 2018-09-18 03:21:47
2.3K00
代码可运行
举报
运行总次数:0
代码可运行

在操作系统重启后恢复应用程序的工作状态

发布于 2018-01-21 13:29 更新于 2018-09-01 00:13

Windows 10 创意者更新之后,默认开启了重启后恢复应用程序状态的功能。这是自 Vista 以来就提供的功能——Restart Manager。


应用程序实现这一功能只需要调用 RegisterApplicationRestart 即可。传入两个参数:

  1. 重启后使用的命令行参数(例如当前正在打开的文件,以及正在阅读或编辑的位置)
  2. 决定是否进行重启的限制标记(任何时候都能重启还是在某些条件下关掉重启功能)

我封装了以下这个函数的调用并将其放到 GitHub 上:sharing-demo/ApplicationRestartManager.cs at master · walterlv/sharing-demo

调用代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if (ApplicationRestartManager.IsRestartManagerSupported)
{
    ApplicationRestartManager.RegisterApplicationRestart(
        currentOpeningFile,
        ApplicationRestartFlags.None);
}

:封装的 ApplicationRestartManager

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using System;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
using System.Windows;
using Jetbrains.Annotations;

namespace Walterlv.Win32
{
    /// <summary>
    /// 为应用程序提供重启后恢复状态的功能。
    /// </summary>
    public class ApplicationRestartManager
    {
        /// <summary>
        /// 获取一个值,该值指示当前操作系统环境是否支持 Restart Manager 功能。
        /// Restart Manager 是 Windows Vista 新增的功能。在 Windows 10 秋季创意者更新之后,默认开启了 EWX_RESTARTAPPS。
        /// </summary>
        public static bool IsSupported => IsSupportedLazy.Value;

        /// <summary>
        /// 向操作系统的 Restart Manager 注册应用终止后的重启方式。
        /// </summary>
        /// <param name="pwsCommandLine">
        /// 应用程序的重启时应该使用的参数,允许为 null,表示不带参数。
        /// 请注意:如果命令行参数中的某一个参数包含空格,请加上引号。
        /// </param>
        /// <param name="dwFlags">为应用程序的重启行为添加限制,默认没有限制。</param>
        /// <returns></returns>
        public static bool RegisterApplicationRestart(
            [CanBeNull] string pwsCommandLine,
            ApplicationRestartFlags dwFlags = ApplicationRestartFlags.None)
        {
            return 0 == RegisterApplicationRestart(pwsCommandLine, (int) dwFlags);
        }

        /// <summary>
        /// Windows Vista 及以上才开启 Restart Manager。
        /// </summary>
        [ContractPublicPropertyName(nameof(IsSupported))]
        private static readonly Lazy<bool> IsSupportedLazy =
            new Lazy<bool>(() => Environment.OSVersion.Version >= new Version(6, 0));

        /// <summary>
        /// Registers the active instance of an application for restart.
        /// See also: [RegisterApplicationRestart function (Windows)](https://msdn.microsoft.com/en-us/library/windows/desktop/aa373347)
        /// </summary>
        /// <param name="pwzCommandline">
        /// A pointer to a Unicode string that specifies the command-line arguments for the application when it is restarted. The maximum size of the command line that you can specify is RESTART_MAX_CMD_LINE characters. Do not include the name of the executable in the command line; this function adds it for you.
        /// If this parameter is NULL or an empty string, the previously registered command line is removed. If the argument contains spaces, use quotes around the argument.
        /// </param>
        /// <param name="dwFlags">
        /// This parameter can be 0 or one or more of the following values:
        /// - 1: Do not restart the process if it terminates due to an unhandled exception.
        /// - 2: Do not restart the process if it terminates due to the application not responding.
        /// - 4: Do not restart the process if it terminates due to the installation of an update.
        /// - 8: Do not restart the process if the computer is restarted as the result of an update.
        /// </param>
        /// <returns>
        /// This function returns S_OK on success or one of the following error codes.
        /// - E_FAIL: Internal error.
        /// - E_INVALIDARG: The specified command line is too long.
        /// </returns>
        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        private static extern uint RegisterApplicationRestart(string pwzCommandline, int dwFlags);
    }

    /// <summary>
    /// 表示重启时的限制标记。
    /// </summary>
    [Flags]
    public enum ApplicationRestartFlags
    {
        /// <summary>
        /// 没有重启限制。如果仅指定 <see cref="None"/>,那么操作系统在可以重启应用程序的时候都会重启应用。
        /// </summary>
        None = 0,

        /// <summary>
        /// 指定此时不重启:因未处理的异常而导致进程停止工作。
        /// </summary>
        RestartNoCrash = 1,

        /// <summary>
        /// 指定此时不重启:因应用程序无响应而导致进程停止工作。
        /// </summary>
        RestartNoHang = 2,

        /// <summary>
        /// 指定此时不重启:因应用安装更新导致进程关闭。
        /// </summary>
        RestartNoPatch = 4,

        /// <summary>
        /// 指定此时不重启:因操作系统安装更新后重启导致进程关闭。
        /// </summary>
        RestartNoReboot = 8
    }
}

参考资料

本文会经常更新,请阅读原文: https://walterlv.com/post/application-restart-manager.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 吕毅 (包含链接: https://walterlv.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 (walter.lv@qq.com)

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-01-21 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
WPF 基于 WER 注册应用崩溃无响应回调和重启方法
本文来告诉大家如何在 Windows 上利用从 Vista 引入的 Windows Error Reporting (WER) 机制来实现,在应用崩溃、无响应等异常的时候收到回调用于处理信息保存
林德熙
2021/08/17
8370
WPF 基于 WER 注册应用崩溃无响应回调和重启方法
.NET/C# 获取一个正在运行的进程的命令行参数
在自己的进程内部,我们可以通过 Main 函数传入的参数,也可以通过 Environment.GetCommandLineArgs 来获取命令行参数。
walterlv
2020/02/10
2.5K0
制作一个极简的 .NET 客户端应用自安装或自更新程序
本文主要说的是 .NET 客户端应用,可以是只能在 Windows 端运行的基于 .NET Framework 或基于 .NET Core 的 WPF / Windows Forms 应用,也可以是其他基于 .NET Core 的跨平台应用。但是不是那些更新权限受到严格控制的 UWP / iOS / Android 应用。
walterlv
2023/10/22
2820
.NET 命令行参数包含应用程序路径吗?
发布于 2018-09-11 13:28 更新于 2018-09-13 03:24
walterlv
2018/09/18
5630
.NET 命令行参数包含应用程序路径吗?
C#/.NET基于Topshelf创建Windows服务的守护程序不显示UI界面的问题分析和解决方案
C#/.NET基于Topshelf创建Windows服务的守护程序作为服务启动的客户端桌面程序不显示UI界面的问题分析和解决方案
Rector
2019/05/25
1.4K0
如何在 .NET/C# 代码中安全地结束掉一个控制台应用程序?通过发送 Ctrl+C 信号来结束
我的电脑上每天会跑一大堆控制台程序,于是管理这些程序的运行就成了一个问题。或者说你可能也在考虑启动一个控制台程序来完成某些特定的任务。
walterlv
2023/10/22
1.6K0
如何在 .NET/C# 代码中安全地结束掉一个控制台应用程序?通过发送 Ctrl+C 信号来结束
C# Windows服务开发
我要开发一个系统服务,服务的作用是定时检测并关闭其他应用的弹窗,但是开发后却发现,服务在运行是压根获取不到任何窗口。
码客说
2022/05/23
1.3K0
C# Windows服务开发
在C#/.NET应用程序开发中创建一个基于Topshelf的应用程序守护进程(服务)
在上一篇文章《C#/.NET基于Topshelf创建Windows服务程序及服务的安装和卸载》中,我们了解发C#/.NET创建基于Topshelf Windows服务程序的大致流程,参数配置以及服务的安装和卸载。同时,我们也使用一个简单的定时任务演示了Topshelf服务的执行情况。
Rector
2020/06/19
2.2K0
.NET/C# 阻止屏幕关闭,阻止系统进入睡眠状态
在 Windows 系统中,一段时间不操作键盘和鼠标,屏幕便会关闭,系统会进入睡眠状态。但有些程序(比如游戏、视频和演示文稿)在运行过程中应该阻止屏幕关闭,否则屏幕总是关闭,会导致体验会非常糟糕。
walterlv
2023/10/22
1K0
.NET/C# 阻止屏幕关闭,阻止系统进入睡眠状态
在 Windows 系统上降低 UAC 权限运行程序(从管理员权限降权到普通用户权限)
在 Windows 系统中,管理员权限和非管理员权限运行的程序之间不能使用 Windows 提供的通信机制进行通信。对于部分文件夹(ProgramData),管理员权限创建的文件是不能以非管理员权限修改和删除的。
walterlv
2023/10/23
2.1K0
如何将应用程序与文件类型(文件扩展名)关联起来
自定义一个文件格式,如 .jgrass ,如何将这种文件格式与对应的程序关联起来? 或者,自己编写了一个可以打开 txt 格式的应用程序,怎么能够通过双击 txt 文件,直接打开这个自定义程序?
jgrass
2024/12/25
1200
如何将应用程序与文件类型(文件扩展名)关联起来
使用 PInvoke.net Visual Studio Extension 辅助编写 Win32 函数签名
2018-07-21 14:35
walterlv
2018/09/18
1.1K0
使用 PInvoke.net Visual Studio Extension 辅助编写 Win32 函数签名
将 async/await 异步代码转换为安全的不会死锁的同步代码
发布于 2018-03-16 03:58 更新于 2018-08-19 11:10
walterlv
2018/09/18
1.7K0
将 async/await 异步代码转换为安全的不会死锁的同步代码
如何创建应用程序清单文件 App.Manifest,如何创建不带清单的应用程序
如果你的程序对 Windows 运行权限有要求,那么需要设置应用程序清单。本文介绍如何添加应用程序清单,并解释其中各项权限设置的实际效果。
walterlv
2023/10/22
1.4K0
如何创建应用程序清单文件 App.Manifest,如何创建不带清单的应用程序
(2/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
发布于 2018-07-25 13:20 更新于 2018-07-28 11:50
walterlv
2018/09/18
1.3K1
(2/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
WPF 使用 AppBar 将窗口停靠在桌面上,让其他程序不占用此窗口的空间(附我封装的附加属性)
本文介绍如何使用 Windows 的 AppBar 相关 API 实现固定停靠在桌面上的特殊窗口。
walterlv
2023/10/22
1.1K0
WPF 使用 AppBar 将窗口停靠在桌面上,让其他程序不占用此窗口的空间(附我封装的附加属性)
如何在 .NET 库的代码中判断当前程序运行在 Debug 下还是 Release 下
发布于 2018-07-05 11:39 更新于 2018-09-01 00:00
walterlv
2018/09/18
1.8K0
WPF 跨应用程序域的 UI(Cross AppDomain UI)
发布于 2017-11-12 16:36 更新于 2017-11-13 15:04
walterlv
2018/09/18
1.2K0
WPF 跨应用程序域的 UI(Cross AppDomain UI)
[C# 开发技巧]如何防止程序多次运行
最近发现很多人在论坛中问到如何防止程序被多次运行的问题的,如: http://social.msdn.microsoft.com/Forums/zh-CN/6398fb10-ecc2-4c03-ab25-d03544f5fcc9, 所以这里就记录下来,希望给遇到同样问题的朋友有所参考的,同时也是对自己的一个积累。在介绍具体实现代码之前,我们必须明确解决这个问题的思路是什么的?下面只要分享我的一个思考的这个问题的方式:
乔达摩@嘿
2020/09/11
2K0
[C# 开发技巧]如何防止程序多次运行
如何在 ASP.NET MVC 中集成 AngularJS(3)
今天来为大家介绍如何在 ASP.NET MVC 中集成 AngularJS 的最后一部分内容。 调试路由表 - HTML 缓存清除 就在我以为示例应用程序完成之后,我意识到,我必须提供两个版本的路由表:一个运行在调试模式的应用程序下和一个运行在发布模式的应用程序下。在调试模式下,JavaScript 文件在未使用压缩功能的情况下会被下载。如果想要调试并在 JavaScript 控制器中设置断点,这是必须的。事实上,路由表的产生版本也出现了一些挑战,由于产生路由代码使用的是 JavaScript 捆绑,但是在
葡萄城控件
2018/01/10
1.9K0
如何在 ASP.NET MVC 中集成 AngularJS(3)
推荐阅读
WPF 基于 WER 注册应用崩溃无响应回调和重启方法
8370
.NET/C# 获取一个正在运行的进程的命令行参数
2.5K0
制作一个极简的 .NET 客户端应用自安装或自更新程序
2820
.NET 命令行参数包含应用程序路径吗?
5630
C#/.NET基于Topshelf创建Windows服务的守护程序不显示UI界面的问题分析和解决方案
1.4K0
如何在 .NET/C# 代码中安全地结束掉一个控制台应用程序?通过发送 Ctrl+C 信号来结束
1.6K0
C# Windows服务开发
1.3K0
在C#/.NET应用程序开发中创建一个基于Topshelf的应用程序守护进程(服务)
2.2K0
.NET/C# 阻止屏幕关闭,阻止系统进入睡眠状态
1K0
在 Windows 系统上降低 UAC 权限运行程序(从管理员权限降权到普通用户权限)
2.1K0
如何将应用程序与文件类型(文件扩展名)关联起来
1200
使用 PInvoke.net Visual Studio Extension 辅助编写 Win32 函数签名
1.1K0
将 async/await 异步代码转换为安全的不会死锁的同步代码
1.7K0
如何创建应用程序清单文件 App.Manifest,如何创建不带清单的应用程序
1.4K0
(2/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
1.3K1
WPF 使用 AppBar 将窗口停靠在桌面上,让其他程序不占用此窗口的空间(附我封装的附加属性)
1.1K0
如何在 .NET 库的代码中判断当前程序运行在 Debug 下还是 Release 下
1.8K0
WPF 跨应用程序域的 UI(Cross AppDomain UI)
1.2K0
[C# 开发技巧]如何防止程序多次运行
2K0
如何在 ASP.NET MVC 中集成 AngularJS(3)
1.9K0
相关推荐
WPF 基于 WER 注册应用崩溃无响应回调和重启方法
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验