我无法使用 WIX 安装程序执行 VBScript。目前我有 WiX 配置的这一部分:
<Binary Id='KillThatProcessBinary' SourceFile='KillThatProcess.vbs' />
<CustomAction Id="KillThatProcessAction"
Execute="immediate"
BinaryKey='KillThatProcessBinary'
VBScriptCall='KillThatProcessFunction'
Return="check"/>
<InstallExecuteSequence>
<Custom Action='KillThatProcessAction' Before='InstallValidate'/>
<ScheduleReboot After="InstallFinalize"/>
</InstallExecuteSequence>
这个 VBS 脚本 (KillThatProcess.vbs
):
Public Function KillThatProcessFunction()
Set oShell = WScript.CreateObject("WSCript.shell")
oShell.run "cmd /C wmic process where ""name like '%java%'"" delete"
Return 0
End Function
我已经尝试将此脚本插入到 CustomAction 中(作为 insideText),并添加属性:Script="vbscript"。但每次我收到错误消息时,什么都不起作用 - “此 Windows Installer 程序包存在问题。无法运行完成此安装所需的脚本。请联系您的支持人员或程序包供应商。”
日志文件中的错误:
Error 0x80070643: Failed to install MSI package.
[1A88:2FA4][2018-08-21T14:11:17]e000: Error 0x80070643: Failed to configure per-user MSI package.
[1A88:2FA4][2018-08-21T14:11:17]i319: Applied execute package: LPGateway, result: 0x80070643, restart: None
[1A88:2FA4][2018-08-21T14:11:17]e000: Error 0x80070643: Failed to execute MSI package.
我已经执行了这个 vbs 脚本(不是来自安装程序)并且它可以工作。有人知道我做错了什么吗?
最佳答案
<小时/>There are a few issues I want to summarize:
- VBA & VBScript Functions: That VBScript looks like it is actually VBA and calling VBScript in an MSI requires a bit of tweaking to call VBScript functions properly.
- Reboot: The reboot you schedule must get a better condition to avoid unexpected reboots.
- Process Kill: What process are you trying to kill?
- Elevation: If it is elevated you need to run the kill elevated for it to succeed. Your per-user setup is likely not set to elevate at all (so you can generally only end processes running as yourself).
- Restart Manager: Very often you do not need to kill processes, due to the Restart Manager feature of Windows that Windows Installer tries to use. Attempt to explain this feature (look for yellow sections).
问题 1:那一定是 VBA 脚本而不是 VBScript?郑重声明:我还没见过 VBScript 中的返回
?在 VBScript 中,您可以通过将函数名称设置为您想要返回的任何内容来从函数返回,快速示例:
result = IsEmptyString("")
MsgBox CStr(result)
Function IsEmptyString(str)
If str = "" Then
IsEmptyString = True
Else
IsEmptyString = False
End If
End Function
Note: The above is just a silly, rather meaningless example. For more elaborate checking try IsBlank from ss64.com. VBScript comes with the functions IsEmpty and IsNull and IsObject.
当在MSI文件中使用时,我通常不会在VBScript中添加函数,而是直接运行脚本,所以运行这个VBScript应该可以工作:
MsgBox(Session.Property("ProductName"))
将其插入 WiX 源(注意未指定函数调用):
<Binary Id='Sample.vbs' SourceFile='Sample.vbs' />
<CustomAction Id='Sample.vbs' VBScriptCall='' BinaryKey='Sample.vbs' Execute='immediate' Return='ignore'/>
至关重要的是,您的 VBScript 仍然可以调用同一 VBScript 文件中可用的其他函数。因此,在上面的示例中,可以从文件顶部的主“nameless”函数调用“IsEmptyString”。
检查退出代码:最后,任何设置为检查退出代码的自定义操作都可能使您的设置进入中止(立即模式)或回滚(延迟模式)。如果自定义操作无法运行,您必须结束设置,我只会检查退出代码。
<小时/>问题 2:重新启动。在我看来,这是一个非常严重的问题。我见过有人因为在大规模部署期间导致意外重启而被赶出家门。在打开十几个 Visual Studio 窗口、几十个浏览器窗口以及 Word 和 Excel 的情况下重新启动知识 worker 的 PC(及其经理)。它可能会导致很多问题。他们可能知道你住在哪里! :-)
请阅读以下答案(至少开头的 3 个要点): Reboot on install, Don't reboot on uninstall
<小时/>问题 3:进程终止。如上所述,进程的终止与重新启动问题有关。如果进程符合 Windows 重新启动管理器的要求,则并不总是需要终止进程,如上面的链接所述。 Let me repeat it here (黄色部分应该告诉你它的要点 - 特别是我认为的第二个部分)。
有几种不同的方法可以终止进程。请注意,最常见的问题可能是您没有访问权限和/或特权来终止进程 - 无论您使用什么工具或方法来执行此操作。
也许您可以尝试 Util 架构中的CloseApplication 功能:http://wixtoolset.org/documentation/manual/v3/xsd/util/closeapplication.html
- In Wix MSI: Killing a process upon uninstallation
- Kill windows service forcefully in WIX (向底部)
- 使用 WMI / VBScript 终止进程
- 有些人结合taskill.exe and WiX通过Quiet Execution Custom Action (CAQuietExec:隐藏命令行窗口)。 FireGiant documentation .
我不确定推荐哪些选项。我不喜欢完全终止进程的概念,但有时我想没有其他选择。
关于java - WIX 安装程序从 CustomAction 执行 vbscript,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51947460/