共用方式為


適用於在外部位置進行封裝或未封裝之架構相依應用程式的 Windows 應用程式 SDK 部署指南 (機器翻譯)

本主題提供部署使用外部位置封包或非封包且使用 Windows 應用 SDK 的應用程式的指南。

  • 這類應用程式是傳統型應用程式(而非 UWP 應用程式)。
  • 它們可以以 .NET 語言撰寫,例如 C# 或 C++。
  • 針對其使用者介面,他們可以使用 WinUI 3、WPF 或 WinForms 或其他 UI 架構。

概觀

具有外部位置的封包應用程式和未封包應用程式的開發人員負責向最終使用者部署所需的 Windows 應用程式 SDK 執行時間套件。 這可以透過執行安裝程式或直接安裝 MSIX 套件來完成。 下面的部署 Windows 應用程式 SDK 執行時間部分更詳細地描述了這些選項。

使用外部位置和未封包的應用程式進行封裝,也有額外的執行時間需求。 您必須使用 Bootstrapper API 初始化對 Windows 應用程式 SDK 執行時期的存取。 此外,如果您的應用程式使用 Windows 應用程式 SDK 以外的其他架構套件,則可以使用動態相依性 API。 下面的使用外部位置封包或非封包的應用程式的執行時要求部分更詳細地描述了這些要求。

必要條件

其他必要條件

  • 實驗預覽版本的 Windows 應用程式 SDK 需要啟用側載才能安裝執行時間。
    • Windows 10 版本 2004 及更高版本上會自動啟用側載。

    • 如果您的開發電腦或部署電腦執行的是 Windows 11,請確認是否啟用側載:

      • 設定>隱私權&安全性>專為開發人員打造。 確定開發人員模式設定已開啟。
    • 如果您的開發電腦或部署電腦執行的是 Windows 10 版本 1909 或更早版本,請確認是否啟用旁加載:

      • 設定>更新&安全性>專為開發人員打造>使用開發人員功能。 確認選擇了側載應用程式開發人員模式
    • 開發者模式設定包括側載以及其他功能。

      注意

      如果電腦在企業環境中進行管理,則可能存在阻止更改這些設定的策略。 在此情況下,如果您在或應用程式嘗試安裝 Windows 應用程式 SDK 執行時間時收到錯誤,請連絡 IT 專業人員以啟用側載或開發人員模式

部署 Windows 應用程式 SDK 執行時間

使用外部位置封包和非封包的應用程式有兩個選項來部署 Windows 應用程式 SDK 執行時間:

  • 選項 1:使用安裝程式:無訊息安裝程式會散發所有 Windows 應用程式 SDK MSIX 套件。 每個 X64X86Arm64 架構都有一個單獨的安裝程式。
  • 選項 2:直接安裝套件:您可以讓現有的安裝或 MSI 工具攜帶並安裝 Windows 應用程式 SDK 的 MSIX 套件。

選項 1:使用安裝程式

您可以透過執行安裝程式來部署所有 Windows 應用程式 SDK 執行時間套件。 該安裝程式可從 Windows 應用程式 SDK 下載中取得。 執行安裝程式 (.exe) 時,您應該會看到類似以下內容的輸出:

Deploying package: Microsoft.WindowsAppRuntime.1.0_0.318.928.0_x64__8wekyb3d8bbwe
Package deployment result : 0x0

Deploying package: Microsoft.WindowsAppRuntime.1.0_0.318.928.0_x86__8wekyb3d8bbwe
Package deployment result : 0x0

Deploying package: MicrosoftCorporationII.WindowsAppRuntime.Main.1.0_0.318.928.0_x64__8wekyb3d8bbwe
Package deployment result : 0x0
Provisioning result : 0x0

Deploying package: Microsoft.WindowsAppRuntime.Singleton_0.318.928.0_x64__8wekyb3d8bbwe
Package deployment result : 0x0
Provisioning result : 0x0

Deploying package: Microsoft.WinAppRuntime.DDLM.0.318.928.0-x6_0.318.928.0_x64__8wekyb3d8bbwe
Package deployment result : 0x0
Provisioning result : 0x0

Deploying package: Microsoft.WinAppRuntime.DDLM.0.318.928.0-x8_0.318.928.0_x86__8wekyb3d8bbwe
Package deployment result : 0x0
Provisioning result : 0x0

All install operations successful.

您可以在沒有使用者互動的情況下執行安裝程式,並使用 --quiet 選項抑制所有文字輸出:

WindowsAppRuntimeInstall.exe --quiet

你也可以選擇使用該 --force 選項強制更新 MSIX 套件並關閉任何目前正在執行的 Windows 應用程式 SDK 進程。 此功能在 1.1 中引入。

WindowsAppRuntimeInstall.exe --force

若要查看所有安裝程式命令列選項,請執行 WindowsAppRuntimeInstall --h

安裝完成後,您可以使用外部位置執行封包的應用程式或非封包的應用程式。 有關如何建置和執行使用 Windows 應用程式 SDK 的使用外部位置打包或未打包的應用程式的範例,請參閱教學課程:在使用外部位置打包或使用 Windows 應用程式 SDK 的未打包應用程式中使用引導程式 API

將 Windows 應用程式 SDK 安裝程式連結到應用程式的設定

如果您的應用程式有自訂安裝程序,則可以將 Windows 應用程式 SDK 安裝過程連結到應用程式的安裝過程中。 Windows 應用程式 SDK 安裝程式目前不提供預設 UI,因此您需要使用安裝程式的自訂 UI 進行連結。

您可以預設啟動並追蹤 Windows 應用程式 SDK 設置,同時使用 ShellExecute 顯示您自己的設定進度視圖。 Windows 應用程式 SDK 安裝程式以靜默方式解壓縮 Windows 應用 MSIX 套件並呼叫 PackageManager.AddPackageAsync 方法來完成安裝。 這與您可能使用的其他執行時間安裝程式非常類似,例如 .NET、Visual C++或 DirectX。

如需示範如何從安裝程式執行 Windows 應用程式 SDK 安裝程式的程式碼範例,請參閱安裝程式功能測試中的 RunInstaller 函數。

安裝程式範例

請參閱下面的範例,以了解如何從 Win32 安裝程序啟動安裝程式,而不在安裝過程中彈出控制台視窗:

疑難排解

傳回碼

下表列出 Windows 應用程式 SDK .exe 安裝程式最常見的傳回碼。 所有版本的安裝程式的傳回碼都相同。

傳回碼 描述
0x0 軟體封包安裝或設定已成功完成。
0x80073d06 一或多個套件無法安裝。
0x80070005 無法進行系統範圍的安裝或配置,因為應用程式未以提升的權限執行,或執行安裝的使用者沒有管理員權限。

安裝錯誤

如果 Windows 應用程式 SDK 安裝程式在安裝過程中傳回錯誤,它將傳回描述問題的錯誤代碼。

選項 2:直接部署 Windows 應用程式 SDK 執行時間套件

作為使用 Windows 應用程式 SDK 安裝程式向最終使用者進行部署的替代方法,你可以透過應用程式的程式或 MSI 手動部署 MSIX 套件。 此選項最適合想要更多控制的開發人員。

有關示範安裝程式如何安裝 MSIX 套件的範例,請參閱 Windows 應用程式 SDK 安裝程式程式碼中的 install.cpp

若要檢查是否已安裝 Windows 應用程式 SDK(如果是的話,哪個版本),您可以呼叫 PackageManager.FindPackagesForUserWithPackageTypes 來檢查特定套件系列。

從 mediumIL (完全信任) 解除封裝程式 (請參閱 Application 元素),您可以使用下列程式代碼來檢查向目前使用者註冊的套件:

using Windows.Management.Deployment;

public class WindowsAppSDKRuntime
{
    public static IsPackageRegisteredForCurrentUser(
        string packageFamilyName,
        PackageVersion minVersion,
        Windows.System.ProcessorArchitecture architecture,
        PackageTypes packageType)
    {
        ulong minPackageVersion = ToVersion(minVersion);

        foreach (var p : PackageManager.FindPackagesForUserWithPackageTypes(
            string.Empty, packageFamilyName, packageType)
        {
            // Is the package architecture compatible?
            if (p.Id.Architecture != architecture)
            {
                continue;
            }

            // Is the package version sufficient for our needs?
            ulong packageVersion = ToVersion(p.Id.Version);
            if (packageVersion < minPackageVersion)
            {
                continue;
            }

            // Success.
            return true;
        }

        // No qualifying package found.
        return false;
    }

    private static ulong ToVersion(PackageVersion packageVersion)
    {
        return ((ulong)packageVersion.Major << 48) |
               ((ulong)packageVersion.Minor << 32) |
               ((ulong)packageVersion.Build << 16) |
               ((ulong)packageVersion.Revision);
    }
}

針對上述案例,呼叫 FindPackagesForUserWithPackageTypes 最好呼叫 FindPackagesForUser。 這是因為您可以將搜尋範圍縮小到 (在此範例中),只要 是架構 或主要 套件。 這可避免比對其他類型的套件(例如資源、選擇性或套件組合),這在此範例中並不感興趣。

若要使用目前/呼叫的用戶內容,請將userSecurityId參數設定為空字串。

現在,一些資訊可協助您決定 如何在 上述程式代碼範例中呼叫 函式。 正確安裝的執行時間是由多個相依於系統 CPU 架構的套件所組成:

  • 在 x86 計算機上:Fwk=[x86]、Main=[x86]、Singleton=[x86]、DDLM=[x86]。
  • 在 x64 計算機上:Fwk=[x86、x64]、Main=[x64]、Singleton=[x64]、DDLM=[x86、x64]。
  • 在 arm64 機器上:Fwk=[x86、x64、arm64]、Main=[arm64]、Singleton=[arm64]、DDLM=[x86、x64、arm64]。

針對MainSingleton套件,其架構應該符合系統的CPU架構;例如,x64系統上的 x64 套件。 針對 Framework 套件,x64 系統可以同時執行 x64 和 x86 應用程式;同樣地,arm64 系統也可以執行 arm64、x64 和 x86 應用程式。 DDLM 套件檢查與 Framework 檢查類似,不同之處在於 PackageType=main, 和 packagefamilyname 不同,而且由於 DDLM 的唯一命名配置,因此可能適用多個 (不同) packagefamilyname。 如需詳細資訊,請參閱 MSIX 套件 規格。因此,檢查會更像這樣:

public static bool IsRuntimeRegisteredForCurrentUser(PackageVersion minVersion)
{
    ProcessorArchitecture systemArchitecture = DetectSystemArchitecture();

    return IsFrameworkRegistered(systemArchitecture, minVersion) &&
           IsMainRegistered(systemArchitecture, minVersion) &&
           IsSingletonRegistered(systemArchitecture, minVersion) &&
           IsDDLMRegistered(systemArchitecture, minVersion);
}

private static ProcecssorArchitecture DetectSystemArchitecture()
{
    // ...see the call to IsWow64Process2(), and how the result is used...
    // ...as per `IsPackageApplicable()` in
    // [install.cpp](https://github.com/microsoft/WindowsAppSDK/blob/main/installer/dev/install.cpp)
    // line 99-116...
    // ...WARNING: Use IsWow64Process2 to detect the system architecture....
    // ...         Other similar APIs exist, but don't give reliably accurate results...
}

private static bool IsFrameworkRegistered(ProcessorArchitecture systemArchitecture,
    PackageVersion minVersion)
{
    // Check x86.
    if (!IsPackageRegisteredForCurrentUser(
        global::Microsoft.WindowsAppSDK.Runtime.Packages.Framework.PackageFamilyName,
        minVersion, ProcessorArchitecture.X86,
        PackageTypes.Framework))
    {
        return false;
    }

    // Check x64 (if necessary).
    if ((systemArchitecture == ProcessorArchitecture.X64) || 
        (systemArchitecture == ProcessorArchitcture.Arm64))
    {
        if (!IsPackageRegisteredForCurrentUser(
            global::Microsoft.WindowsAppSDK.Runtime.Packages.Framework.PackageFamilyName,
            minVersion, ProcessorArchitecture.X64,
            PackageTypes.Framework))
        {
            return false;
        }
    }

    // Check arm64 (if necessary).
    if (systemArchitecture == ProcessorArchitcture.Arm64)
    {
        if (!IsPackageRegisteredForCurrentUser(
            global::Microsoft.WindowsAppSDK.Runtime.Packages.Framework.PackageFamilyName,
            minVersion, ProcessorArchitecture.Arm64,
            PackageTypes.Framework))
        {
            return false;
        }
    }

    return true;
}

private static bool IsMainRegistered(ProcessorArchitecture systemArchitecture,
    PackageVersion minVersion)
{
    return IsPackageRegisteredForCurrentUser(
        global::Microsoft.WindowsAppSDK.Runtime.Packages.Main.PackageFamilyName,
        minVersion,
        systemArchitecture,
        PackageTypes.Main);
}

private static bool IsSingletonRegistered(ProcessorArchitecture systemArchitecture,
    PackageVersion minVersion)
{
    return IsPackageRegisteredForCurrentUser(
        global::Microsoft.WindowsAppSDK.Runtime.Packages.Singleton.PackageFamilyName,
        minVersion,
        systemArchitecture,
        PackageTypes.Main);
}

private static bool IsDDLMRegistered(ProcessorArchitecture systemArchitecture,
    PackageVersion minVersion)
{
    // ...similar to IsFrameworkRegistered, but the packageFamilyName is more complicated...
    // ...and no predefined constant is currently available...
    // ...for more details, see
    // https://github.com/microsoft/WindowsAppSDK/blob/main/specs/Deployment/MSIXPackages.md.
}

上述資訊和程式代碼涵蓋基本偵測案例。 若要偵測是否已為所有使用者布建運行時間,或從應用程式容器執行上述作業,以及/或從已 mediumIL 封裝的程序進行,則需要額外的邏輯。

部署案例

  • 系統範圍內安裝 Windows 應用程式 SDK 執行時間:系統範圍的安裝會變更所有使用者的計算機,包括將來新增的新使用者。 如果應用程式正在提升許可權且執行安裝的使用者具有系統管理員許可權,則安裝程式會呼叫 ProvisionPackageForAllUsersAsync 來註冊全系統 MSIX 套件。 如果系統範圍註冊不成功,則僅為目前執行安裝的使用者執行安裝。 在受控企業環境中,IT 系統管理員應該能夠像往常一樣為每個人佈建。

  • Windows 應用程式 SDK 安裝程式所轉散發的架構:Windows 應用程式 SDK 安裝程式可在、 x64Arm64 架構中使用x86。 每個版本的安裝程式都包含 MSIX 套件,只針對它命名的特定架構。 例如,如果您在 x64 或和 Arm64 裝置上執行 x86 WindowsAppRuntimeInstall.exe ,則該 x86 安裝程式只會部署到該裝置上的 x86 架構套件。

  • 所有 Windows 應用程式 SDK MSIX 套件已安裝在電腦上:MSIX 套件安裝到系統範圍的位置,磁碟上僅存在一份副本。 如果應用程式在電腦上已安裝所有 MSIX 套件相依性時嘗試安裝 Windows 應用程式 SDK,則不會執行安裝。

  • 電腦上未安裝一個或多個 Windows 應用程式 SDK MSIX 套件:部署 Windows 應用程式 SDK 時,請務必嘗試安裝所有 MSIX 套件 (架構、主、singleton、DDLM),以確保所有依賴項已安裝且您避免影響最終使用者體驗。

使用外部位置封包或非封包的應用程式執行要求

使用外部位置打包或未打包的應用程式有額外的執行時間要求才能使用 Windows 應用程式 SDK 執行時間。 這涉及在執行時間引用和初始化 Windows 應用程式 SDK Framework 套件。 此外,動態相依性 API 可用來參考 Windows 應用程式 SDK 以外的其他架構套件。

使用 Windows 應用程式 SDK 執行時

使用外部位置封包的應用程式和非封包的應用程式必須呼叫 Bootstrapper API 才能在執行時間使用 Windows 應用程式 SDK。 在應用程式可以使用 Windows 應用程式 SDK 功能 (例如 WinUI、App Lifecycle、MRT Core 和 DWriteCore) 之前,這是必要的。 引導程式元件允許使用外部位置封包和非封包的應用程式來執行以下重要任務:

  • 尋找 Windows 應用程式 SDK 架構套件並將其載入到應用程式的包圖中。
  • 初始化 Windows 應用程式 SDK 架構套件的動態相依性生命週期管理器 (DDLM)。 DDLM 的目的是防止在外部位置打包的應用程式或未打包的應用程式使用 Windows 應用程式 SDK 架構包時為其提供服務。

為使用外部位置封包的應用程式和非封包的應用程式載入 Windows 應用程式 SDK 執行時間的最簡單方法是在專案檔案 (.csproj 或 .vcxproj) 中設定<WindowsPackageType>None</WindowsPackageType>屬性。 您也可以直接在應用程式的啟動程式碼中呼叫引導程式 API,以便更好地控制初始化。 有關更多詳細資訊,請參閱對使用外部位置封包或非封包的應用程式使用 Windows 應用 SDK 執行時教學課程:在使用 Windows 應用 SDK 的使用外部位置封包或非封包的應用程式中使用引導程序 API

動態依賴關係支援允許使用外部位置打包和未打包的應用程式保留其現有的部署機制 (例如 MSI 或任何安裝程式),並能夠在其應用程式中利用 Windows 應用程式 SDK。 動態依賴可以被封包應用程式、帶有外部位置封包應用程式、非封包應用程式使用;儘管它主要供與外部位置封包應用程式和非封包應用程式一起使用。

Windows 應用程式 SDK 架構套件的每個版本和架構都有一個 DDLM。 這代表著在 x64 電腦上,您可能同時擁有一個 DDLM x86 和一個 x64 版本來支援兩種架構的應用程式。

使用動態依賴 API 引用其他架構封包

如果您想使用 Windows 應用程式 SDK 以外的其他架構套件 (例如 DirectX) 中的功能,則使用外部位置封包和非封包的應用程式可以呼叫動態相依性 API。 除了引導程式元件之外,Windows 應用程式 SDK 還提供了一組更廣泛的 C/C++ 函數和 WinRT 類,用於實作動態相依性 API。 該 API 旨在用於在執行時動態引用任何架構包。

關於詳細資訊息,請參閱從桌面應用動態使用 MSIX 架構套件動態相依性範例

將 .winmd 檔案部署至目標計算機

我們建議您與您的應用程式一起繼續部署 Windows 元資料 (.winmd) 檔案。 中繼資料可以在執行時被各種 API 和行為使用,缺少中繼資料可能會限制或破壞功能。 例如,中繼資料可用於跨公寓邊界編組物件;而編組的需要可以是機器性能的函數。 由於沒有確定的方法來知道您是否需要中繼資料,因此除非.winmd您非常關心大小,否則您應該部署中繼資料。