共用方式為


手動使用外部位置封裝來授與套件身分識別

如需新增套件身分識別背後的動機,以及在Visual Studio中建置身分識別套件和手動建置身分識別套件之間的差異,請參閱 概觀

本主題描述如何手動建置和註冊身分識別套件。 如需在Visual Studio中建置身分識別套件的相關信息,請參閱 在Visual Studio中使用外部位置封裝來授與套件身分識別

以下是手動建置和註冊身分識別套件的步驟(本主題將詳細說明:

  1. 建立身分套件的套件清單
  2. 建置並簽署身分識別套件
  3. 將身分識別元數據新增至桌面應用程式指令清單
  4. 在安裝程式中註冊身分識別套件
  5. 選擇性步驟

建立識別套件的套件清單

建立身分識別套件的第一個步驟是根據下列範本建立套件指令清單。 這是 MSIX 指令清單,但僅用於身分識別,而且不會改變應用程式的運行時間行為。

<?xml version="1.0" encoding="utf-8"?>
<Package IgnorableNamespaces="uap uap10"
  xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
  xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
  xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10"
  xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities">
  <Identity Name="ContosoPhotoStore" Publisher="CN=Contoso" Version="1.0.0.0" ProcessorArchitecture="neutral" />
  <Properties>
    <DisplayName>Contoso PhotoStore</DisplayName>
    <PublisherDisplayName>Contoso</PublisherDisplayName>
    <Logo>Assets\storelogo.png</Logo>
    <uap10:AllowExternalContent>true</uap10:AllowExternalContent>
  </Properties>
  <Resources>
    <Resource Language="en-us" />
  </Resources>
  <Dependencies>
    <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.19041.0" MaxVersionTested="10.0.26100.0" />
  </Dependencies>
  <Capabilities>
    <rescap:Capability Name="runFullTrust" />
    <rescap:Capability Name="unvirtualizedResources"/>
  </Capabilities>
  <Applications>
    <Application Id="ContosoPhotoStore" Executable="ContosoPhotoStore.exe" uap10:TrustLevel="mediumIL" uap10:RuntimeBehavior="win32App"> 
      <uap:VisualElements AppListEntry="none" DisplayName="Contoso PhotoStore" Description="Contoso PhotoStore App" BackgroundColor="transparent" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" />
    </Application>
  </Applications>
</Package>

請注意下列關於這份列表的重要細節:

  • 請填寫 Identity 元素屬性,並輸入您的應用程式的詳細資訊
    • Name 是身分識別套件所需的名稱
    • Publisher 必須符合用來簽署應用程式的憑證的 Subject 信息
    • Version 是所需的身分識別套件版本。 常見的做法是讓身分識別套件版本與應用程式版本一致。 如果已經註冊該版本的套件,您將無法在系統上註冊身分識別套件的版本。 您必須先取消註冊現有的套件,才能重新安裝具有相同版本的套件。
    • ProcessorArchitectureneutral 如所示,讓身分識別套件適用於所有架構 (x86、x64 和 ARM64)
  • 請填入您的應用程式的詳細資料到 DisplayNamePublisherDisplayName 元素中。
    • 除非您在清單中新增簡單身分識別以外的其他功能,否則這些值不會顯示在任何地方。
  • Logo 元素更新為應用程式安裝目錄中的相對路徑,以對應到 .png、.jpg或 .jpeg 圖像。
  • 確定 元素 AllowExternalContent 已設定為 true ,如所示,可重複使用現有的安裝程式
  • 設定 TargetDeviceFamilyMinVersionMaxVersionTested 如下所示:
    • 設定 MinVersion10.0.19041.0,以取得 Windows 10 和 Windows 11 作系統版本的最大觸達和統一性
    • 設定 MinVersion10.0.26100.0 ,將身分識別套件限制為 Windows 11 版本 24H2 和更新版本
    • 設定 MaxVersionTested10.0.26100.0 ,如下所示
    • 注意: AllowExternalContent 這裡使用的功能是在 Windows 組建 10.0.19041.0 中引進的。 如果您的應用程式比這還低,您應該在安裝程式中執行 OS 版本檢查,而不是在 10.0.19041.0 之前的 OS 版本上註冊身分識別套件。 請參閱 在安裝程式中註冊身分識別套件
  • runFullTrustunvirtualizedResources 功能應按照所示宣告,以確保 Win32 的相容性。
  • 請為與應用程式相關聯的每個可執行檔,如下所示,添加一個Application元素。
    • 確保 TrustLevelmediumIL,而 RuntimeBehaviorwin32App,如 Win32 相容性所示
  • 需要 VisualElements 子元素,但 AppListEntry="none" 屬性可確保已安裝的應用程式不會顯示身分識別套件
    • 請使用相關詳細資訊更新DisplayName屬性和Description屬性,並保留其他屬性,如下所示(參考的影像路徑不需要解析)
    • 如需可能需要當地語系化和影像的案例,請參閱 當地語系化和視覺資產

當您在稍後的步驟中註冊套件時,從此指令清單建立的身分識別套件將會連線到應用程式的安裝目錄。

建置並簽署身分識別套件

建立身分識別套件指令清單之後,請使用 Windows SDK 中的 MakeAppx.exe 工具來 建置身分識別套件。

MakeAppx.exe pack /o /d <path to directory that contains manifest> /nv /p <output path>\MyPackage.msix

注意:必須使用 /nv 旗標來略過清單中參考檔案路徑的驗證。

若要安裝在終端用戶計算機上,身分識別套件必須使用目標計算機上信任的憑證進行簽署。 您可以 建立新的自我簽署憑證以供開發之用 ,並使用 Windows SDK 中提供的 SignTool 簽署您的身分識別套件,但需要 IT 部門或 Azure 信任簽署 等服務的生產憑證,才能在終端使用者電腦上註冊套件。

SignTool.exe sign /fd SHA256 /a /f <path to certificate>\MyCertificate.pfx /p <certificate password> <path to package with external location>\MyPackage.msix

注意:如需如何使用生產憑證在 CI/CD 管線內建置和簽署身分識別套件,請參閱 MSIX 和 CI/CD 管線概觀 以取得範例。

將身分識別元數據新增至傳統型應用程式指令清單

您可以藉由包含 應用程式指令清單 (也就是並存或融合指令清單)與與身分識別套件指令清單中元數據相符的元數據,來連接身分識別套件與應用程式可執行檔。

在 Visual Studio 中,您可以開啟 [專案]作功能表,然後選取 [新增>>],將應用程式指令清單新增至可執行的專案。

以下是範例應用程式指令清單代碼段, msix 示範將二進位檔與身分識別套件中的元數據連線所需的專案。

<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
  <assemblyIdentity version="0.0.0.0" name="ContosoPhotoStore"/>
  <msix xmlns="urn:schemas-microsoft-com:msix.v1"
          publisher="CN=Contoso"
          packageName="ContosoPhotoStore"
          applicationId="ContosoPhotoStore"
        />
</assembly>

元素的屬性 msix 必須符合識別套件指令清單中的這些值:

  • packageNamepublisher屬性必須分別符合身分識別套件指令清單中Name元素中的PublisherIdentity屬性。
  • 必須使applicationId屬性符合您的識別套件清單中對應Id元素的Application屬性。

在安裝程式中註冊身分識別套件

將身分識別與您的應用程式產生關聯的最後一個步驟是在安裝程式中註冊身分識別套件,並將它與應用程式的安裝目錄產生關聯。

PowerShell

使用正確的參數執行 powershell.exe 是註冊封裝的最簡單方式。 每一使用者安裝與整部機器安裝的指導方針不同。

Per-User (PowerShell)

若要在每個使用者安裝期間註冊身分識別套件:

powershell.exe -NoLogo -NoProfile -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -Command "Add-AppxPackage -Path <PackagePath> -ExternalLocation <ExternalLocation>"
  • 設定 <PackagePath> 為上一個步驟中產生之已簽署識別套件的絕對路徑(檔名)。
  • 設定 <ExternalLocation> 為應用程式安裝目錄的絕對路徑(不含任何可執行檔名稱)。

若要在個別使用者卸載期間取消註冊身分識別套件:

powershell.exe -NoLogo -NoProfile -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -Command "Get-AppxPackage <PackageName> | Remove-AppxPackage"
  • 設定<PackageName>為您在識別套件清單中定義的套件名稱(Identity 元素的 Name 屬性)

Per-Machine (PowerShell)

若要在整部機器安裝期間註冊身分識別套件:

powershell.exe -NoLogo -NoProfile -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -Command "Add-AppxPackage -Stage <PackagePath> -ExternalLocation <ExternalLocation>; Add-AppxProvisionedPackage -Online -PackagePath <PackagePath>"
  • 設定 <PackagePath> 為上一個步驟中產生之已簽署識別套件的絕對路徑(檔名)。
  • 設定 <ExternalLocation> 為應用程式安裝目錄的絕對路徑(不含任何可執行檔名稱)。

若要在全機器卸載期間取消註冊身分識別套件:

powershell.exe -NoLogo -NoProfile -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -Command "$packages = Get-AppxPackage <PackageName>; foreach ($package in $packages) { Remove-AppxProvisionedPackage -PackageName $package.PackageFullName -Online }; foreach ($package in $packages) { Remove-AppxPackage -Package $package.PackageFullName -AllUsers }
  • 設定<PackageName>為您在識別套件清單中定義的套件名稱(Identity 元素的 Name 屬性)

PackageManager API

如果您想要呼叫 OS API 來註冊和取消註冊身分識別套件,PackageManager API 會提供對 PowerShell 的對等功能。 每一使用者安裝與整部機器安裝的指導方針不同。

以下是示範 API 的代碼段。 如需 C# 和 C++ 的生產環境就緒程式代碼,請參閱 範例應用程式

Per-User (PackageManager)

下列程式代碼清單示範如何使用 AddPackageByUriAsync 方法來註冊識別套件,並使用 RemovePackageAsync 方法取消註冊身分識別套件。

using Windows.Management.Deployment;

...

// Register the identity package during install

var externalUri = new Uri(externalLocation);
var packageUri = new Uri(packagePath);

var packageManager = new PackageManager();

var options = new AddPackageOptions();
options.ExternalLocationUri = externalUri;

await packageManager.AddPackageByUriAsync(packageUri, options);

...

// Unregister the identity package during uninstall

var packageManager = new PackageManager();
var packages = packageManager.FindPackagesForUserWithPackageTypes("", "<IdentityPackageFamilyName>", PackageType.Main);
foreach (var package in packages)
{
  await packageManager.RemovePackageAsync(package.Id.FamilyName);
}

請注意下列關於此程式代碼的重要詳細資料:

  • 設定 externalLocation 為應用程式安裝目錄的絕對路徑(不含任何可執行檔案名稱)
  • 設定 packagePath 為上一個步驟中產生的已簽署身分識別套件絕對路徑 (檔名)
  • 在註冊身分識別套件的系統上執行Get-AppxPackage <IdentityPackageName> PowerShell 命令可以找到<IdentityPackageFamilyName>。 屬性 PackageFamilyName 包含要在這裡使用的值。

Per-Machine (PackageManager)

下列程式代碼清單示範如何使用 StagePackageByUriAsync 和 ProvisionPackageForAllUsersAsync 方法來註冊身分識別套件,並使用 DeprovisionPackageForAllUsersAsyncRemovePackageAsync 方法來取消註冊身分識別套件。

// Register the identity package during install

var externalUri = new Uri(externalLocation);
var packageUri = new Uri(packagePath);

var packageManager = new PackageManager();

var options = new StagePackageOptions();
options.ExternalLocationUri = externalUri;

await packageManager.StagePackageByUriAsync(packageUri, options);
await packageManager.ProvisionPackageForAllUsersAsync(packageFamilyName);

...

// Unregister the identity package during uninstall

var packageManager = new PackageManager();

var packages = packageManager.FindPackagesForUserWithPackageTypes("", "<IdentityPackageFamilyName>", PackageType.Main);
foreach (var package in packages)
{
  await packageManager.DeprovisionPackageForAllUsersAsync(package.Id.FamilyName);
  await packageManager.RemovePackageAsync(package.Id.FamilyName, RemovalOptions.RemoveForAllUsers);
}

請注意下列關於此程式代碼的重要詳細資料:

  • 設定 externalLocation 為應用程式安裝目錄的絕對路徑(不含任何可執行檔案名稱)
  • 設定 packagePath 為上一個步驟中產生的已簽署身分識別套件絕對路徑 (檔名)
  • 在身分識別套件已註冊的系統上執行Get-AppxPackage <IdentityPackageName> PowerShell 命令即可找到<IdentityPackageFamilyName>。 屬性 PackageFamilyName 包含要在這裡使用的值。

範例應用程式

如需完整運作的 C# 和C++應用程式,請參閱 PackageWithExternalLocation 範例,以示範如何註冊和取消註冊身分識別套件。

選擇性步驟

在地化和視覺效果資產

識別套件身份的某些功能可能導致在 Windows 作業系統中顯示來自於身分識別套件資訊清單的字串和圖像。 例如:

  • 使用相機、麥克風或位置 API 的應用程式會在 Windows 隱私權設定中擁有專用的控件切換,以及使用者可用來授與或拒絕對這些敏感性資源的存取權的代理同意提示。
  • 註冊共用目標的應用程式會顯示在 [共用] 對話框中。

若要將身分識別套件指令清單中的字串本地化,請參閱 將指令清單本地化

在身分識別套件的指令清單屬性 VisualElements 中提供影像路徑時,提供的路徑應該是應用程式安裝目錄中的相對路徑,這些路徑應解析為 .png、.jpg或 .jpeg 影像。 屬性名稱表示影像的預期維度(150x150 和 40x40)。