脚本使 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 配置项。
| 密钥名称 | 值类型 | 必需? | 违约 | DESCRIPTION |
|---|---|---|---|---|
scriptPath |
字符串 | 是的 | 无 | 脚本的路径,包括名称和扩展。 如果指定,则路径相对于应用程序的工作目录,否则,它从包的根目录开始。 |
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)
]
}