透過套件支援架構執行指令碼

腳本可讓 IT 專業人員在使用 MSIX 封裝應用程式之後,將應用程式動態自訂至使用者的環境。 例如,您可以使用腳本來設定資料庫、設定 VPN、掛接共用磁片磁碟機,或動態執行授權檢查。 腳本提供許多彈性。 它們可能會變更登錄機碼,或根據電腦或伺服器組態執行檔案修改。

您可以使用套件支援架構 (PSF) 在封裝的應用程式可執行檔執行之前執行一個 PowerShell 腳本,並在應用程式可執行檔執行之後執行一個 PowerShell 腳本來清除。 應用程式資訊清單中定義的每個應用程式可執行檔都可以有自己的腳本。 您可以將腳本設定為只在第一次啟動應用程式時執行一次,而不顯示 PowerShell 視窗,讓使用者不會不小心提前結束腳本。 還有其他選項可用來設定腳本可執行檔方式,如下所示。

必要條件

若要讓腳本能夠執行,您必須將 PowerShell 執行原則設定為 RemoteSigned 。 您可以執行此命令來執行此動作:

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned

必須針對 64 位 PowerShell 可執行檔和 32 位 PowerShell 可執行檔設定執行原則。 請務必開啟每個版本的 PowerShell,並執行上述其中一個命令。

以下是每個可執行檔的位置。

  • 64 位元電腦:
    • 64 位可執行檔: %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe
    • 32 位可執行檔: %SystemRoot%\SysWOW64\WindowsPowerShell\v1.0\powershell.exe
  • 32 位元電腦:
    • 32 位可執行檔: %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe

如需 PowerShell 執行原則的詳細資訊,請參閱 這篇文章

🚩 請務必在套件中包含 StartingScriptWrapper.ps1 檔案,並將它放在與可執行檔相同的資料夾中。 您可以從 PSF NuGet 套件PSF Github 存放庫複製此檔案。

啟用腳本

若要指定每個已封裝應用程式可執行檔要執行的腳本,您需要修改 config.json 檔案。 若要告知 PSF 在執行封裝的應用程式之前執行腳本,請新增名為 的 startScript 組態專案。 若要告訴 PSF 在封裝的應用程式完成之後執行腳本,請新增名為 的 endScript 組態專案。

編寫設定專案的腳本

以下是腳本可用的設定專案。 結束腳本會 waitForScriptToFinish 忽略 和 stopOnScriptError 組態專案。

機碼名稱 值類型 必要項? 預設 描述
scriptPath 字串 N/A 腳本的路徑,包括名稱和延伸模組。 如果指定,路徑會相對於應用程式的工作目錄,否則會從封裝的根目錄開始。
scriptArguments 字串 No empty 空格分隔的引數清單。 PowerShell 腳本呼叫的格式相同。 這個字串會附加至 scriptPath ,以發出有效的PowerShell.exe呼叫。
runInVirtualEnvironment boolean No true 指定腳本是否應該在封裝應用程式執行所在的相同虛擬環境中執行。
runOnce boolean No true 指定腳本是否應該針對每個使用者、每個版本執行一次。
showWindow boolean No false 指定是否顯示 PowerShell 視窗。
stopOnScriptError boolean No false 指定如果啟動腳本失敗,是否要結束應用程式。
waitForScriptToFinish boolean No true 指定封裝的應用程式是否應該等待啟動腳本完成,再啟動。
timeout DWORD No INFINITE 允許腳本執行多久。 當時間經過時,腳本將會停止。

注意

不支援設定 stopOnScriptError: true 範例應用程式的 和 waitForScriptToFinish: false 。 如果您設定這兩個設定專案,PSF 會傳回錯誤ERROR_BAD_CONFIGURATION。

範例組態

以下是使用兩個不同應用程式可執行檔的範例組態。

{
  "applications": [
    {
      "id": "Sample",
      "executable": "Sample.exe",
      "workingDirectory": "",
      "stopOnScriptError": false,
      "startScript":
      {
        "scriptPath": "RunMePlease.ps1",
        "scriptArguments": "\\\"First argument\\\" secondArgument",
        "runInVirtualEnvironment": true,
        "showWindow": true,
        "waitForScriptToFinish": false
      },
      "endScript":
      {
        "scriptPath": "RunMeAfter.ps1",
        "scriptArguments": "ThisIsMe.txt"
      }
    },
    {
      "id": "CPPSample",
      "executable": "CPPSample.exe",
      "workingDirectory": "",
      "startScript":
      {
        "scriptPath": "CPPStart.ps1",
        "scriptArguments": "ThisIsMe.txt",
        "runInVirtualEnvironment": true
      },
      "endScript":
      {
        "scriptPath": "CPPEnd.ps1",
        "scriptArguments": "ThisIsMe.txt",
        "runOnce": false
      }
    }
  ],
  "processes": [
    ...(taken out for brevity)
  ]
}