WIX 安装程序从 CustomAction 执行 vbscript

WIX installer execute vbscript from CustomAction

我无法使用 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(作为 innerText),并添加属性:Script="vbscript"。但没有任何效果,每次我收到错误消息 - “此 Windows 安装程序包有问题。完成此安装所需的脚本不能 运行。联系您的支持人员或软件包供应商。"

日志文件中的错误:

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:

  1. 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.
  2. Reboot: The reboot you schedule must get a better condition to avoid unexpected reboots.
  3. 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. (look for yellow sections).

问题 1那一定是 VBA 脚本而不是 VBScript? 郑重声明:我没在 VBScript 中看到 return?在 VBScript 中,您 return 通过将函数名称设置为等于您想要的任何名称来 return,快速示例:

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 文件中可用的其他函数。因此,在上面的示例中,“IsEmptyString”可以从文件顶部的主 "nameless" 函数调用。

检查退出代码:最后,任何设置为检查退出代码的自定义操作都可以将您的设置放入 abort(立即模式)或 rollback(延迟模式)。如果自定义操作无法 必须 结束设置,我只会检查退出代码 运行。


问题 2:重新启动。在我看来,这是一个非常严重的问题。我见过有人因为在大规模部署期间导致意外重启而出局。重新启动知识工作者的 PC(和他们的经理),打开十几个 Visual Studio windows,打开几十个浏览器 windows 和 Word 和 Excel 等等。它会导致很多问题。他们可能知道你住在哪里! :-)

请阅读以下答案(至少开头的 3 个要点):


问题 3:进程终止。如上所述,终止进程与重启问题有关。如果进程符合 Windows 重新启动管理器,则并不总是需要终止进程,如上面 link 中所述。 (黄色部分应该给你它的要点 - 特别是我认为的第二个)。

有几种不同的方法可以终止进程。请注意,最常见的问题可能是您没有终止进程的访问权限和/或特权 - 无论您使用什么工具或方法来这样做。

也许您可以尝试 Util 架构中的 CloseApplication 功能http://wixtoolset.org/documentation/manual/v3/xsd/util/closeapplication.html

我不确定推荐这些选项中的哪一个。我不喜欢完全终止进程的概念,但有时我猜没有其他选择。