使用包支持框架运行脚本Run scripts with the Package Support Framework

使用脚本,IT 专业人员可以在使用 .MSIX 打包后,向用户的环境动态自定义应用程序。Scripts enable IT Pros to customize an application dynamically to the user's environment after it is packaged using MSIX. 例如,你可以使用脚本来配置数据库、设置 VPN、装载共享驱动器或动态执行许可证检查。For example, you can use scripts to configure your database, set up a VPN, mount a shared drive, or perform a license check dynamically. 脚本提供了很大的灵活性。Scripts provide a lot of flexibility. 它们可能会更改注册表项或基于计算机或服务器配置执行文件修改。They may change registry keys or perform file modifications based on the machine or server configuration.

你可以使用包支持框架 (PSF) 在打包的应用程序可执行文件运行之前运行一个 PowerShell 脚本,并在运行应用程序可执行文件后运行一个 PowerShell 脚本以进行清理。You can use the Package Support Framework (PSF) to run one PowerShell script before a packaged application executable runs and one PowerShell script after the application executable runs to clean up. 在应用程序清单中定义的每个应用程序可执行文件都可以有自己的脚本。Each application executable defined in the application manifest can have its own scripts. 您可以将脚本配置为仅在第一次应用程序启动时运行一次,而不显示 PowerShell 窗口,使用户不会错误地提前结束该脚本。You can configure the script to run once only on the first app launch and without showing the PowerShell window so users won't end the script prematurely by mistake. 还有其他选项可用于配置脚本的运行方式,如下所示。There are other options to configure the way scripts can run, shown below.

先决条件Prerequisites

若要使脚本能够运行,需要将 PowerShell 执行策略设置为 RemoteSignedTo enable scripts to run, you need to set the PowerShell execution policy to RemoteSigned. 可以通过运行以下命令来执行此操作:You can do this by running this command:

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned

需要为64位 PowerShell 可执行文件和32位 PowerShell 可执行文件设置执行策略。The execution policy needs to be set for both the 64-bit PowerShell executable and the 32-bit PowerShell executable. 请确保打开每个版本的 PowerShell,并运行上面所示的其中一个命令。Make sure to open each version of PowerShell and run one of the commands shown above.

下面是每个可执行文件的位置。Here are the locations of each executable.

  • 64 位计算机:64-bit computer:
    • 64位可执行文件:% SystemRoot% \system32\WindowsPowerShell\v1.0\powershell.exe64-bit executable: %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe
    • 32位可执行文件:% SystemRoot% \SysWOW64\WindowsPowerShell\v1.0\powershell.exe32-bit executable: %SystemRoot%\SysWOW64\WindowsPowerShell\v1.0\powershell.exe
  • 32 位计算机:32-bit computer:
    • 32位可执行文件:% SystemRoot% \system32\WindowsPowerShell\v1.0\powershell.exe32-bit executable: %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe

有关 PowerShell 执行策略的详细信息,请参阅 此文For more information about PowerShell execution policies, see this article.

确保还在包中包含 StartingScriptWrapper.ps1 文件,并将其放在可执行文件所在的同一文件夹中。Make sure to also include the StartingScriptWrapper.ps1 file in your package and place it in the same folder as your executable. 可以从 PSF NuGet 包复制此文件。You can copy this file from the PSF NuGet package.

启用脚本Enable scripts

若要指定将为每个打包的应用程序可执行文件运行的脚本,需要修改 文件上的config.jsTo specify what scripts will run for each packaged application executable, you need to modify the config.json file. 若要告诉 PSF 在执行打包应用程序之前运行脚本,请添加名为的配置项目 startScriptTo tell PSF to run a script before the execution of the packaged application, add a configuration item called startScript. 若要告诉 PSF 在打包的应用程序完成后运行脚本,请添加名为的配置项目 endScriptTo tell PSF to run a script after the packaged application finishes add a configuration item called endScript.

编写配置项目脚本Script configuration items

以下是可用于脚本的配置项目。The following are the configuration items available for the scripts. 结束脚本将忽略 waitForScriptToFinishstopOnScriptError 配置项目。The ending script ignores the waitForScriptToFinish and stopOnScriptError configuration items.

项名Key name 值类型Value type 必需?Required? 默认Default 说明Description
scriptPath stringstring Yes 空值N/A 脚本的路径,包括名称和扩展名。The path to the script including the name and extension. 路径相对于应用程序的工作目录(如果已指定),否则在包的根目录处启动。The path is relative to the application's working directory if specified, otherwise, it starts at the root directory of the package.
scriptArguments stringstring No emptyempty 空格分隔参数列表。Space delimited argument list. 对于 PowerShell 脚本调用,格式是相同的。The format is the same for a PowerShell script call. 此字符串将追加到 scriptPath ,以便进行有效的 PowerShell.exe 调用。This string gets appended to scriptPath to make a valid PowerShell.exe call.
runInVirtualEnvironment booleanboolean No true 指定是否应在打包应用程序运行所在的虚拟环境中运行脚本。Specifies whether the script should run in the same virtual environment that the packaged application runs in.
runOnce booleanboolean No true 指定脚本是否应每个用户每个版本运行一次。Specifies whether the script should run once per user, per version.
showWindow booleanboolean No falsefalse 指定是否显示 PowerShell 窗口。Specifies whether the PowerShell window is shown.
stopOnScriptError booleanboolean No falsefalse 指定在启动脚本失败时是否退出应用程序。Specifies whether to exit the application if the starting script fails.
waitForScriptToFinish booleanboolean No true 指定打包的应用程序在启动前是否应等待开始脚本完成。Specifies whether the packaged application should wait for the starting script to finish before starting.
timeout DWORDDWORD No INFINITEINFINITE 允许脚本执行的时间长度。How long the script will be allowed to execute. 当时间结束时,脚本将停止。When the time elapses, the script will be stopped.

备注

stopOnScriptError: true waitForScriptToFinish: false 不支持为示例应用程序设置和。Setting stopOnScriptError: true and waitForScriptToFinish: false for the sample application is not supported. 如果你设置这两个配置项目,则 PSF 将返回 ERROR_BAD_CONFIGURATION 的错误。If you set both of these configuration items, PSF will return the error ERROR_BAD_CONFIGURATION.

示例配置Sample configuration

下面是使用两个不同的应用程序可执行文件的示例配置。Here is a sample configuration using two different application executables.

{
  "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)
  ]
}