1. 程式人生 > >UWP: 實現 UWP 應用自啟動

UWP: 實現 UWP 應用自啟動

button mes config 至少 編輯 current blank 參考 navigate

原文: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

UWP: 實現 UWP 應用自啟動