VBScript关闭应用程序不工作

VBScript关闭应用程序不工作,vbscript,Vbscript,我目前正在学习VBScript,我编写此脚本只是为了练习,在一个脚本中关闭多个应用程序(记事本和计算器)时遇到问题。当我在单独的脚本中运行应用程序时,它们会关闭。但当我在这个脚本中把所有内容结合在一起时,它们并没有结束。我是否在WMI服务中出错 '*** calc.vbs *** Set WshShell = CreateObject("WScript.Shell") WshShell.Run "calc" WScript.Sleep 1500 WshShell.AppActivate

我目前正在学习VBScript,我编写此脚本只是为了练习,在一个脚本中关闭多个应用程序(记事本和计算器)时遇到问题。当我在单独的脚本中运行应用程序时,它们会关闭。但当我在这个脚本中把所有内容结合在一起时,它们并没有结束。我是否在WMI服务中出错

'*** calc.vbs ***

Set WshShell = CreateObject("WScript.Shell")

WshShell.Run "calc"

WScript.Sleep 1500

WshShell.AppActivate "Calculator"

WScript.Sleep 1500

WshShell.SendKeys "5"

WScript.Sleep 1000

WshShell.SendKeys "{+}"

WScript.Sleep 1000

WshShell.SendKeys "10{+}"

WScript.Sleep 1000

WshShell.SendKeys "12"

WScript.Sleep 1000

WshShell.SendKeys "{=}"

WScript.Sleep 5000

strComputer = "."

Set objWMIService = GetObject("winmgmts:" _

    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

Set colProcessList = objWMIService.ExecQuery("SELECT * FROM Win32_Process 

Where Name = 'calc.exe'")

For Each objProcess In colProcessList

    objProcess.Terminate

Next

'*** notepad.vbs ***

WScript.Sleep 5000

WshShell.Run "notepad"

WshShell.AppActivate "Untitled - Notepad"

WScript.Sleep 1000

WshShell.SendKeys "This is the first line "

WScript.Sleep 1000

WshShell.SendKeys "~" ' same as {Enter}

WScript.Sleep 1000

WshShell.SendKeys "This is the second line"

WScript.Sleep 1000

WshShell.SendKeys "{Enter}"

WScript.Sleep 1000

WshShell.SendKeys "This is the third line"

WScript.Sleep 5000

Set colProcessListt = objWMIService.ExecQuery("SELECT * FROM Win32_Process 

Where Name = 'notepad.exe'")

For Each objProcesss In colProcessListt

    objProcesss.Terminate

Next

您的问题是由一个好的(
选项Explicit
)和一些非常坏的(错误恢复下一步时全局
)、顶部长列表中的变暗变量/远离它们的实际使用以及疯狂的变量名(objProcess、objProcess等等)的组合造成的。为了说明这一点,我将使用一种非常简单的技术来保存“一个文件中有许多不同的有趣代码”

Option Explicit

' global consts and variables (not needed here)

' poor man's dispatch; use re-order or comments to choose current piece of work
WScript.Quit Literals()
WScript.Quit CloseCalcBad()
WScript.Quit CloseCalc()
WScript.Quit BadVars()

' can do literals; even date literals; have thought about Locale
Function Literals()
  Literals = 1
  Dim literalNumeric : literalNumeric = 20
  Dim literalString : literalString = "BeachBall"
  Dim literalDate : literalDate = #1/2/3#
  WScript.Echo "literalNumeric 20:", literalNumeric
  literalNumeric = 12.34
  WScript.Echo "literalNumeric 12.34:", literalNumeric, GetLocale()
  WScript.Echo "literalString: ""BeachBall""", literalString
  WScript.Echo "literalDate #1/2/3#:", literalDate, GetLocale()
  Literals = 0
End Function

' can't work with undefined vars like strComputer etc.
Function CloseCalcBad()
  CloseCalcBad = 1
  WScript.Echo "CloseCalcBad()"
  Dim WshShell : Set WshShell = CreateObject("WScript.Shell")
  WScript.Echo "start calc"
  WshShell.Run "calc"
  WScript.Echo "waiting"
  WScript.Sleep 5000

  WScript.Echo "trying to close"
  On Error Resume Next
' if you comment out the (evil) OERN, you'll get
' Microsoft VBScript runtime error: Variable is undefined: 'strComputer'
  strComputer = "."
  Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
  Set colProcessList = objWMIService.ExecQuery("SELECT * FROM Win32_Process Where Name = 'calc.exe'")
  For Each objProcess In colProcessList
      WScript.Echo "in loop"
      WScript.Echo TypeName(objProcess)
      objProcess.Terminate
  Next
  WScript.Echo "done"
  CloseCalcBad = 0
End Function

' no OERN, no undefined vars, IT WORKS!
Function CloseCalc()
  CloseCalc = 1
  WScript.Echo "CloseCalc()"
  Dim WshShell : Set WshShell = CreateObject("WScript.Shell")
  WScript.Echo "start calc"
  WshShell.Run "calc"
  WScript.Echo "waiting"
  WScript.Sleep 5000

  WScript.Echo "trying to close"
  Dim strComputer : strComputer = "."
  Dim objWMIService : Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
  Dim colProcessList : Set colProcessList = objWMIService.ExecQuery("SELECT * FROM Win32_Process Where Name = 'calc.exe'")
  Dim objProcess
  For Each objProcess In colProcessList
      WScript.Echo "in loop"
      WScript.Echo TypeName(objProcess)
      objProcess.Terminate
  Next
  WScript.Echo "done"
  CloseCalc = 0
End Function

' it's difficult to keep track of bad vars (undefined vars hidden by OERN)
Function BadVars()
  BadVars = 1
  Dim s1 : s1 = "Prefix"
 On Error Resume Next
  s2 = "Suffix"
  WScript.Echo "s1:", s1
  WScript.Echo "s2:", s2 ' statement/line skipped, because s2 can't be accessed
  WScript.Echo "where did s2 output go?"
  BadVars = 0
End Function
这样的脚本处理(短)函数中的不同主题/问题,这些函数将1(失败)或0(成功)返回到顶层代码(并从那里返回到操作系统)。通过重新排序或评论,您可以选择当前正在处理的特殊功能/主题/问题。如果一个问题导致另一个问题,您可以添加一个函数,开发一个解决方案,测试它,然后返回到您开始使用的函数

因为函数可以很短,而且切中要害,所以建议您在使用前使用局部变量并将其调暗;不需要有趣的名字

函数的开头是您的代码;我添加了日期文字来演示如果您学到了一些新东西,如何重构/改进/增强函数

CloseCalcBad()-及其输出:

cscript 41169790.vbs
CloseCalcBad()
start calc
waiting
trying to close
in loop
done
显示OERN隐藏“未定义变量”错误,跳过使用坏变量的语句/行(
WScript.Echo TypeName(objProcess)
),但自豪地显示诊断输出,如“完成”

CloseCalc()使使用的变量变暗,因此关闭Calc-输出:

cscript 41169790.vbs
CloseCalc()
start calc
waiting
trying to close
in loop
SWbemObjectEx   <-- have something to terminate!
done

在不增加WMI复杂性的情况下显示邪恶的全局OERN。

这里有一个大的代码转储,其中99%与我的问题无关。你能把它翻个底朝天,找出与我的问题实际相关的三、四行吗?这个网站的工作原理不太清楚。请花几分钟阅读如何创建一个新的,然后回来和你的文章,以摆脱所有不相关的噪音,留下最少的代码来演示你的问题。谢谢。我已经将代码简化为我的问题。很抱歉,下次我会知道的更多。非常感谢你的反馈,这很清楚,很中肯,现在我明白了,非常感谢。
cscript 41169790.vbs
s1: Prefix
where did s2 output go?