0

我正在尝试使用 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 ""
4

1 回答 1

0

在处理逻辑控制流问题时,最好从故事/描述开始:

我想开始卸载过程并等待它以成功或失败终止(通过打开具有适当标题的窗口来表示)

永远不要在条件下对真/假进行比较;那只是容易出错的脂肪。

不要依赖 VBscript 的智能来转换非布尔值;在条件句中使用适当(子)类型的变量/表达式。

请记住,VBScript 不会简化条件的计算:

If This() Or That() Then

将调用这两个函数,即使 This 返回 True(因此整个子句必须为 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
于 2012-08-28T22:23:53.867 回答