ВАЖНОЕ ОБНОВЛЕНИЕ:
Как Cheran S заявил ниже, это хорошая идея, чтобы избежать использования «taskmgr» для этого скрипта. Я не собираюсь редактировать код, так как считаю, что лучше сохранить исходный вопрос в максимально возможной степени, поскольку это частично аннулирует и запутывает ответ и комментарий Черана.
Хорошей альтернативой «taskmgr» будет «CharMap» (для простого и быстрого тестирования).
<ч />
Запуск 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)
Я просмотрел это , но я считаю, что у моего скрипта нет проблем с кавычками. Для ясности я получаю сообщение об ошибке в начале строки "For Each ...".
Что особенного в том, что он будет работать нормально с первого раза, но как только он зациклится, вот когда я получаю ошибку. Таким образом, он закроет все нужные Windows / приложения, но как только он пройдет вторую итерацию, я получу ошибку. Я вставил «On Error Resume Next», но это не решает проблему (я добавлю его позже, так как это необходимо для разрешения конфликта, когда Window / Process запускается одновременно с попытками Close / End / Stop, выполненными сценарием ).
Я думаю, это потому, что я должен условно проверить, существует ли процесс; проблема в том, что я не совсем уверен, как это сделать с этим кодом (я никогда не был хорош с коллекциями). У кого-нибудь есть предложения, как это сделать с этим кодом конкретно?
<ч />
Я просмотрел это и попытался написать быстрый альтернативный скрипт, но он не сработал. Вот код:
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 Key + R), а затем вводя следующие строки (по одной, разумеется):
- Мои документы
- Контроль
- Урочная
- известково
- блокнот
Вы, вероятно, знали ключевые слова, но я просто хотел выделить , почему Я использую эти конкретные (скорость и простота).
<ч />
Я уберу это, если Черан добавит окончательный код к опубликованному ответу
Окончательное решение:
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 без особых проблем. Лучше всего запустить оба сценария одновременно, чтобы увидеть, как он работает.