> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 自訂安裝動作

> 自訂安裝動作

許多遊戲會使用反作弊和其他中介軟體。這些元件通常會在使用者安裝遊戲時以鏈結方式安裝。使用者可能透過 Microsoft Store 安裝某款遊戲，並透過其他散發通路安裝另一款遊戲。如果這兩款遊戲以鏈結方式安裝相同的中介軟體套件，平台會確保不會發生衝突。遊戲可以在其套件中包含一或多個任意的 .exe 或 .msi 檔案，並要求在完成應用程式安裝的過程中執行這些檔案。自訂安裝動作功能是用於安裝遊戲的反作弊軟體或其他可轉散發中介軟體。如此一來，您就可以在提交至 Microsoft Store 的 MSIX 中，以及透過其他散發通路提交的 .msi 或 .exe 檔案中，使用完全相同的鏈結安裝程式 .exe 檔案。

在傳統的 Win32 應用程式中，共用中介軟體通常是透過獨立的可轉散發檔案安裝，這些檔案通常是可與遊戲本身組合在一起的自解壓縮 .exe 或 .msi。Microsoft Store 應用程式會將相依性模型化為架構套件，這些套件不會與遊戲組合在一起，而是透過 Microsoft Store 個別部署。在此模型中，取用端應用程式的資訊清單會宣告對一或多個架構套件的相依性。接著 Microsoft Store 會負責以鏈結方式安裝這些相依性。雖然 Microsoft Store 中有許多可轉散發套件以架構套件的形式提供，但不可避免地會有部分可轉散發套件無法以架構套件形式取得。對於這些套件，解決方案是允許遊戲將可轉散發套件組合在遊戲套件內。

若要包含 .exe 或 .msi 可轉散發套件，您需要更新 MicrosoftGame.config 檔案。這些變更包括宣告您要使用的自訂動作類型，以及其在安裝套件中的位置。
任何可轉散發套件都必須包含在套件中，並在 MicrosoftGame.config 中宣告。宣告內容包括可執行檔的路徑 (相對於宣告的 Folder 路徑，而 Folder 路徑又相對於套件本身的根路徑)。宣告內容也包括執行可執行檔時要傳遞給它的任何命令列引數。這是透過在 MicrosoftGame.config 檔案中加入 **CustomInstallActions** 元素來完成。

## CustomInstallActions

**CustomInstallActions** 元素包含要執行哪些自訂安裝動作以及何時執行的所有定義。您只能在 MicrosoftGame.config 檔案中宣告此元素的一個執行個體。它有一個必要的子元素 **Folder**，這是一個字串，用來指定包含所有自訂動作所需之所有檔案的資料夾。此資料夾可以包含子資料夾。您必須負責確保套件包含任何自訂動作可執行檔的所有相依性，而且這些相依性位於每個可執行檔適當的載入路徑中。

<Note>當您封裝遊戲時，`makepkg` 會將此 **CustomInstallActions** 元素轉譯為所產生之 `appxmanifest.xml` 中的 MSIX `windows.customInstall` 延伸模組，其中對應的元素是 `<CustomInstall>`，且 **Folder** 是以*屬性*表示。您不需要自行撰寫該 `<CustomInstall>` 形式；在 MicrosoftGame.config 中，**Folder** 是 **CustomInstallActions** 的子*元素*，如本文稍後的**遊戲設定檔變更**範例所示。</Note>

<Note>您不得將任何主要遊戲可執行檔或其他檔案放入指定的 Folder 中。它明確地僅供自訂安裝檔案使用。</Note>

在 **CustomInstallActions** 元素中，應用程式可以宣告 **InstallActionList**、**RepairActionList** 和 **UninstallActionList** 子元素。這些全都是選擇性的：您可以宣告其中任何一個，也可以都不宣告。在每個清單中，您可以指定一或多個 **InstallAction**、**RepairAction** 或 **UninstallAction** 子項目。平台會依照您指定的順序，使用您指定的命令列引數，執行您指定的動作。

### 動作類型

自訂安裝延伸模組的三個子節點決定了特定自訂動作的執行時機。自訂安裝動作有三種類型。

* **安裝動作：** 平台在應用程式首次啟動之前執行的動作
* **修復動作：** 使用者選取 \[修復] 或 \[重設] 時執行的動作
* **解除安裝動作：** 使用者解除安裝應用程式時執行的動作

<Info>儘管名稱如此，**安裝動作並不會在安裝套件時執行**。每種動作類型都會在應用程式生命週期中的特定時間點執行，而 **InstallAction** 會在遊戲*首次啟動之前*立即執行一次 (這是平台可以顯示必要 UAC 提示的第一個時間點)。「安裝」、「修復」和「解除安裝」指的是動作所屬的生命週期*類別*，而不是動作執行的時刻。如果您需要在實際安裝/下載套件時執行工作，自訂安裝動作並不是適用的機制。如需完整的順序，請參閱[自訂動作使用方式](#custom-action-usage)。</Info>

一般而言，您會指定以 **InstallAction** 鏈結安裝某個可轉散發套件，然後指定以 **UninstallAction** 將其解除安裝。不過，在某些情況下，您可能會選擇只安裝而不搭配對應的解除安裝。在此情境中，您的應用程式會安裝某些內容，並在應用程式解除安裝時將其保留；這可能適用於由其他應用程式共用的可轉散發套件。同樣地，您的 **RepairAction** 可能只是重新宣告您為 **InstallAction** 指定的可執行檔，這是常見的做法。您想要在安裝/修復/解除安裝中執行的每個動作，也有可能各自需要不同的可執行檔。此結構描述非常有彈性：平台不要求任何動作。您可以自由地為每款遊戲適當設定這些行為。

<Info>只有在已執行安裝或修復動作的情況下，才會執行解除安裝動作。系統會使用 Name 屬性來追蹤此狀態。因此，安裝/修復/解除安裝動作必須具有相同的 Name。</Info>

### 動作的組成部分

#### File

您必須為每個動作指定要執行的檔案，而且此檔案必須位於您的套件中。如果您指定路徑，該路徑會隱含地相對於您的 **CustomInstallActions** **Folder** 路徑。您無法指定絕對路徑。您的路徑不得以反斜線 (\\) 開頭。

#### Name

您必須為動作指定 *Name*。此 *Name* 在父系 *Actions* 節點內必須是唯一的，但可以在不同的 Actions 節點之間共用。例如，您可以將 File="MySetup.exe" 和 *Name*="abc123" 同時指定為 **InstallAction** 和 **RepairAction**。另一方面，如果您有兩個 **InstallAction** 元素，它們必須各自具有不同的 *Name*。只要可執行檔沒有變更，您就應該在各套件版本之間為相同的可執行檔使用相同的 *Name*。*Name* 會作為動作的身分識別，讓平台追蹤哪些動作已成功執行，以及更新的套件是否需要執行這些動作。如果更新的套件指定了具有已成功執行之 *Name* 的自訂動作，平台會在更新時略過此動作。

<Info>引數清單的差異並不構成身分識別的差異。如果您想要在*更新的*套件中使用不同的引數執行相同的可執行檔，就必須提供不同的 *Name*。您必須負責適當設定所宣告的 *Name*，並在各版本之間追蹤它們。</Info>

#### Arguments

每個自訂安裝動作都有第三個元素 *argument*，可讓您加入執行可轉散發命令時需要包含的任何引數。

## 自訂動作使用方式

安裝反作弊軟體通常需要使用者具有系統管理員權限，而且一般而言 (由於自訂動作是極為強大的功能)，平台會要求任何具有自訂動作的套件都需要系統管理員權限。對於以系統管理員權限執行的作業，Windows 會要求在首次執行應用程式時顯示使用者帳戶控制 (UAC) 提示。使用者工作流程如下。

* 遊戲的 Microsoft Store 頁面包含需求的說明，包括安裝是否需要提高權限、安裝是否會執行自訂動作，以及這對使用者可能代表的意義。提供此資訊是為了讓使用者在購買遊戲時能做出明智的決定。
* 假設使用者接受這些限制和影響，他們會選取 \[安裝]。
* 平台會偵測到套件包含自訂動作，並記錄需要執行自訂動作的事實。不過，平台不會在初始安裝階段執行自訂動作。相反地，任何自訂動作都會在使用者首次啟動遊戲時執行。
* 首次啟動遊戲時，在平台即將執行自訂動作的時間點，會顯示 UAC 提示。使用者接著需要提供系統管理員認證並接受提高權限。即使套件包含多個自訂動作，也只會向使用者顯示一次 UAC 提示。除非一或多個自訂動作已變更，否則更新時不會再出現 UAC 提示。解除安裝遊戲時會出現 UAC 提示。

所有自訂動作都必須傳回零表示成功。如果任何自訂動作失敗，平台會繼續執行其餘的自訂動作，並繼續嘗試啟動應用程式。在之後每次啟動應用程式時，平台都會繼續重試任何失敗/未完成的安裝自訂動作，直到該動作成功為止。如果應用程式在自訂動作失敗時無法正常運作，使用者隨時可以前往應用程式的 \[設定] 頁面，並選取 \[修復] 或 \[重設]。修復/重設不會重新下載遊戲檔案，只會重新註冊套件。任何失敗或未執行的自訂動作都會重新註冊以便執行。如果您的自訂安裝程式在成功時會傳回某個非零值，其中一個選項是將此安裝程式包裝在您建立的另一個可執行檔中，讓該可執行檔在成功時傳回零。

Microsoft Store 原則包含關於允許以鏈結方式安裝哪些類型之中介軟體/可轉散發軟體的指導方針。概括而言，鏈結安裝是針對執行遊戲所需的共用軟體，而非用於安裝不相關的應用程式或其他軟體。

<Note>自訂安裝動作僅在主要 MSIXVC 套件內受到支援。架構套件、選用套件、修改套件或任何其他類型的套件都不支援自訂安裝動作。</Note>

<Note>自訂安裝、修復和解除安裝動作是由零售版 Microsoft Store 部署管線執行。當您為了開發而在本機安裝套件時，這些動作不會執行；例如，當您使用 `wdApp install` 安裝鬆散的 `.msixvc`，或使用 `Add-AppxPackage` 註冊套件時。本機開發安裝仍可讓您驗證套件是否正確*宣告*了這些動作 (它們會以 `windows.customInstall` 延伸模組的形式出現在所產生的 `appxmanifest.xml` 中)，但在該路徑上不會叫用自訂動作可執行檔本身。若要端對端驗證動作的執行，請透過 Store 或沙箱流程安裝遊戲。</Note>

## 以自訂安裝動作執行 MSI

對於 MSI，您需要提供 MSI 的名稱，平台會對該檔案執行 msiexec.exe。請勿提供 **/i**、**/f** 或 **/x** 引數，因為這些引數是根據宣告該 MSI 的動作類型 (安裝、修復或解除安裝) 推斷而來。您無法為 **/f** 參數提供任何選項。不過，您可以提供通常會提供給 msiexec.exe 的任何其他選擇性引數。這是命令列引數受到限制的唯一情境：對於非 MSI 動作，您可以提供任何想要的引數。對於非 MSI 動作，平台不會剖析或驗證引數，只會將其傳遞給可執行檔。您必須負責確保引數正確無誤。

目前沒有對 MST (MSI 轉換) 的直接支援。如果您需要使用 MSI/MST，其中一個可能的因應措施是建置一個包裝 msiexec 的獨立 .exe，以執行您的 MSI 並套用您的 MST。

## 遊戲設定檔變更

下列 XML 範例示範如何在 MicrosoftGame.config 檔案中適當新增內容，以允許自訂安裝動作。

```xml theme={null}
  <!-- Include CustomInstallActions element. Declare InstallActions, 
  RepairActions and/or UninstallActions as appropriate for your app. --> 
  <DesktopRegistration>
    <!-- ... --> 
    <!-- Other entries omitted for brevity. --> 
    <!-- ... --> 
    <CustomInstallActions>
      <Folder>MyInstallers</Folder>
        <InstallActionList>
          <InstallAction File="CustomInstaller.exe" Name="TaskName" Arguments="/silent /example" />
        </InstallActionList>
        <RepairActionList>
          <RepairAction File="CustomInstaller.exe" Name="TaskName" Arguments="/silent /repair" />
        </RepairActionList>
        <UninstallActionList>
          <UninstallAction File="CustomInstaller.exe" Name="TaskName" Arguments="/silent /remove" />
        </UninstallActionList>
    </CustomInstallActions>
  </DesktopRegistration>
```

在上述範例中，所有可執行檔和任何相依性都必須放在您於套件根目錄指定的 MyInstallers 資料夾中。在該資料夾內，您可以建立任何適合您應用程式的子資料夾結構。在此範例中，MySetup.exe 的路徑會是 \<package root>\MyInstallers\Banana\MySetup.exe。如果該可執行檔有任何相依性，也必須將其放在適當的資料夾或子資料夾中。

下列順序說明如何在多個版本之間撰寫資訊清單。

```xml theme={null}
<!-- v1 of the game. --> 
    <CustomInstallActions>
      <Folder>MyInstallers</Folder>
      <InstallActionList>
        <InstallAction File="CustomInstaller.exe" Name="TaskName_1" Arguments="/silent /example" />
          <!-- The platform records the successful install of TaskName_1. --> 
      </InstallActionList>
      <RepairActionList>
        <RepairAction File="CustomInstaller.exe" Name="TaskName_1" Arguments="/silent /repair" />
      </RepairActionList>
      <UninstallActionList>
        <UninstallAction File="CustomInstaller.exe" Name="TaskName_1" Arguments="/silent /remove" />
        <!-- The platform records the successful uninstall of TaskName_1. --> 
      </UninstallActionList>
    </CustomInstallActions>
      
<!-- v2 of the game, where the redist is NOT updated. --> 
    <CustomInstallActions>
      <Folder>MyInstallers</Folder>
        <InstallActionList>
          <InstallAction File="CustomInstaller.exe" Name="TaskName_1" Arguments="/silent /example" />
          <!-- The platform detects that we've already installed TaskName_1, so we don't  
          run it again. Therefore, there's no UAC prompt. --> 
        </InstallActionList>
        <RepairActionList>
          <RepairAction File="CustomInstaller.exe" Name="TaskName_1" Arguments="/silent /repair" />
        </RepairActionList>
        <UninstallActionList>
          <UninstallAction File="CustomInstaller.exe" Name="TaskName_1" Arguments="/silent /remove" />
        </UninstallActionList>
      </CustomInstallActions>
 
<!-- v2 of the game, where a redist IS updated. --> 
    <CustomInstallActions>
      <Folder>MyInstallers</Folder>
        <InstallActionList>
          <InstallAction File="CustomInstaller.exe" Name="TaskName_2" Arguments="/silent /example" />
          <!-- The platform detects that we haven't previously run TaskName_2, so we need 
          to run it this time and show a UAC prompt. -->  
        </InstallActionList>
        <RepairActionList>
          <RepairAction File="CustomInstaller.exe" Name="TaskName_1" Arguments="/silent /repair" />
        </RepairActionList>
        <UninstallActionList>
          <UninstallAction File="CustomInstaller.exe" Name="TaskName_1" Arguments="/silent /remove" />
        </UninstallActionList>
      </CustomInstallActions>
```


## Related topics

- [安裝 GDK 工具鏈](/zh-TW/home/setup-install/download-install.md)
- [XR-047 使用者設定檔存取](/zh-TW/publishing/certification/xr/xr-047.md)
- [設定並安裝 GDK](/zh-TW/home/setup-install/get-started.md)
- [開發新的 GDK 遊戲](/zh-TW/home/build-first-title/developing-new-titles.md)
- [PFStatisticsDeleteStatisticsRequest](/zh-TW/services/playfab/api-references/c/pfstatisticstypes/structs/pfstatisticsdeletestatisticsrequest.md)
