Windows 10 UWP 36 of N: 1709 (FCU)面向desktop environment的啟動功能

  • 298
  • 0
  • UAP
  • 2021-04-30

幾點功能簡介在1709 (FCU) SDK上,偏向UWP on desktop

在Fall Creator Update的SDK上介紹了幾點很有趣的功能,今天要介紹的就是兩點

  1.  Startup Task
  2. Commandline execution

基本上這兩項功能都是針對 desktop environment而來的,所以不需要額外加入Extension到 Reference中!讓我們直接進入demo八


Startup Task

這個功能基本上就是在device boot(開機或是登入)的時候啟動的應用程式,當然這個功能在Win32上就已經很常看的到。在UWP就分成兩種宣告來使用!一個就是使用原生的UWP 宣告另外一個就是給Desktop bridge的宣告。這邊直接來看Package.manifest的部份八

<?xml version="1.0" encoding="utf-8"?>

<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"
  xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
  IgnorableNamespaces="uap uap5 desktop mp">

  <Dependencies>
    <TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
  </Dependencies>

  <Resources>
    <Resource Language="x-generate"/>
  </Resources>

  <Applications>

      <Extensions>
<!-- for pure UWP app -->
        <uap5:Extension Category="windows.startupTask" Executable="$targetnametoken$.exe" EntryPoint="$targetnametoken$.App">
          <uap5:StartupTask TaskId="PureUWPStartupTaskId" Enabled="false" DisplayName="PureUWPStartupTask"/>
        </uap5:Extension>
<!-- for desktopbridge app -->
      <desktop:Extension Category="windows.startupTask" Executable="$targetnametoken$.exe" EntryPoint="$targetnametoken$.App" >
        <desktop:StartupTask TaskId="DeskBridgeUWPStartupTaskId" Enabled="false" DisplayName="DeskBridgeUWPStartupTask"/>
      </desktop:Extension>
      </Extensions>

    </Application>
  </Applications>

</Package>
這邊需要注意到的是 startup task是只有在desktop device form的Windows 10裝置上才能使用的功能!而在Iot Core上早已經實現該功能(Iot Core開機完成的UI就是個UWP app)而在 TargetDeviceFamily可以修改成 Windows.Desktop讓宣告上更加直接在package上直接區分給Desktop device form. 而外需要注意的是TaskId需要用在API上

這邊宣告完成就可以deploy到device上,就會如下圖所示(一個Package可以支援多個StartupTask,但是TaskId需要是唯一值)

接下來就是寫Code來request啟用startup task了!如下C# code所示

public class StartupTaskHelper
    {
        private StartupTask task;
        private IReadOnlyList<StartupTask> tasks;

        public async Task RequestStarupTaskAsync(string taskId)
        {
            if (!ApiInformation.IsApiContractPresent(typeof(UniversalApiContract).Name, 5, 0))
            {
                throw new PlatformNotSupportedException("FCU or later");
            }

            if (string.IsNullOrEmpty(taskId) || string.IsNullOrWhiteSpace(taskId))
            {
                throw new ArgumentException(nameof(taskId));
            }

            try
            {
                task = await StartupTask.GetAsync(taskId);
                switch (task.State)
                {
                    case StartupTaskState.Enabled:
                        break;
                    default:
                    case StartupTaskState.Disabled:
                        await task?.RequestEnableAsync();
                        break;
                    case StartupTaskState.DisabledByPolicy:
                    case StartupTaskState.DisabledByUser:
                        break;
                }
            }
            catch (UnauthorizedAccessException uEx)
            {
                System.Diagnostics.Debug.WriteLine(uEx.Message);
                throw uEx;
            }
        }

        public async Task RequestStarupTasksAsync(string taskId)
        {
            if (!ApiInformation.IsApiContractPresent(typeof(UniversalApiContract).Name, 5, 0))
            {
                throw new PlatformNotSupportedException("FCU or later");
            }

            if (string.IsNullOrEmpty(taskId) || string.IsNullOrWhiteSpace(taskId))
            {
                throw new ArgumentException(nameof(taskId));
            }

            try
            {
                tasks = await StartupTask.GetForCurrentPackageAsync();
                task = tasks.SingleOrDefault(i => i.TaskId.Equals(taskId));
                switch (task.State)
                {
                    case StartupTaskState.Enabled:
                        break;
                    default:
                    case StartupTaskState.Disabled:
                        await task?.RequestEnableAsync();
                        break;
                    case StartupTaskState.DisabledByPolicy:
                    case StartupTaskState.DisabledByUser:
                        break;
                }
            }
            catch (UnauthorizedAccessException uEx)
            {
                System.Diagnostics.Debug.WriteLine(uEx.Message);
                throw uEx;
            }
        }

        public void DisableStartupTask()
        {
            task.Disable();
        }

        public async Task DisableStartupTaskAsync(string taskId)
        {
            if (string.IsNullOrEmpty(taskId) || string.IsNullOrWhiteSpace(taskId))
            {
                throw new ArgumentException(nameof(taskId));
            }

            try
            {
                tasks = await StartupTask.GetForCurrentPackageAsync();
                tasks.SingleOrDefault(i => i.TaskId.Equals(taskId))?.Disable();
            }
            catch (UnauthorizedAccessException uEx)
            {
                System.Diagnostics.Debug.WriteLine(uEx.Message);
                throw uEx;
            }
        }
    }

這邊很簡單的只需要使用 StartupTask配上taskid就可以變更狀態成 enable or disable。


Commandline execution

這個功能更加偏向開發人員!這個功能就是可以使用 commandline or powershell指令的方式來啟動UWP app,當然因為使可以使用commandline的方式所以一樣可以帶而外參數到app中。需要修改Package.manifest的部分如下

<?xml version="1.0" encoding="utf-8"?>

<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 uap5 mp">

  <Identity
    Name="693b125e-d51d-4522-bf7d-571a95d0fca8"
    Publisher="CN=Richie"
    Version="1.0.0.0" />

  <mp:PhoneIdentity PhoneProductId="693b125e-d51d-4522-bf7d-571a95d0fca8" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>

  <Properties>
    <DisplayName>xBindSample</DisplayName>
    <PublisherDisplayName>Richie</PublisherDisplayName>
    <Logo>Assets\StoreLogo.png</Logo>
  </Properties>

  <Dependencies>
    <TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
  </Dependencies>

  <Resources>
    <Resource Language="x-generate"/>
  </Resources>

  <Applications>
    <Application Id="App"
      Executable="$targetnametoken$.exe"
      EntryPoint="xBindSample.App">
      <uap:VisualElements
        DisplayName="xBindSample"
        Square150x150Logo="Assets\Square150x150Logo.png"
        Square44x44Logo="Assets\Square44x44Logo.png"
        Description="xBindSample"
        BackgroundColor="transparent">
        <uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png"/>
        <uap:SplashScreen Image="Assets\SplashScreen.png" />
      </uap:VisualElements>

      <Extensions>
<!-- commandline execution feature -->
        <uap5:Extension Category="windows.appExecutionAlias" Executable="xBindSample.exe" EntryPoint="xBindSample.App">
          <uap5:AppExecutionAlias>
            <uap5:ExecutionAlias Alias="CMDUWP.exe"/>
          </uap5:AppExecutionAlias>
        </uap5:Extension>
      </Extensions>

    </Application>
  </Applications>

  <Capabilities>
    <Capability Name="internetClient" />
  </Capabilities>
</Package>

這邊要加入的一樣是在uap5下的 windows.appExecutionAlias,這邊有趣的事是需要設定ExecutionAlias!這邊的條件就是必須是.exe為結尾的字串名稱。

執行畫面如下

這邊一樣需要override OnActivated在App.xaml.cs再去判斷 ActivationKind 是否為CommandLineLaunch。在強轉型 IActivatedEventArgs 成 CommandLineActivatedEventArgs就可以取得在commandline下所帶入的operation了!

如果需要簡單加入該功能可以安裝Visual studio 2017的Project Template ( https://marketplace.visualstudio.com/items?itemName=AndrewWhitechapelMSFT.CommandLine-ActivatedWindowsApp

 

 

總結~

加入了startup task以及commandline execution比較偏向LOB(Enterprise)的功能,UWP依然在演進到更多Win32所支援的功能!也期待更多有趣的應用和功能實作出現。

 

***以上Code以及說明都有可能隨著Windows 10 的版本以及Visual Studio 版本有所調整!***

參考資料 Microsoft Docs,Windows Blogs for developer

下次再分享Windows 10 的新技術拉~