Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   проблема с WScript.Shell.Exec (http://forum.oszone.net/showthread.php?t=271860)

morebeauty 12-11-2013 08:01 2252549

проблема с WScript.Shell.Exec
 
Доброго дня.
Есть скрипт:
Код:

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.
Помогите разобраться.
Заранее спасибо!

Iska 12-11-2013 08:54 2252579

Цитата:

Цитата morebeauty
Запускает cmd.exe, но при этом вместо привычного приглашения ввести команды "C:\*****>" видно только черный экран. !!! »

morebeauty, всё так. А Вы ожидали увидеть нечто иное?! Зачем Вам «.Exec()»? Что Вы понимаете под возможностью «управлять»?

morebeauty 12-11-2013 10:24 2252637

Цитата:

Цитата Iska
Зачем Вам «.Exec()»? Что Вы понимаете под возможностью «управлять»? »

Значит выполнить Terminate(), перехватить вывод (stdOut), выполнить ввод (stdIn).
Этого достаточно?

Iska 12-11-2013 10:40 2252646

Первое можно выполнить и после «.Run()». А второе и третье — да, только «.Exec()». Но Вы не ответили на:
Цитата:

Цитата Iska
А Вы ожидали увидеть нечто иное?! »

Что Вы ожидали/хотели увидеть? Т.е., что не так?

morebeauty 12-11-2013 11:02 2252652

Цитата:

Цитата Iska
Что Вы ожидали/хотели увидеть? Т.е., что не так? »

Цитата:

Цитата morebeauty
Запускает cmd.exe, но при этом вместо привычного приглашения ввести команды "C:\*****>" видно только черный экран. »

То есть ожидал полноценную командную строку с возможностью ввода/вывода.

Скажите, а Вы совсем не догадывались что именно я ожидал увидеть? А если у Вас были догадки, скажите, среди них была "открывая командную строку ожидал увидеть немецкое порно"? :)

morebeauty 12-11-2013 12:39 2252720

Вложений: 2
Ожидал
cmd2.PNG

Увидел
cmd1.PNG

Iska 12-11-2013 19:53 2253119

Цитата:

Цитата morebeauty
Скажите, а Вы совсем не догадывались что именно я ожидал увидеть? А если у Вас были догадки, скажите, среди них была "открывая командную строку ожидал увидеть немецкое порно"? »

Нет, на это моей фантазии не хватило.


Цитата:

Цитата morebeauty
То есть ожидал полноценную командную строку с возможностью ввода/вывода. »

Вы и получили полноценную командную строку с возможностью ввода/вывода. Программного — поскольку потоки ввода, вывода и ошибок (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 2253124

После прочтения вот этого
Цитата:

Синтаксис:

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 2253404

Ну тогда вопрос такой.
Как мне открыть командную строку с возможностью ей управлять и иметь информацию о выводе в скрипте.
Мне это нужно для того, чтобы, например, подключиться по telnet к чему либо и автоматом ввести логин и пароль при приглашении их ввести. Ну и выполнить так же автоматом нужный набор команд. И само собой иметь возможность ввести команды самостоятельно с клавиатуры. Ну и еще с несколькими утилитами требуется работа.
SendKeys + Sleep не предлагать.

Если это будет собственная консоль для ввода/вывода заместо стандартной, то необходимо еще и как то скрыть это черное окошко (зачем оно будет висеть на экране смущать людей). Ну и наброски на Delphi или на C++, чтобы я хоть имел представление с чего начать.

Хотя я все же представляю себе это так. Открывается консольное окошко, скрипт все с него перехватывает, потом каким то образом отключает перехват и отправляет перехваченное снова в окно, чтобы это было видно пользователю. Ну или как то так.

Iska 13-11-2013 06:56 2253412

morebeauty, Вам следует написать свой клиент telnet. Иных вариантов, чтобы удовлетворить все Ваши запросы, нет.

morebeauty 13-11-2013 07:03 2253413

Цитата:

Цитата Iska
Вам следует написать свой клиент telnet »

А еще свои утилиты ping, tracert и многие другие.

Есть еще мнения?

morebeauty 13-11-2013 10:25 2253478

Тогда еще вопрос. В контекстном меню командной строки есть пункт "Пометить". То есть я могу выделить нужный мне текст и скопировать его в буфер. Как происходит эта операция? поток уже выведен на терминал, значит он не перехватывается. Происходит что-то другое. Кто нибудь знает об этом? Как программно это осуществить?

Iska 13-11-2013 12:31 2253563

Цитата:

Цитата morebeauty
А еще свои утилиты ping, tracert и многие другие. Есть еще мнения? »

Можете самостоятельно поискать у объекта WshExec методы для отключения и подключения стандартных потоков дочернего процесса. Как найдёте — вот тогда и начинайте иронизировать, я первый сниму перед Вами шляпу и начну побивать себя в грудь со словами «Mea culpa».
Вот только причём здесь ping и tracert; они разве интерактивные?! Речь шла именно про клиента telnet, которым Вы хотели манипулировать и программно, и ручками одновременно. Я указал Вам путь.

Цитата:

Цитата morebeauty
Как программно это осуществить? »

Легко: Console Functions (Windows).

morebeauty 14-11-2013 07:10 2254172

Цитата:

Мне это нужно для того, чтобы, например, подключиться по telnet к чему либо и автоматом ввести логин и пароль при приглашении их ввести. Ну и выполнить так же автоматом нужный набор команд. И само собой иметь возможность ввести команды самостоятельно с клавиатуры. Ну и еще с несколькими утилитами требуется работа.

Iska 14-11-2013 08:00 2254193

morebeauty, у «.Exec()» нет возможности произвольно, по Вашему желанию, подключаться/отключаться к потокам дочернего процесса.

Гуллипут 15-11-2013 07:45 2254954

Если исключить это
Цитата:

Цитата morebeauty
Если это будет собственная консоль для ввода/вывода заместо стандартной, то необходимо еще и как то скрыть это черное окошко (зачем оно будет висеть на экране смущать людей). »

, то можно было бы попробовать свой скрипт запускать через cscript, чтобы получить ещё собственное окно консоли, и в него выводить то, что перехватывает Exec через stdout.


Время: 14:50.

Время: 14:50.
© OSzone.net 2001-