2016-12-15 142 views
-2

我目前正在学习VBScript,而且我已经编写了这个脚本来练习,而且我在一个脚本中遇到了关闭多个应用程序(记事本和计算器)的问题。当我在单独的脚本中自行运行应用程序时,它们会关闭。但是当我将这些脚本中的所有内容合并在一起时,它们并没有关闭我的WMI服务有问题吗?VBScript关闭应用程序不工作

'*** 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 
+1

*这是一个大的代码转储,其中99%与我的问题无关。你可以通过它来试图找到与我的问题实际相关的三条或四条线吗?*本网站的工作方式并不完全相同。请花几分钟时间阅读关于如何创建[mcve]的信息,然后返回并[编辑]您的信息以摆脱所有无关紧要的噪音,并留下所需的**最小代码**,重新拥有。谢谢。 –

+0

我已经减少了我的问题所属的代码。对不起,转储下次会更好。 –

回答

1

你的问题是一个很好的(Option Explicit)共同造成的,有些很糟糕(全球On Error Resume Next,在顶部/远离自己的实际使用,以及疯狂的变量名(objProcess调光长列表变量, objProcesss,...))的东西。为了表明这一点,我将使用一种非常简单的技术来在一个文件中保存许多不同的有趣代码片段。

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(成功)到顶级代码(和从那里到OS)的问题。通过重新排序或评论,您可以选择当前正在处理的特殊功能/主题/问题。如果问题导致另一个问题,您可以添加一个函数,开发一个解决方案,测试它,然后返回到您开始使用的函数。

因为函数可能很短并且很重要,所以鼓励您在使用之前使用局部变量并将其调暗;不需要有趣的名字。 ()函数从你的代码开始;我添加了日期文字来演示如何在重新学习新内容时重构/改进/增强函数。

CloseCalcBad() - 和其输出:

cscript 41169790.vbs 
CloseCalcBad() 
start calc 
waiting 
trying to close 
in loop 
done 

表明OERN隐藏 “VAR没有定义” 的错误,跳过其中使用坏VARS语句/线(WScript.Echo TypeName(objProcess)),但呈献诊断输出像“完成”。

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

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

我包括BadVars() -

cscript 41169790.vbs 
s1: Prefix 
where did s2 output go? 

展现邪恶全球OERN没有WMI的额外的复杂性。

+0

非常感谢您的反馈,它很清楚,并且现在我明白了,非常感谢。 –