使用套件支援架構執行腳本

腳本可讓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 字串 否 空 空格分隔的參數清單。 PowerShell 腳本呼叫的格式相同。 這個字串會附加至 scriptPath ,以進行有效的 PowerShell.exe 呼叫。
runInVirtualEnvironment 布爾值 否 是 指定文稿是否應該在封裝應用程式執行所在的相同虛擬環境中執行。
runOnce 布爾值 否 是 指定腳本是否應在每個版本的每位使用者執行一次。
showWindow 布爾值 否 假的 指定是否顯示PowerShell視窗。
stopOnScriptError 布爾值 否 假的 指定啟動文稿失敗時是否要結束應用程式。
waitForScriptToFinish 布爾值 否 是 指定封裝的應用程式是否應該等候啟動腳本在啟動之前完成。
timeout DWORD 否 無限 允許腳本執行的時間是多久。 當時間經過時,腳本將會停止。

備註

不支援對範例應用程式設定 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)
  ]
}