使用包支持框架运行脚本

通过脚本,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 包或PSF Github NuGet复制此文件

启用脚本

若要指定将为每个打包的应用程序可执行文件运行哪些脚本,需要修改config.js 的脚本。 若要告知 PSF 在执行打包的应用程序之前运行脚本,请添加名为 的配置项目 startScript 。 若要告知 PSF 在打包的应用程序完成后运行脚本,请添加名为 的配置项目 endScript

编写配置项目脚本

下面是可用于脚本的配置项目。 结束脚本将忽略 waitForScriptToFinishstopOnScriptError 配置项。

项名称 值类型 必需? 默认 说明
scriptPath string 不适用 脚本的路径,包括名称和扩展名。 如果指定路径,则路径相对于应用程序的工作目录;否则,它从包的根目录开始。
scriptArguments string empty 空格分隔参数列表。 PowerShell 脚本调用的格式相同。 此字符串将追加到 scriptPath ,以在调用PowerShell.exe有效。
runInVirtualEnvironment boolean 指定脚本是否应该在打包应用程序运行的同一虚拟环境中运行。
runOnce boolean 指定脚本是否应该按每个用户、每个版本运行一次。
showWindow boolean false 指定是否显示 PowerShell 窗口。
stopOnScriptError boolean false 指定在启动脚本失败时是否退出应用程序。
waitForScriptToFinish boolean 指定打包的应用程序是否应该在启动前等待启动脚本完成。
timeout DWORD 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)
  ]
}