我正在尝试使用VBS脚本以编程方式卸载ClickOnce应用程序。它工作得很好。但如果卸载失败,我希望它发送响应“应用程序已被删除”。
以下是我到目前为止所做的,并且它在很大程度上起作用。有时延迟时间不够长,或者其他窗口窃取焦点,而sendkeys的“OK”不会进入窗口。
---完整源代码---
On Error Resume Next
Set objShell = WScript.CreateObject("WScript.Shell")
objShell.Run "taskkill /f /im TEST.App.UI.exe*"
objShell.Run "rundll32.exe dfshim.dll,ShArpMaintain test.app.ui.application, Culture=neutral, PublicKeyToken=f77d770cef, processorArchitecture=msil"
Do Until Success = True
Success = objShell.AppActivate("Test App")
Wscript.Sleep 500
Loop
objShell.SendKeys "OK"
'Commented out on purpose
'install new
'objShell.Run ""
答案 0 :(得分:0)
在解决逻辑控制流的问题时,最好从a开始 故事/说明:
我想启动卸载过程并等待它终止 成功或失败(通过打开一个窗口表示 适当的标题)
永远不要在条件中使用与True / False的比较;这只是容易出错的 脂肪
不要依赖VBscript的智能来转换非布尔值;使用 条件中适当(子)类型的变量/表达式。
请记住,VBScript不会快速评估条件:
If This() Or That() Then
将调用这两个函数,即使This返回True(因此也是如此) 整个条款必须是真的)。所以不要试图这样做:
... Until (objShell.AppActivate("Uninstall - Success") Or _
objShell.AppActivate("Uninstall - Failure"))
在设计循环时,请考虑何时应进行休假检查;如果 你想从一个可能空的文件中读取,有必要提前检查:
Do Until tsIn.AtEndOfStream
sLine = tsIn.ReadLine()
...
Loop
但如果您想从用户那里获得有效的输入,您必须先询问 你可以查一下:
Do
sInp = ...
Loop While isBad(sInp)
.AppActivate和.SendKeys是每个程序员的敌人;推迟战斗 反对他们,直到你解决了控制流问题。
在代码中:
' Wait Wait Fail Success
' , Array(False, False, True , True ) _ shouldn't happen, but will terminate too
Dim aHappenings : aHappenings = Array( _
Array(False, False, False, True ) _
, Array(False, False, True , False) _
)
Dim aTest
For Each aTest In aHappenings
WScript.Echo Join(aTest)
Dim bOk : bOk = False
Dim bFail : bFail = False
Dim i : i = 0
Do
bOk = aTest(i + 0)
bFail = aTest(i + 1)
WScript.Echo Join(Array(" ", i, bOk, bFail))
i = i + 2
Loop Until bOk Or bFail
WScript.Echo "Done."
WScript.Echo
Next
输出:
False False False True
0 False False
2 False True
Done
False False True False
0 False False
2 True False
Done.
你可以利用这样一个事实,即成功或失败(不是两者)都会发生:
Dim i : i = 0
Dim bDone
Do
bDone = aTest(i + 0)
If Not bDone Then
bDone = aTest(i + 1)
End If
WScript.Echo Join(Array(" ", i, bDone))
i = i + 2
Loop Until bDone