重要更新:
正如Cheran在下面所述,是一个好主意,避免在这个脚本中使用"taskmgr“。我不打算编辑代码,因为我觉得最好尽可能地保留原来的问题,因为这样做会部分地使Cheran的回答和评论无效。。
一个替代"taskmgr“的好方法是"CharMap”(用于简单和快速的测试).
运行(32位),我得到了一个正在抛出此错误的脚本:
Script: C:\test.vbs
Line: 40
Char: 3
Error: 0x80041017
Code: 80041017
Source: (null)
下面是代码:
Set objWshShell = Wscript.CreateObject("Wscript.Shell")
Set objWshNet = CreateObject("Wscript.Network")
strComputer = objWshNet.ComputerName
Set objWMIService = GetObject("winmgmts:" & _
"{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Dim arrWinTitle(2)
arrWinTitle(0) = "My Documents"
arrWinTitle(1) = "Control Panel"
Dim arrProcName(3)
arrProcName(0) = "'taskmgr.exe'"
arrProcName(1) = "'calc.exe'"
arrProcName(2) = "'notepad.exe'"
Sub srBlockWindow(strWinTitle, intWinTitle, strProcName, intProcName)
i = 0
Do While i = 0
If objWshShell.AppActivate(strWinTitle(intWinTitle)) Then
objWshShell.AppActivate(strWinTitle(intWinTitle))
Wscript.Sleep 100
objWshShell.SendKeys "%{F4}"
Wscript.Sleep 100
End If
If intWinTitle = 0 Then
intWinTitle = intWinTitle + 1
Else
intWinTitle = 0
End If
Wscript.Sleep 100
Set colProcesses = objWMIService.ExecQuery _
("SELECT * FROM Win32_Process WHERE NAME = " & strProcName(intProcName))
For Each objProcess In colProcesses
objProcess.Terminate()
Next
If intProcName >= 0 Then
intProcName = intProcName + 1
ElseIf intProcName >= 5 Then
intProcName = 0
End If
Set colProcesses = Nothing
Loop
End Sub
Call srBlockWindow(arrWinTitle, 0, arrProcName, 0)
我已经复习过这,但我相信我的脚本对引号没有任何问题。为了清晰起见,我在“每一个.”开头都会出现错误。绳子。
奇怪的是,它将在第一次运行良好,但一旦它循环,这是我得到的错误。因此,它将关闭所有所需的Windows/应用程序,但一旦完成第二次迭代,我就会得到错误。我插入了“”,但这并不能解决这个问题(稍后我会添加它,因为当窗口/进程以脚本所做的关闭/结束/停止尝试同时启动时,它是解决冲突所必需的)。
--我认为这是因为我应该有条件地检查进程是否存在;问题是,我不太清楚如何使用这段代码(我从来没有很好地处理过集合)。有人对如何具体使用此代码执行此操作有建议吗?
我回顾了这,并试图编写一个快速的替代脚本,但它并没有真正起作用。下面是代码:
Set service = GetObject("winmgmts:")
Dim arrProcName(3)
arrProcName(0) = "'taskmgr.exe'"
arrProcName(1) = "'calc.exe'"
arrProcName(2) = "'notepad.exe'"
Sub srTest(strProc, intProc)
i = 0
Do While i = 0
For Each Process In Service.InstancesOf("Win32_Process")
If Process.Name = strProc(intProc) Then
Process.Name.Terminate
Process.Terminate
End If
Next
If intProc = 0 Then
intProc = intProc + 1
ElseIf intProc >= 3 Then
intProc = 0
End If
Loop
End Sub
Call srTest(arrProcName, 0)
正如您所看到的,我尝试了两个"Process.Terminate“& "Process.Name.Terminate",但是都没有产生任何结果(甚至不是一个错误)。我还用"Wscript.Echo Process.Name“和"Wscript.Echo strProc(intProc)”对其进行了测试,但这两种方法都不起作用。
现在我在这个替代解决方案上失败了,我觉得我在黑暗中疯狂地刺杀解决方案,所以我将把这些深奥的挑战推迟到比我优越得多的社区。
这里可能有几个人正在阅读这篇文章,并想知道为什么我要针对我的文档、控制面板、taskmgr.exe、calc.exe和notepad.exe。几乎每个阅读这篇文章的人可能都能自己推断,但我会确保我对那些需要它的人来说很清楚。我这样做是因为它使测试变得更容易,因为所有这些都可以通过使用"Run“快捷方式(Windows Key + R)来访问,然后输入以下字符串(当然,每次输入一个字符串):
您可能知道关键字,但我只想强调为什么我要使用这些特定的关键字(速度和简单性)。
,如果Cheran将最后的代码添加到发布的答案中,我将删除它
最后解决办法:
Set objWshShell = Wscript.CreateObject("Wscript.Shell")
Set objWshNet = CreateObject("Wscript.Network")
strComputer = objWshNet.ComputerName
Set objWMIService = GetObject("winmgmts:" & _
"{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Dim arrWinTitle
arrWinTitle = Array("My Documents", "Control Panel")
Dim arrProcName
arrProcName = Array("'charmap.exe'", "'calc.exe'", "'notepad.exe'")
Sub srBlockWindow(strWinTitle, intWinTitle, strProcName, intProcName)
i = 0
Do While i = 0
On Error Resume Next
' In the Event of Conflict w/Initiation of Window or Process
If objWshShell.AppActivate(strWinTitle(intWinTitle)) Then
objWshShell.AppActivate(strWinTitle(intWinTitle))
Wscript.Sleep 100
objWshShell.SendKeys "%{F4}"
Wscript.Sleep 100
End If
intWinTitle = (intWinTitle + 1) Mod (UBound(strWinTitle) + 1)
Wscript.Sleep 100
Set colProcesses = objWMIService.ExecQuery _
("SELECT * FROM Win32_Process WHERE NAME = " & strProcName(intProcName))
For Each objProcess In colProcesses
objProcess.Terminate()
Next
intProcName = (intProcName + 1) Mod (UBound(strProcName) + 1)
Set colProcesses = Nothing
Loop
End Sub
Call srBlockWindow(arrWinTitle, 0, arrProcName, 0)
下面是一个我拼凑在一起测试它的快速脚本:
Set objWshShell = Wscript.CreateObject("Wscript.Shell")
i = 0
Do While i = 0
objWshShell.Run "explorer.exe /e, C:\Documents and Settings\User\My Documents"
Wscript.Sleep 200
objWshShell.Run "CharMap.exe"
Wscript.Sleep 200
objWshShell.Run "Control.exe"
Wscript.Sleep 200
objWshShell.Run "calc.exe"
Wscript.Sleep 200
objWshShell.Run "notepad.exe"
Wscript.Sleep 200
Loop
小心点!调整时间,以便您可以结束"Wscript.exe“没有太多的问题。最好同时运行两个脚本,看看它是如何工作的。
发布于 2011-03-26 22:00:04
我发现了两大问题:
Array
函数初始化数组,前提是您事先知道数组中有多少元素。在这种情况下,您只需将arrWinTitle
声明为变体而不是数组:
Dim arrWinTitle arrWinTitle =Array(“我的文档”,“控制面板”)strProcName
的最大下标应该是2,而不是5。即使这样,这段代码也不能工作。似乎您要做的是循环遍历数组的元素,然后从0开始。这样做的一个更好方法是使用Mod
操作符:
intProcName = (intProcName + 1) Mod (UBound(strProcName) + 1)
还请注意如何使用UBound
函数来避免对数组的实际长度进行硬编码。我不会花太多时间来分析您的第二个示例,因为它只是尝试使第一个示例工作。但是,我要注意的是,在arrProcName
数组中,进程名仍然有单引号,这也是脚本无法工作的原因之一。
https://stackoverflow.com/questions/5438259
复制相似问题