建立託管應用程式

從 Windows 10 版本 2004 開始,你可以建立託管應用程式託管應用程式與上層主機應用程式共享相同的可執行檔和定義,但它的外觀和行為類似於系統上的單獨應用程式。

裝載的應用程式適用於您想要元件 (例如可執行檔或指令碼檔案) 行為類似獨立 Windows 10 應用程式,但元件需要主機處理序才能執行的情況。 例如,PowerShell 或 Python 指令碼可以傳遞為需要安裝主機才能執行的託管應用程式。 裝載的應用程式可以有自己的開始磚、身分識別,以及與 Windows 10 功能 (例如背景工作、通知、磚和共用目標) 的深度整合。

託管應用程式功能由套件清單中的多個元素和屬性支持,這些元素和屬性使託管應用程式能夠使用主機應用程式套件中的可執行檔和定義。 當使用者執行裝載的應用程式時,OS 會自動在託管應用程式的身分識別下啟動主機可執行檔。 然後,主機可以載入視覺資產、內容或呼叫 API 作為託管應用程式。 託管應用程式取得主機和託管應用程式之間聲明的功能的交集。 這代表託管應用程式不能要求比主機提供的功能更多的功能。

定義主機

主機是託管應用程式的主要可執行檔或執行時程序。 目前,唯一支援的主機是具有套件標識的桌面應用程式 (.NET 或 C++ 桌面)。 桌面應用程式可以透過多種方式獲得包標識:

主機由 uap10:HostRuntime 擴充在其套件清單中聲明。 此延伸模組具有一個 Id 屬性,必須為其指派一個值,該值也由託管應用程式的套件清單引用。 啟動託管應用程式後,主機將以託管應用程式的身份啟動,並且可以從託管應用程式套件載入內容或二進位檔案。

以下範例示範如何在套件清單中定義主機。 uap10:HostRuntime 延伸模組是套件範圍的,因此被宣告為 Package 元素的子元素。

<Package xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10">

  <Extensions>
    <uap10:Extension Category="windows.hostRuntime"  
        Executable="PyScriptEngine\PyScriptEngine.exe"  
        uap10:RuntimeBehavior="packagedClassicApp"  
        uap10:TrustLevel="mediumIL">
      <uap10:HostRuntime Id="PythonHost" />
    </uap10:Extension>
  </Extensions>

</Package>

記下有關以下元素的重要細節。

Element 詳細資料
uap10:Extension windows.hostRuntime 類別聲明了一個套件範圍的延伸模組,該延伸模組定義了啟動託管應用程式時要使用的執行時間資訊。 託管應用程式將使用延伸模組中聲明的定義執行。 當使用上一個範例中聲明的主機應用程式時,託管應用程式將作為可執行檔 PyScriptEngine.exemediumIL 執行。

Executableuap10:RuntimeBehavioruap10:TrustLevel 屬性指定套件中主機程序二進位檔案的名稱以及託管應用程式的運作方式。 例如,使用上一範例中的屬性的託管應用程式將作為中等信任等級的可執行 PyScriptEngine.exe 執行。
uap10:HostRuntime Id 屬性聲明包中此特定主機應用程式的唯一識別碼。 一個套件可以有多個主機應用程式,並且每個應用程式都必須有一個具有唯一 Iduap10:HostRuntime 元素。

宣告裝載的應用程式

託管應用程式聲明對主機的套件依賴關係。 託管應用程式利用主機的 Id (即主機套件中 uap10:HostRuntime 延伸模組的 Id 屬性) 進行啟動,而不是在其自己的包中指定入口點可執行檔。 託管應用程式通常包含主機可以存取的內容、視覺資產、指令碼或二進位檔案。 託管應用程式套件中的 TargetDeviceFamily 值應與主機的目標值相同。

託管應用程式套件可以簽名或未簽署:

  • 簽署的套件可能包含可執行檔。 這在具有二進制延伸模組機制的場景中非常有用,該機制使主機能夠加載託管應用程式包中的 DLL 或註冊元件。
  • 在大多數情況下,未簽署的套件將包含可執行內容。 但是,僅包含非執行檔案的未簽名包在主機只需要載入映像、資產和內容或指令碼檔案的情況下非常有用。 未簽署的套件必須在其 Identity 元素中包含特殊 OID 值,否則將不允許它們註冊。 這可以防止未簽署的包與已簽署的套件發生衝突或欺騙已簽名的套件身份。

若要定義託管應用程式,請在套件清單中聲明以下項目:

下列範例示範未簽署裝載應用程式之套件指令清單的相關區段。

<Package xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10">

  <Identity Name="NumberGuesserManifest"
    Publisher="CN=AppModelSamples, OID.2.25.311729368913984317654407730594956997722=1"
    Version="1.0.0.0" />

  <Dependencies>
    <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.19041.0" MaxVersionTested="10.0.19041.0" />
    <uap10:HostRuntimeDependency Name="PyScriptEnginePackage" Publisher="CN=AppModelSamples" MinVersion="1.0.0.0"/>
  </Dependencies>

  <Applications>
    <Application Id="NumberGuesserApp"  
      uap10:HostId="PythonHost"  
      uap10:Parameters="-Script &quot;NumberGuesser.py&quot;">
    </Application>
  </Applications>

</Package>

記下有關以下元素的重要細節。

Element 詳細資料
身分識別 由於本範例中的託管應用程式套件未簽名,因此 Publisher 屬性必須包含 OID.2.25.311729368913984317654407730594956997722=1 字串。 這可確保未簽署的套件無法欺騙已簽署套件的身份。
TargetDeviceFamily MinVersion 屬性必須指定 10.0.19041.0 或更新版本的 OS 版本。
uap10:HostRuntimeDependency 此元素聲明對主機應用程式套件的依賴關係。 這由主機套件的名稱發布者以及它所依賴的 MinVersion 組成。 您可以在主機套件的 Identity 元素下找到這些值。
應用程式 uap10:HostId 屬性表示主機上的相依性。 託管應用程式套件必須聲明此屬性,而不是應用程式延伸模組的常見 ExecutableEntryPoint 屬性。 因此,託管應用程式從具有對應 HostId 值的主機繼承 ExecutableEntryPoint 和執行時間屬性。

uap10:Parameters 屬性會指定傳遞至主機可執行檔進入點函式的參數。 由於主機必須知道如何使用這些參數,因此主機與託管應用程式之間會有隱含的合約。

在執行時間註冊未簽署的託管應用程式套件

uap10:HostRuntime 延伸模組的優點之一是,它使主機能夠在執行時間動態產生託管應用程式套件並使用 PackageManager API 進行註冊,而無需對其進行簽署。 這可讓主機動態產生託管應用程式套件的內容和指令清單,然後加以註冊。

使用 PackageManager 類別的以下方法來註冊未簽署的託管應用程式套件。 這些方法從 Windows 10 版本 2004 開始可用。

  • AddPackageByUriAsync:使用 options 參數的 AllowUnsigned 屬性註冊未簽署的 MSIX 套件。
  • RegisterPackageByUriAsync:執行鬆散的套件指令清單檔案註冊。 如果套件已簽名,則包含清單的資料夾必須包含 .p7x 檔案和目錄。 如果無符號,則必須設定選項參數的 AllowUnsigned 屬性。

未簽署託管應用程式的需求

  • 套件清單中的應用程式擴充元素不能包含啟動資料,例如 ExecutableEntryPointTrustLevel 屬性。 相反,這些元素只能包含表示對主機的依賴關係的 uap10:HostId 屬性和 uap10:Parameters 屬性。
  • 套件必須是主要套件。 它不能是套件組合、架構套件、資源或選擇性套件。

安裝及註冊未簽署託管應用程式套件之主機的需求

範例

對於將自身聲明為主機,然後在執行時動態註冊託管應用程式套件的功能齊全的範例應用程式,請參閱託管應用程式範例

主機

主機名為 PyScriptEngine。 這是一個用 C# 寫的包裝器,執行 python 指令碼。 使用 -Register 參數執行時,指令碼引擎會安裝包含 python 指令碼的託管應用程式。 當使用者嘗試啟動新安裝的託管應用程式時,會啟動主機並執行 NumberGuesser Python 指令碼。

主機應用程式的套件清單 (PyScriptEnginePackage 資料夾中的 Package.appxmanifest 檔案) 包含 uap10:HostRuntime 延伸模組,該延伸模組將應用程式聲明為具有 ID PythonHost 和可執行 PyScriptEngine.exe 的主機。

注意

在此範例中,套件清單名為 Package.appxmanifest,它是 Windows 應用程式套件專案的一部分。 產生此專案時,它會產生一個名為 AppxManifest.xml 的清單,並為主機應用程式產生 MSIX 套件。

託管應用程式

託管應用程式由 python 指令碼和套件工件 (例如套件清單) 組成。 它不包含任何 PE 檔案。

託管應用程式的套件清單 (NumberGuesser/AppxManifest.xml 檔案) 包含以下項目:

  • Identity 元素的 Publisher 屬性包含 OID.2.25.311729368913984317654407730594956997722=1 標識符,這是未簽名套件所必需的。
  • Application 元素的 uap10:HostId 屬性將 PythonHost 標識為其主機。

執行範例

此範例需要 10.0.19041.0 版或更新版本的 Windows 10 和 Windows SDK。

  1. 範例下載到開發電腦上的資料夾。

  2. 在 Visual Studio 中開啟 PyScriptEngine.sln 解決方案,並將 PyScriptEnginePackage 專案設定為啟動專案。

  3. 建置 PyScriptEnginePackage 專案。

  4. 在解決方案資源管理器中,右鍵點選 PyScriptEnginePackage 專案並選擇部署部署。

  5. 開啟命令提示字元視窗到複製範例檔案的目錄,然後執行以下命令來註冊範例 NumberGuesser 應用程式 (託管應用程式)。 變更 D:\repos\HostedApps 為您複製範例檔案的路徑。

    D:\repos\HostedApps>pyscriptengine -Register D:\repos\HostedApps\NumberGuesser\AppxManifest.xml
    

    注意

    您可以在命令列上執行 pyscriptengine,因為範例中的主機聲明了 AppExecutionAlias

  6. 打開開始功能表並點擊 NumberGuesser 以執行託管應用程式。