1

Тема: VBScript: Как создать окно ввода с заданным временем ожидания.

Добрый вечер!


intext=inputbox("")

Возможно ли сделать ограничение по времени этому окошку запроса данных, или может есть другие способы осуществить подобный ввод данных с таймером, по окончании которого окошко бы просто исчезало?

Стремление - залог успеха

2 (изменено: wisgest, 2013-01-08 19:14:04)

Re: VBScript: Как создать окно ввода с заданным временем ожидания.

Мне представляется что без создания дополнительного процесса задачу не решить.
Т.к. предполагается обмениваться только текстовыми данными, то проще всего его запускать с помощью WshShell.Exec().

Вспомогательный файл InputBox.vbs:

Input = InputBox("")
WScript.StdOut.Write Input
WScript.Quit IsEmpty(Input)

(Можно будет добавить передачу дополнительных аргументов для InputBox() через аргументы командной строки, стандартный поток ввода или, даже, переменные окружения.)
(Вместо отдельного файла можно использовать задание в WSF-файле.)

Основной скрипт:

Set WshShell = CreateObject("WScript.Shell")

Input = InputBoxWithTimeout(15)
If Not IsEmpty(Input) Then
  MsgBox "Введено [" & Input & "]"
Else
  MsgBox "Ничего не введено"
End If

Function InputBoxWithTimeout(SecondsToWait)
  With WshShell.Exec("WScript.exe InputBox.vbs")
    For I = 1 To SecondsToWait * 10
      WScript.Sleep 100
      If .Status = 1 Then
        If .ExitCode = 0 Then InputBoxWithTimeout = .StdOut.ReadAll()
        Exit Function
      End If
    Next
    .Terminate
  End With
End Function

Я лишь не пойму: почему при SecondsToWait = 0, если отсчёт в цикле вести от 0, то окно закрывается сразу, а от 1 — нет, хотя должно быть наоборот?

3

Re: VBScript: Как создать окно ввода с заданным временем ожидания.

Если нужно просто выйти из скрипта, то достаточно перед функцией прописать WScript.Timeout = <Seconds>.

4

Re: VBScript: Как создать окно ввода с заданным временем ожидания.

Хм, я тут подумал, если же и использовать вспомогательный файл, то может сделать просто с аргументами и Timeout.

Вот основной скрипт:

'Какой-нибудь код

Timeout = 5 'Количество секунд, через которое должен отключиться InputBox

Set a = CreateObject("WScript.Shell")
Set b = a.Exec("Wscript InputBox.vbs " & Timeout)

Do

If b.ExitCode = 0 Then TimeoutInputBox = b.StdOut.ReadAll

WScript.Sleep 100

Loop Until b.Status = 1 


If TimeoutInputBox <> "" Then MsgBox TimeoutInputBox Else MsgBox "Ничего не ввели"

'Продолжение кода

А вот вспомогательный:

WScript.Timeout = WScript.Arguments.Item(0)

WScript.StdOut.Write InputBox ("Введи что-нибудь")

Ну а если делать временный, то можно одним скриптом...
Только все как-то сложно получится:

Timeout = 5 'Количество секунд, через которое должен отключиться InputBox

Set FSO = CreateObject("Scripting.FileSystemObject")

With FSO.OpenTextFile("InputBox.vbs", 2, True)
.WriteLine "WScript.Timeout = WScript.Arguments.Item(0)"
.Write "WScript.StdOut.Write InputBox (""Введи что-нибудь"")"
.Close
End With

Set a = CreateObject("WScript.Shell")
Set b = a.Exec("Wscript InputBox.vbs " & Timeout)

Do

If b.ExitCode = 0 Then TimeoutInputBox = b.StdOut.ReadAll

WScript.Sleep 100

Loop Until b.Status = 1 

FSO.DeleteFile "InputBox.vbs"

If TimeoutInputBox <> "" Then MsgBox TimeoutInputBox Else MsgBox "Ничего не ввели"

Set a = Nothing
Set b = Nothing
Set FSO = Nothing
Программист - это не профессия, а смысл жизни (с)

5 (изменено: wisgest, 2013-01-11 16:46:30)

Re: VBScript: Как создать окно ввода с заданным временем ожидания.

Wscript.Timeout — напрочь вылетело из головы (из-за того, что никогда там прочно и не сидело). Ну, в таком случае, чуть проще будет передавать задержку не вспомогательному скрипту, а самому WScript.exe как ключ //T:<секунды>.

Так же в #2 я различал, с одной стороны, случай ввода пустой строки и, с другой, нажатие «Отмена» или окончание врмени (последние два случая тоже можно было бы различить между собой).
Теперь же (используя //T) надо при нажатии «OK» наоборот возвращать ненулевой код завершения (или истечение времени будет рассматриваться как ввод пустой строки, а не «Отмена»). (И что-то я не представляю, как различить при необходимости истечение времени и «Отмену». Добавлено: На самом деле всё просто — при нажатии «OK» или «Отмена» возвращать разные ненулевые коды завершения, ну или передавать доп.сведения отдельной строкой в выходном потоке. )

Но, в целом, это всё равно неправильный подход, т.к. при начале ввода отсчёт времени должен прекращаться, а здесь это невозможно осуществить.

6

Re: VBScript: Как создать окно ввода с заданным временем ожидания.

html

Я конечно далек от мысли... (с)

7

Re: VBScript: Как создать окно ввода с заданным временем ожидания.

Okey, спасибо за идейки, буду размышлять над ними и эксперементировать по возможности...
Понравилась фишка с wscript.timeout, но увы она не подходит в данном случае по своей безУсловности... А насчёт запуска другого vbs-ника, хотелось бы обойтись без него, но пока как показывают обстоятельства никак.

wisgest пишет:

(И что-то я не представляю, как различить при необходимости истечение времени и «Отмену».)

В этом как раз нет необходимости, есть необходимость лишь получать то, что вводят в окошке...
Кстати, вспомнилась изумительная для меня ExecuteGlobal, может что-нибудь в этом направлении слепим, да бы избежать по возможности запуска доп.скрипта... Первая попытка:

ExecuteGlobal "Wscript.Timeout=5 : intext=inputbox("""")"
msgbox "текст после таймера"

увенчалась провалом...

Стремление - залог успеха

8 (изменено: smaharbA, 2013-01-17 15:04:09)

Re: VBScript: Как создать окно ввода с заданным временем ожидания.

ExecuteGlobal "Wscript.Timeout=2"
msgbox Eval("inputbox("""")")
Я конечно далек от мысли... (с)

9

Re: VBScript: Как создать окно ввода с заданным временем ожидания.

smaharbA пишет:

ExecuteGlobal "Wscript.Timeout=2"
msgbox Eval("inputbox("""")")

Так-то сценарий весь закрывается, без возможности продолжаться...

Программист - это не профессия, а смысл жизни (с)

10 (изменено: wisgest, 2013-01-11 21:40:43)

Re: VBScript: Как создать окно ввода с заданным временем ожидания.

Только сейчас обратил внимание, что, как при использовании WScript.Timeout, так и WSCRIPT.EXE//T, если время вышло, то возвращается набранная в InputBox в тот миг строка без необходимости подтверждения. Интересное, хотя и непонятное мне поведение!
Также не очень понимаю, как влияет ExecuteGlobal() в примере smaharbA (Eval() во второй строке, по-моему, никак не влияет и без него можно обойтись). Но в том примере, если в InputBox нажать OK, то действие .Timeout распространяется и на MsgBox; и, по-любому, после MsgBox ничего уже не работает.

11

Re: VBScript: Как создать окно ввода с заданным временем ожидания.

В общем остановился я на решении запускать другой файл, всем спасибо за помошь!
Ради спортивного интереса выкладываю непонятный для меня момент, с которым столкнулся во время одного из экспериментов:
Основной скрипт


Set E = CreateObject("WScript.Shell").Exec("wscript 1.vbs")
keytime=3000
wscript.sleep keytime
E.terminate
msgbox E.StdOut.ReadAll
wscript.quit

Вспомогательный


intext=InputBox("1")
'...
intext=InputBox("2")
'...
WScript.StdOut.Write "outtext"

Так вот, когда запускаем сценарий и просто ждём, всё хорошо начинается, открывается первый inputbox, но при выполнении terminate у меня начинаются чудеса: вполне логично закрывается первый inputbox, но тут же продолжается выполнение вспомогательного скрипта, т.е. открывается уже второй inputbox, закрывается и он, и только потом вспомогательный скрипт прекращает своё выполнение; а основной скрипт в процентах 90% случаев вылетает с ошибкой


---------------------------
Windows Script Host
---------------------------
Сценарий:    основной скрипт.vbs
Ошибка:    Недопустимый дескриптор окна. 
Код:    80070578
Источник:     (null)
---------------------------
ОК   
---------------------------

а в остальных уж 10% доходит до конца и выдаёт пустой StdOut. Насчёт пустого StdOut понятно, но почему возобновляется выполнение вспомогательного скрипта вплоть до второго inputbox, при попытке убивании его terminate-ом?

Стремление - залог успеха

12 (изменено: smaharbA, 2013-01-17 15:04:29)

Re: VBScript: Как создать окно ввода с заданным временем ожидания.

Обернуть ?

var s=new ActiveXObject("MSScriptControl.ScriptControl");
s.language="vbscript";
WScript.Timeout=5;
s.AddObject("WScript",WScript);
s.executestatement('\
x=inputbox(""):\
msgbox x:\
')
Я конечно далек от мысли... (с)

13

Re: VBScript: Как создать окно ввода с заданным временем ожидания.

smaharbA, гениально, жаль что это js-скрипт; может как-нить удастся это переделать под vbs? Т.к. скрипт у меня длинный, и уж так повелось, что js это не моё, не умею я там работать как ни пытался...

P.S: Я тут подумал, раз уж из под js можно юзать vbs-сценарий, нельзя ли сделать наоборот - из vbs js-возможности?

Стремление - залог успеха

14 (изменено: smaharbA, 2013-01-17 15:04:55)

Re: VBScript: Как создать окно ввода с заданным временем ожидания.

set s=CreateObject("MSScriptControl.ScriptControl")
s.language="vbscript"
s.AddObject "WScript",WScript
set fso=CreateObject("Scripting.FileSystemObject")
set f=fso.OpenTextFile(WScript.ScriptFullName)
for x=1 to 8: f.SkipLine: next
s.executestatement(f.ReadAll())
WScript.Quit()
WScript.Timeout=3
x=inputbox("")
msgbox x
msgbox 123
Я конечно далек от мысли... (с)

15 (изменено: smaharbA, 2013-01-17 15:05:49)

Re: VBScript: Как создать окно ввода с заданным временем ожидания.

set s=CreateObject("MSScriptControl.ScriptControl")
s.language="vbscript"
s.AddObject "WScript",WScript
set fso=CreateObject("Scripting.FileSystemObject")
set f=fso.OpenTextFile(WScript.ScriptFullName)
do while f.ReadLine()<>"WScript.Quit():rem Start":loop
s.executestatement(f.ReadAll())
WScript.Quit():rem Start
WScript.Timeout=3
x=inputbox("")
msgbox x
msgbox 123

Но наверное будет проблема с асинхронным вызовом процедур


офф: как с этим - http://forum.script-coding.com/help.php ?

Я конечно далек от мысли... (с)

16

Re: VBScript: Как создать окно ввода с заданным временем ожидания.

smaharbA, приведи свои посты в соответствие Правилам.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

17

Re: VBScript: Как создать окно ввода с заданным временем ожидания.

smaharbA, интересное решение однако , раньше нигде не сталкивался с объектом MSScriptControl. Но не без трудностей при видоизменении скрипта. Как я понял самосчитывание тела скрипта необходимо, т.к. после запуска s.executestatement() и истечения времени timeout, команды, стоящие после s.executestatement() попросту не выполняются. Хотел похитрить, чтоб как-то выйти из него, после выполнения мне нужных там комманд (inputbox), но увы пока безуспешны. Вот одна из моих попыток, чтоб была понятна суть моих стараний:


set s=CreateObject("MSScriptControl.ScriptControl")
s.language="vbscript"
s.AddObject "WScript",WScript
do
s.executestatement("WScript.Timeout=3 : x=inputbox("""") : Exit do")
loop
msgbox x
msgbox 123

Как я понял s.executestatement() запускает независимый скрипт в скрипте? (Хорошей русскоязычной литературы, не считая машинного перевода по MSScriptControl не нашёл). Может есть какие-то доп. опции, чтоб взять под контроль это дело?

P.S. Кстати, объект "MSScriptControl.ScriptControl" на Windows 7 Home Basic не создаётся, пришлось на старом добром XP тестить.

Стремление - залог успеха

18

Re: VBScript: Как создать окно ввода с заданным временем ожидания.

по поводу "не создается"
\Windows\SysWOW64\wscript.exe c:\d.vbs

по поводу выхода из цикла - наверное только флаг типа

set s=CreateObject("MSScriptControl.ScriptControl")
s.language="vbscript"
s.AddObject "WScript",WScript
do while not [флаг]
s.executestatement("WScript.Timeout=3 : x=inputbox("""") : [флаг]=true")
[флаг]=s.eval("[флаг]")
loop
WScript.Timeout=0
msgbox x
msgbox 123
Я конечно далек от мысли... (с)

19

Re: VBScript: Как создать окно ввода с заданным временем ожидания.

smaharbA пишет:

[флаг]=true

Не силён. На примере.

Стремление - залог успеха

20

Re: VBScript: Как создать окно ввода с заданным временем ожидания.

это просто пример применения имен переменных в национальных символах ))
могло быть и flag=true

Я конечно далек от мысли... (с)

21

Re: VBScript: Как создать окно ввода с заданным временем ожидания.

А, понял. Ну а вы сами пробовали запускать его? Дело в том, что после истечения timeout, если не ответили на окно запроса inputbox, окошко закрывается и скрипт довыполняет только то, что внутри s.executestatement(""), и далее скрипт закрывается, не доходя уже даже до loop или что бы там ни было. Целью моего введенного цикла была то, что я хотел как-нибудь вытащить фокус выполнения сценария из s.executestatement("") с помощью Exit do, а не наличие самого цикла.

А еще, если всё же успеть ввести текст и нажать ОК (ну или просто Отмену) до истечения timeout, скрипт продолжает выполняться нормально, доходит до msgbox, но вот введённый текст опять таки не выходит за пределы s.executestatement(""), т.е. выходит пустое окно msgbox.

Стремление - залог успеха

22

Re: VBScript: Как создать окно ввода с заданным временем ожидания.

set s=CreateObject("MSScriptControl.ScriptControl")
s.language="vbscript"
s.AddObject "WScript",WScript
do while not [флаг]
s.executestatement("WScript.Timeout=3 : x=inputbox("""") : [флаг]=true")
[флаг]=s.eval("[флаг]")
x=s.eval("x")
loop
WScript.Timeout=0
msgbox x
msgbox 123

а то, что после таймаута не выполняется, наверное так и должно быть (

Я конечно далек от мысли... (с)

23 (изменено: smaharbA, 2013-01-18 22:32:32)

Re: VBScript: Как создать окно ввода с заданным временем ожидания.

скорее всего само выполнение внутри объекта это уже "багофича" (

по тому и выше был предложен вариант "самочтения" и выполнения нужного тела

наверное всеж таки проще исполюзовать showModalDialog от хтмл, как нибудь встроив его в скрипт

Я конечно далек от мысли... (с)

24

Re: VBScript: Как создать окно ввода с заданным временем ожидания.

Наверно. smaharbA, спасибо! будем пробовать что проще...

Кстати, хороша и идея

wisgest пишет:

Вместо отдельного файла ... использовать задание в WSF-файле.

Стремление - залог успеха

25

Re: VBScript: Как создать окно ввода с заданным временем ожидания.

Lucky пишет:

intext=inputbox("")

может есть другие способы осуществить подобный ввод данных с таймером

Вот здесь http://gallery.technet.microsoft.com/sc … t-36122f57 есть нечто подобное. Если допилить, вполне сгодится для решения вопроса.

Щт Уккщк Куыгьу Туче