• Windows Vista 开发新特性(1) 有关重启管理器 Restart Manager


     (这段时间在Vista兼容性讲座以及后续的支持过程中积累了一些东西,很希望和大家分享,这篇文章就作一个开头吧,我会在近期陆续发一些Vista开发相关的内容。)

    自从我们开始使用计算机开始,重新启动就一直是我们用来“解决问题”的最后纺线,应用程序的更新更是如此,很多的问题都因为从新启动而变得简单。但是随着我们用的系统变得复杂,重新启动也变得越来越让人无法接受,你可以想象一下需要关闭20个窗口然后等待10分钟来启动所有的系统服务的感觉吗?而你所更新的可能仅仅是媒体播放器的一个小小的bug。
    Windows系统更新
    可能很多人都已经注意到了微软的Windows更新系统的新功能,它可以允许你延迟从新启动的操作,比如下图:
    Figure:我们可以仅仅点击关闭,而过后再重启

    Figure:Vista中的系统更新提示
    Figure:Vista中的系统自动更新正在下载和安装更新包
    这个功能让的我们的系统更新变得人性化,我们不用在受电脑的胁迫而去做我们不原意的重启了。
    重启管理器的主要功能
    但是,如果我们的更新更加智能化一下,可以自动的关闭我们正在运行的应用程序,并且在更新完成以后自动的启动它,那不是更好吗?重启管理器就是为了实现这样的功能而设计的。
    先看一下我们如果使用了重启管理器会有怎样的效果。假设你在下班之前没有完成一个文档,把写了一半的文件留在了屏幕上;那么如果半夜里Word 2007需要进行更新,那么Vista系统就会调用重启管理器来通知Word 2007做安全关闭动作,当支持重启管理器的Word 2007收到安全关闭的消息的时候,它会自动将未完成的文档保存并关闭自己的所有窗口;当更新完成以后,重启管理器就会通知Word 2007启动并会协助其恢复原来的状态;不仅仅包括未完成的文档,还包括窗口的位置,光标的位置等所有和用户使用环境相关的内容。
    同时,在我们设计更新程序的安装包的时候我们也可以调用重启管理器的API来向应用程序发出关闭和重启消息。

    Figure:使用了重启管理器API的安装包会给出友好的提示
    我们可以很明显的看到,重启管理器可以帮助我们提升用户在更新应用程序的过程中的体验,基本上用户的工作过程不会被更新程序打扰,而可以专注于自己正在处理的工作。
    如何实现重启管理器的功能
    Windows Vista系统已经内置了对重启管理器的支持,系统可以在安装更新包之前自动的向应用程序发出关闭消息,并在安装完成以后发出启动消息。我们的应用程序需要做的事情就是相应这些消息并作出争取的处理。
    1.注册支持重启管理器
    NativeMethods.RegisterApplicationRestart(
                        commandLineReturnValue, //用来唯一标识当前状态的主键
                 0);
          [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            internal static extern uint RegisterApplicationRestart(
                string pszCommandline,
                int dwFlags);
     
    上面所列的是c#代码实现的RegisterApplicationRestart API的调用,RegisterApplicationRetart是用来注册当前应用程序的系统API,调用之后,系统就知道这个应用程序会支持重启管理器的功能;在注册的同时我们还可以传送一个参数commandLineRetureValue,这个参数在后面会被重启管理器作为命令行参数返回给应用程序。
     
    2.响应ENDSESSION_CLOSEAPP系统消息
            //private const int ENDSESSION_LOGOFF = 0x8;
            private const int WM_QUERYENDSESSION = 0x0011;
            private const int ENDSESSION_CLOSEAPP = 0x1;
     
            protected override void WndProc(ref Message m)
            {
               base.WndProc(ref m);
     
               if (m.Msg == WM_QUERYENDSESSION)
               {
                   if (m.LParam.ToInt32() == ENDSESSION_CLOSEAPP)
                   {
                       //这里我们可以保存应用程序的状态
                   }
               }
     }
    这段代码中我们首先定义了系统消息的静态值,然后使用一个标准的系统消息响应方法来检查我们收到的消息是否来自重启管理器;如果是的话,那么我们就需要对应用程序状态进行保存,比如可以使用文件,序列化,甚至数据库进行存储。
     
    3.测试启动参数,并恢复应用程序状态
    private void Form1_Load(object sender, EventArgs e)
            {
                string[] args = Environment.GetCommandLineArgs();
                if (args.Length > 1)
                {
                    String commandLineReturnValue = args[1];
                      //开始恢复应用程序状态
                }
     }
     
    应用程序如果是被重启管理器启动的话,那么我们可以在第二个命令行参数中获得我们当初注册的时候传入的那个参数,借助这个参数我们就可以进行程序的重新启动。
     
    我们可以看到,实际上重启管理器只是定义了一个API用来注册应用程序,和一个系统消息来通知应用程序重启;其他的工作都需要我们的开发人员来自己实现,这可能让我们有点失望,但也是可以理解的,因为系统并不知道那些程序状态是重要的,必须要恢复的;这些应该是开发人员的责任。
     
    另外还有两点很重要的内容,我们在实现重启管理器的时候需要注意:
    1)重启管理器的API只有在Vista的kernel32.dll中才有,所以如果你的应用程序需要提供支持,那么必须在Vista上进行编译;
    2)为了保证我们的应用程序可以在xp及一下系统上正常运行,一定要在调用RegisterApplicationRestart之前检查系统版本,比如使用Environment.OsVersion或者GetVersionEx API,只有当版本号大于6.0.6000的时候才进行调用,否则会造成崩溃。
     
     
    资源:
    1)重启管理器演示程序,RestartManagerController, RestartManagerListner (如果需要请给我发信)
     
     
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    internet连接共享被启用时 出现了一个错误 (null)
    mybatis01-1测试
    配置没有问题,虚拟机Ubuntu系统ifconfig没有网卡信息
    Ubuntu启动Apache
    VM虚拟机Linux系统eth0下面没有inet和inet6
    jQuery通过id和name获取值的区别
    1.4.3 ID遍历爬虫(每天一更)
    mysql中的SQL语句执行的顺序
    Mecanim动画系统丶
    html中常见的行内元素和块级元素,还有常见的行内块元素
  • 原文地址:https://www.cnblogs.com/wuyida/p/6300192.html
Copyright © 2020-2023  润新知