UWP: 实现 UWP 应用自启动

简介: 原文:UWP: 实现 UWP 应用自启动在上一篇文章中,我们实现了使用命令行来启动 UWP 应用,在这一篇文章中,我们会实现 UWP 应用自启用的实现,也即开机后或用户登陆后,应用自己启动。这些特性原来都是 Win32 程序所具备的,UWP 能够支持这些特性使得它和 Win32 程序的行为进一步相同。
原文: UWP: 实现 UWP 应用自启动

上一篇文章中,我们实现了使用命令行来启动 UWP 应用,在这一篇文章中,我们会实现 UWP 应用自启用的实现,也即开机后或用户登陆后,应用自己启动。这些特性原来都是 Win32 程序所具备的,UWP 能够支持这些特性使得它和 Win32 程序的行为进一步相同。 

实现

与实现命令行启动一样,实现自启动也大体上分为两步:首先,在 Package.appxmanifest 中添加 windows.startupTask 扩展(Extension);然后,在 App 类中处理 OnActivated 事件。事实上,除了这两步外,我们还需要增加检查 StartupTask 的状态并允许用户控制自启动的逻辑。

1. 修改 Package.appxmanifest 

右击项目中的 Package.appxmanifest 文件,在快捷菜单中选择“打开方式“->”XML 文本编辑器“。打开后,对它的内容按以下修改:

<Package
  xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
  xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
  xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
  xmlns:uap5="http://schemas.microsoft.com/appx/manifest/uap/windows10/5"
  IgnorableNamespaces="uap mp uap5">
  ...
  <Applications>
    <Application 
      ...
      <Extensions>
        <uap5:Extension Category="windows.startupTask" EntryPoint="AppAutoRun.App" Executable="AppAutoRun.exe">
          <uap5:StartupTask DisplayName="AppAutoRun" Enabled="true" TaskId="AppAutoRun"/>
        </uap5:Extension>
      </Extensions>
    </Application>
  </Applications>
</Package>

上述加粗的部分就是添加的扩展 windows.startupTask,其 EntryPoint 和 Executable 属性分别指明 App 类的完整名称以及当前应用的 exe 名称。

在 Extension 节点中,添加了一个节点 StartupTask,它有三个属性,说明如下:

  • TaskId:任务Id,必填,在所有的 UWP 应用中,它必须是唯一的,不能和其它应用的 TaskId 相同;
  • Enabled:是否启用,必填,指明是否启用当前应用为自启动行为;
  • DisplayName:显示名称,可选,在“任务管理器”中“启动”选项卡中的显示名称;

需要说明的是,Enabled 属性应该设置为 false;事实上这个属性会被忽略;因为 UWP 要实现自启动,至少需要启动一次,并且向用户请求同意才行。另外目前只能添加一个 StartupTask 节点。

此时,可以将应用部署(Deploy)到本机上,然后,在“任务管理器”中“启动”选项卡上,我们就可以看到了。

这里,右击每个任务,可以对它的状态进行控制(启用/禁用),可以看到当前应用的状态是“已禁用”。注意,在设置它的状态之前,App 需要至少被启动过一次。否则这里的设置是不起作用的。

 2. 查看并更改任务状态

除了在 Package.appxmanifest 中增加扩展外,我们还需要使用相关的 API 来查看所添加的 StartupTask 的状态,以及对它的更改。在 MainPage.xaml 中增加以下代码:

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid Margin="12">
            <StackPanel>
                <TextBlock x:Name="tbState" />
                <Button
                    x:Name="btnSetState"
                    Margin="0,4,0,0"
                    Click="btnSetState_Click" />
            </StackPanel>
        </Grid>
    </Grid>

在 MainPage.xaml.cs 中增加以下代码:

        private async void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            await LoadState();
        }

        public async Task LoadState()
        {
            var task = await StartupTask.GetAsync("AppAutoRun");
            this.tbState.Text = $"Status: {task.State}";
            switch (task.State)
            {
                case StartupTaskState.Disabled:
                    // 禁用状态
                    this.btnSetState.Content = "启用";
                    this.btnSetState.IsEnabled = true;
                    break;
                case StartupTaskState.DisabledByPolicy:
                    // 由管理员或组策略禁用
                    this.btnSetState.Content = "被系统策略禁用";
                    this.btnSetState.IsEnabled = false;
                    break;
                case StartupTaskState.DisabledByUser:
                    // 由用户手工禁用
                    this.btnSetState.Content = "被用户禁用";
                    this.btnSetState.IsEnabled = false;
                    break;
                case StartupTaskState.Enabled:
                    // 当前状态为已启用
                    this.btnSetState.Content = "已启用";
                    this.btnSetState.IsEnabled = false;
                    break;
            }
        }

        private async void btnSetState_Click(object sender, RoutedEventArgs e)
        {
            var task = await StartupTask.GetAsync("AppAutoRun");
            if (task.State == StartupTaskState.Disabled)
            {
                await task.RequestEnableAsync();
            }

            // 重新加载状态
            await LoadState();
        }

我们通过 StartupTask 类(位于 Windows.ApplicationModel 命名空间下)的 GetAsync 来获取指定 TaskId 的自启动任务(StartupTask)。StartupTask 类具有一个 State 的枚举属性,用于表示其状态。它们的值及其意义,在注释中已经说明。

补充说明以下几点:

  1. 最开始时,任务的 State 是 Disabled;
  2. 唯有当其 State 是 Disabled 时,才能以编程的方式使用启动;
  3. 当其 State 是 DisabledByUser 或 DisabledByPolicy,需要经由用户手工启动;
  4. 不支持以编程的方式使其 State 成为 Disabled;

通过 StartupTask 类的 RequestEnableAsync 方法,可以向用户请求将其启动,调用这个方法后,会弹出如下窗口:

当用户选择“启用”后,下次系统启动后它就会自动启动,反之,如果选择”禁用“,那么它的状态会是 DisabledByUser。要想启用它,就需要打开”任务管理器“,在”启动“选项卡上右击它,选择“启用”。

3. 处理 OnActivated 事件

然后,在 App 类的 OnActivated 事件上增加对 ActivationKind 类的判断,并作相应的处理即可。代码如下:

        protected override void OnActivated(IActivatedEventArgs args)
        {
            Frame rootFrame = Window.Current.Content as Frame;
            if (rootFrame == null)
            {
                rootFrame = new Frame();
                Window.Current.Content = rootFrame;
            }
            
            if (args.Kind == ActivationKind.StartupTask)
            {
                var startupArgs = args as StartupTaskActivatedEventArgs;
            }

            rootFrame.Navigate(typeof(MainPage), args.Kind);
            Window.Current.Activate();
        }

最后,要注意的是:如果启用了自启动,当系统启动后,应用会以最小化的方式启动。 

参考资料:

Configure your app to start at log-in

目录
相关文章
|
消息中间件 SQL Kafka
Flink CPU问题之CPU利用率低如何解决
Apache Flink是由Apache软件基金会开发的开源流处理框架,其核心是用Java和Scala编写的分布式流数据流引擎。本合集提供有关Apache Flink相关技术、使用技巧和最佳实践的资源。
|
数据可视化 定位技术 Python
【100天精通Python】Day68:Python可视化_Matplotlib 绘制热力图,示例+代码
【100天精通Python】Day68:Python可视化_Matplotlib 绘制热力图,示例+代码
2766 0
|
3月前
|
敏捷开发 人工智能 监控
任务反馈闭环管理:打造高效执行力的17个关键环节全解析
任务反馈闭环管理是一种确保任务从布置到完成全过程信息透明的管理方法,其核心是通过"计划-执行-反馈-改进"的完整循环,解决传统管理中常见的"任务黑洞"问题。这种机制强调责任明确、流程标准化、反馈及时和持续优化,能够显著提升执行力、团队协同效率和组织的敏捷性。关键环节包括SMART目标设定、标准化执行流程、量化反馈机制和PDCA持续改进。有效的闭环管理需要制度设计、工具支持和流程优化的协同配合,并通过五大KPI(任务完成率、反馈及时率等)进行量化评估。实施闭环管理虽面临员工适应、流程复杂等挑战,但数字化转型和智能化工具的应用正推动其向更高效的方向发展。闭环管理不仅是提升效率的工具,更是促进组织持
326 0
|
Ubuntu 开发工具 git
ESP32-C3 VScode开发环境搭建(基于ESP-IDF—Windows和Ubuntu双环境)
对于ESP32-C3开发,自己对Arduino环境使用起来很是不习惯,既然乐鑫官方都出对应的环境,还是来试试官方环境
3213 0
ESP32-C3 VScode开发环境搭建(基于ESP-IDF—Windows和Ubuntu双环境)
|
SQL 分布式计算 大数据
一张图,详解大数据技术架构
一张图,详解大数据技术架构
|
11月前
|
存储 Linux 数据安全/隐私保护
一键部署 200+ 开源Github 2k+ 星星的软件
Websoft9面板是一款基于Web的PaaS/Linux面板,支持在个人服务器上一键部署200多种热门开源应用,适用于个人开发者、中小企业、创业团队、教育机构和技术爱好者。它集成了丰富的开源软件,提供便捷的部署方式、高效的资源利用、良好的可扩展性及低技术门槛,帮助用户快速搭建和管理各类应用。
|
Web App开发 测试技术 项目管理
【Docker项目实战】使用Docker部署Servas自托管书签管理工具
【6月更文挑战第5天】使用Docker部署Servas自托管书签管理工具
326 1
【Docker项目实战】使用Docker部署Servas自托管书签管理工具
|
网络架构
问题解决:启动Gazebo出现Error in REST request报错的问题
问题解决:启动Gazebo出现Error in REST request报错的问题
300 0
西门子S7-200 SMART全局变量和局部变量如何使用,编写带参数子程序并调用
上篇文章中我们学习了西门子S7-200 SMART项目的编译、下载、运行调试及上传,本篇我们来介绍西门子S7-200 SMART的全局变量和局部变量如何使用,以及如何在编程软件STEP7-Micro/WIN SMART中编写带参数子程序并调用。我们先来介绍一下什么是全局变量和局部变量。符号表中定义的变量又称为全局变量,在所有的POU中都有效,在变量表中定义的变量称为局部变量,只在创建它的POU内部有效。
西门子S7-200 SMART全局变量和局部变量如何使用,编写带参数子程序并调用