Показать полную графическую версию : проблема с WScript.Shell.Exec
morebeauty
12-11-2013, 08:01
Доброго дня.
Есть скрипт:
set WshShell = WScript.CreateObject("WScript.Shell")
Set cmdl = WshShell.Exec("cmd")
do 'Цикл для того, чтобы cmd не завершалось после окончания скрипта, а иначе гаснет сразу как запускается
loop while cmdl.Status=0
Запускает cmd.exe, но при этом вместо привычного приглашения ввести команды "C:\*****>" видно только черный экран. !!!
Пробовал вместо cmd запускать ping "ipaddress"
так же вижу черный экран, но по завершению отправки стандартных четырех пакетов окно закрывается (то есть обработка команд таки идет, только ничего не отображается)
Оконные приложения типа calc открываются и работают нормально, причем для них даже не нужна конструкция do...loop
С Run все отрабатывает нормально, но при таком способе я не имею в наличии объект запускаемого приложения (то есть не могу никак им управлять), поэтому нужен именно Exec.
Помогите разобраться.
Заранее спасибо!
Запускает cmd.exe, но при этом вместо привычного приглашения ввести команды "C:\*****>" видно только черный экран. !!! »
morebeauty, всё так. А Вы ожидали увидеть нечто иное?! Зачем Вам «.Exec()»? Что Вы понимаете под возможностью «управлять»?
morebeauty
12-11-2013, 10:24
Зачем Вам «.Exec()»? Что Вы понимаете под возможностью «управлять»? »
Значит выполнить Terminate(), перехватить вывод (stdOut), выполнить ввод (stdIn).
Этого достаточно?
Первое можно выполнить и после «.Run()». А второе и третье — да, только «.Exec()». Но Вы не ответили на:
А Вы ожидали увидеть нечто иное?! »
Что Вы ожидали/хотели увидеть? Т.е., что не так?
morebeauty
12-11-2013, 11:02
Что Вы ожидали/хотели увидеть? Т.е., что не так? »
Запускает cmd.exe, но при этом вместо привычного приглашения ввести команды "C:\*****>" видно только черный экран. »
То есть ожидал полноценную командную строку с возможностью ввода/вывода.
Скажите, а Вы совсем не догадывались что именно я ожидал увидеть? А если у Вас были догадки, скажите, среди них была "открывая командную строку ожидал увидеть немецкое порно"? :)
morebeauty
12-11-2013, 12:39
Ожидал
cmd2.PNG
Увидел
cmd1.PNG
Скажите, а Вы совсем не догадывались что именно я ожидал увидеть? А если у Вас были догадки, скажите, среди них была "открывая командную строку ожидал увидеть немецкое порно"? »
Нет, на это моей фантазии не хватило.
То есть ожидал полноценную командную строку с возможностью ввода/вывода. »
Вы и получили полноценную командную строку с возможностью ввода/вывода. Программного — поскольку потоки ввода, вывода и ошибок (stdin, stdout, stderr) перехвачены. Поскольку перехвачен поток вывода — вывод идёт к объекту WshExec, а не на консоль — посему Вы не видите вывод в окне консоли. Поскольку перехвачен поток ввода — ввод ожидается от объекта WshExec, а не из консоли — посему Вы не можете осуществить ввод в окно консоли: этот ввод некому обрабатывать. С потоком ошибок аналогично потоку вывода.
Пример программной работы с потоками дочернего консольного приложения:
Option Explicit
Const WshRunning = 0
Const WshFinished = 1
Const WshFailed = 2
Dim objWshShell
Dim objWshExec
Dim strStdOut
Dim strStdErr
Set objWshShell = WScript.CreateObject("WScript.Shell")
Set objWshExec = objWshShell.Exec("""%comspec%"" /k")
If objWshExec.Status <> WshFailed Then
objWshExec.StdIn.WriteLine "cd /d ""%SystemRoot%"""
objWshExec.StdIn.WriteLine "dir /b /s ""*.exe"""
objWshExec.StdIn.WriteLine "exit"
strStdOut = ""
strStdErr = ""
Do
strStdOut = strStdOut & objWshExec.StdOut.ReadAll()
strStdErr = strStdErr & objWshExec.StdOut.ReadAll()
WScript.Sleep 100
Loop Until objWshExec.Status = WshFinished
WScript.Echo "StdOut:"
WScript.Echo strStdOut
WScript.Echo
WScript.Echo "StdErr:"
WScript.Echo strStdErr
Else
WScript.Echo "Can't execute [""%comspec%"" /k]."
End If
Set objWshExec = Nothing
Set objWshShell = Nothing
WScript.Quit 0
Гуллипут
12-11-2013, 20:00
После прочтения вот этого
Синтаксис:
Exec(<Command>)
Назначение: создаёт новый дочерний процесс (т.е. процесс с теми же переменными среды), который запускает заданное консольное приложение. Возвращается объект "WshScriptExec", который позволяет контролировать ход выполнения запущенного приложения и обеспечивает доступ к потокам StdIn, StdOut и StdErr этого приложения.
Параметры:
<Command> - строка, командная строка запуска приложения.
Описание: с помощью данного метода можно запускать и графические оконные приложения. В этом случае возвращаемый объект "WshScriptExec" полезен тем, что позволяет получить идентификатор запущенного процесса, который можно использовать, например, для активизации приложения с помощью метода AppActivate.
Пример:
Set WshShell = CreateObject("WScript.Shell")
Set WshExec = WshShell.Exec("nslookup 127.0.0.1")
WScript.Sleep 7000
Set TextStream = WshExec.StdOut
Str = vbNullString
While Not TextStream.AtEndOfStream
Str = Str & Trim(TextStream.ReadLine()) & vbCrLf
Wend
MsgBox Str
Другой пример:
Set WshShell = CreateObject("WScript.Shell")
Set WshExec = WshShell.Exec("notepad")
WScript.Sleep 2000
WshShell.AppActivate(WshExec.ProcessID)
WshShell.SendKeys "0123456789"
мне кажется, что то, что вы ожидаете увидеть, выводится в этот самый stdout, который надо ещё перехватывать и обрабатывать. Так что тут надо искать другие пути.
morebeauty
13-11-2013, 05:52
Ну тогда вопрос такой.
Как мне открыть командную строку с возможностью ей управлять и иметь информацию о выводе в скрипте.
Мне это нужно для того, чтобы, например, подключиться по telnet к чему либо и автоматом ввести логин и пароль при приглашении их ввести. Ну и выполнить так же автоматом нужный набор команд. И само собой иметь возможность ввести команды самостоятельно с клавиатуры. Ну и еще с несколькими утилитами требуется работа.
SendKeys + Sleep не предлагать.
Если это будет собственная консоль для ввода/вывода заместо стандартной, то необходимо еще и как то скрыть это черное окошко (зачем оно будет висеть на экране смущать людей). Ну и наброски на Delphi или на C++, чтобы я хоть имел представление с чего начать.
Хотя я все же представляю себе это так. Открывается консольное окошко, скрипт все с него перехватывает, потом каким то образом отключает перехват и отправляет перехваченное снова в окно, чтобы это было видно пользователю. Ну или как то так.
morebeauty, Вам следует написать свой клиент telnet. Иных вариантов, чтобы удовлетворить все Ваши запросы, нет.
morebeauty
13-11-2013, 07:03
Вам следует написать свой клиент telnet »
А еще свои утилиты ping, tracert и многие другие.
Есть еще мнения?
morebeauty
13-11-2013, 10:25
Тогда еще вопрос. В контекстном меню командной строки есть пункт "Пометить". То есть я могу выделить нужный мне текст и скопировать его в буфер. Как происходит эта операция? поток уже выведен на терминал, значит он не перехватывается. Происходит что-то другое. Кто нибудь знает об этом? Как программно это осуществить?
А еще свои утилиты ping, tracert и многие другие. Есть еще мнения? »
Можете самостоятельно поискать у объекта WshExec методы для отключения и подключения стандартных потоков дочернего процесса. Как найдёте — вот тогда и начинайте иронизировать, я первый сниму перед Вами шляпу и начну побивать себя в грудь со словами «Mea culpa». Вот только причём здесь ping и tracert; они разве интерактивные?! Речь шла именно про клиента telnet, которым Вы хотели манипулировать и программно, и ручками одновременно. Я указал Вам путь.
Как программно это осуществить? »
Легко: Console Functions (Windows) (http://msdn.microsoft.com/en-us/library/ms682073(VS.85).aspx).
morebeauty
14-11-2013, 07:10
Мне это нужно для того, чтобы, например, подключиться по telnet к чему либо и автоматом ввести логин и пароль при приглашении их ввести. Ну и выполнить так же автоматом нужный набор команд. И само собой иметь возможность ввести команды самостоятельно с клавиатуры. Ну и еще с несколькими утилитами требуется работа.
morebeauty, у «.Exec()» нет возможности произвольно, по Вашему желанию, подключаться/отключаться к потокам дочернего процесса.
Гуллипут
15-11-2013, 07:45
Если исключить это
Если это будет собственная консоль для ввода/вывода заместо стандартной, то необходимо еще и как то скрыть это черное окошко (зачем оно будет висеть на экране смущать людей). », то можно было бы попробовать свой скрипт запускать через cscript, чтобы получить ещё собственное окно консоли, и в него выводить то, что перехватывает Exec через stdout.
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.