VBScript-错误0x80041017(空)
重要更新: 正如Cheran S在下面所述,最好避免在这个脚本中使用“taskmgr”。我不打算编辑代码,因为我觉得最好尽可能多地保留原始问题,因为这样做会使Cheran的回答和评论部分无效和混淆。 替代“taskmgr”的一个好方法是“CharMap”(用于简单快速的测试)。VBScript-错误0x80041017(空),vbscript,windows-xp,Vbscript,Windows Xp,重要更新: 正如Cheran S在下面所述,最好避免在这个脚本中使用“taskmgr”。我不打算编辑代码,因为我觉得最好尽可能多地保留原始问题,因为这样做会使Cheran的回答和评论部分无效和混淆。 替代“taskmgr”的一个好方法是“CharMap”(用于简单快速的测试)。 运行Windows XP Professional(32位)时,我有一个脚本抛出了这个错误: Script: C:\test.vbs Line: 40 Char: 3 Error: 0x800
运行Windows XP Professional(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)
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)
我已经复习过了,但我相信我的脚本在引用方面没有任何问题。为了清楚起见,我在“For Each…”字符串的开头得到了错误
奇怪的是,它在第一次运行时会运行良好,但一旦循环,我就会得到错误。因此,它将关闭所有需要的窗口/应用程序,但一旦它通过第二次迭代,我就会得到错误。我插入了“On Error Resume Next”(错误时继续下一步),但这并不能解决问题(我稍后会添加它,因为当窗口/进程与脚本的关闭/结束/停止尝试同时启动时,需要它来解决冲突)
我认为这是因为我应该有条件地检查流程是否存在;问题是,我不太确定如何使用这段代码(我从来都不擅长收集)。有人对如何具体使用此代码有什么建议吗?
我回顾并试图写一个快速的替代脚本,但它并没有真正起作用。代码如下:
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)
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上。几乎每一个读到这篇文章的人都有可能自己推断,但我会确保我对那些需要它的人清楚这一点。我这样做是因为它使测试更容易,因为所有这些都可以通过使用“运行”快捷方式(Windows键+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”时不会出现太多问题。最好同时运行这两个脚本,看看它是如何工作的。我发现了两个大问题:
' This is wrong:
Dim arrWinTitle(2)
Dim arrProcName(3)
' Should be:
Dim arrWinTitle(1)
Dim arrProcName(2)
如果事先知道数组中有多少个元素,也可以使用该函数初始化数组。在这种情况下,您只需将arrWinTitle
声明为变量,而不是数组:
Dim arrWinTitle
arrWinTitle = Array("My Documents", "Control Panel")
If intProcName >= 0 Then
intProcName = intProcName + 1
ElseIf intProcName >= 5 Then
intProcName = 0
End If
首先,strProcName的最大下标应该是2,而不是5。即使这样,这个代码也不会工作。看起来您要做的是循环遍历数组的元素,然后在0处重新开始。更好的方法是使用操作员:
intProcName = (intProcName + 1) Mod (UBound(strProcName) + 1)
还要注意我如何使用该函数来避免对数组的实际长度进行硬编码' This is wrong:
Dim arrWinTitle(2)
Dim arrProcName(3)
' Should be:
Dim arrWinTitle(1)
Dim arrProcName(2)
我不会花太多时间分析你的第二个例子,因为它只是试图让第一个例子起作用。但是,我要注意的是,在
arrProcName
数组中,进程名的周围仍然有单引号,这也是该脚本无法工作的原因之一。当脚本应该在无限循环中运行时,您可能不想使用“taskmgr.exe”作为示例进程名,尤其是在社区网站上发布时。如何停止“wscript.exe”进程?(当然,我只是在运行代码而没有首先检查它,这让我感到羞耻…@Cheran S-LOL,对不起;我有退路了。我从来没有考虑过这个问题,原因有两个:(1)我没有工作代码,rofl。(2) 我在运行对话框中使用此命令:TaskKill/Im Wscript.exe/F
。有一个警告:我运行的是XP Professional客户端,“TaskKill”命令只适用于XP Pro。XP Home的替代方案是TsKill Wscript
。我相信这一原则适用于所有家庭版和专业版(XP/Vista/7)。再一次抱歉,呜呜!关于你的第二点,我完全忘记了将ElseIf字符串编辑为2!我使用了更多的项目进行原型设计,并从第二个阵列中删除了一些项目,但我没有清理交互代码块。给我一些时间来消化你的文章,因为你对数组函数、Mod操作符和UBound函数的使用对我来说都是新的(感谢你记住我是一个完全的新手&添加了那些资源链接!)。在我测试并弄清楚整个脚本应该是什么样子之后,我会确保给您打上“复选标记”。你不必像上次那样等那么久,