Немодальное окно уведомлений из пакетного скрипта
Я хотел бы иметь немодальное окно предупреждения, называемое формой командного файла. В настоящее время я использую vbscript для создания модального окна предупреждения:
>usermessage.vbs ECHO WScript.Echo^( "Generating report - this may take a moment." ^)
WSCRIPT.EXE usermessage.vbs
Но я бы хотел продолжить работу со скриптом (генерацией отчета), не дожидаясь взаимодействия с пользователем. Как я могу сделать это? Мне все равно, vbscript или нет - я просто хочу, чтобы он работал из моего пакетного скрипта (в Windows XP).
1 ответ
Простой ответ, который не предъявляет новых требований к вашему текущему трюку, заключается в использовании start
Команда отсоединить скрипт от выполнения командного файла.
Это может выглядеть примерно так:
> usermessage.vbs ECHO WScript.Echo ^ ("Создание отчета - это может занять некоторое время." ^) запустить WSCRIPT.EXE usermessage.vbs echo Этот текст является прокси для тяжелой работы по написанию отчета
где единственная разница использует start
бежать wscript
, Это страдает от недостатка, заключающегося в том, что временный файл остается в текущем каталоге и в конечном итоге его необходимо удалить вручную.
Обе проблемы просты в решении:
@echo off setlocal set msg="%TMP%\tempmsg.vbs" ECHO WScript.Echo^("Generating report - this may take a moment." ^) >%msg% start WSCRIPT.EXE /I /T:15 %msg% echo This text is a proxy for the hard work of writing the report ping -n 5 127.0.0.1 >NULL del %msg% >NUL 2>&1
Here, I move the temporary script over to the %TMP%
folder, and remember to delete it when we're done with it. Я использовал echo
и ping
command to waste some time to demonstrate a long process running. And, I used the /I
а также /T
варианты wscript
to make certain that the script is run "interactively" and to set a maximum time to allow the script to run.
@echo off
а также setlocal
make it look cleaner when running at a command prompt and prevent it from leaving the name `%msg% in the prompt's environment.
Edit: Johannes Rössel's criticism of setlocal
in the comments is incorrect. If this is invoked at a command prompt, without the setlocal
the variable msg will be visible to the prompt and to other batch files and programs launched from that prompt. Это хорошая практика для использования setlocal
to isolate local variables in a batch file if one is actually writing anything more than a throw-away script.
This can be easily demonstrated:
C:> type seta.bat @set A=SomeValue C:> set A ALLUSERSPROFILE = C: \ Документы и настройки \ Все пользователи APPDATA=C:\Documents and Settings\Ross\Application Data C:> seta.bat C:> set A A=SomeValue ALLUSERSPROFILE = C: \ Документы и настройки \ Все пользователи APPDATA=C:\Documents and Settings\Ross\Application Data C:>
Я боролся с этой же проблемой, у меня был сценарий VBScript, который должен был открывать окно сообщения, но не останавливаться и продолжать. И я хотел закрыть через некоторое время. Это сработало для меня. По сути, один vbscript создает другой файл vbscript, а затем использует shellexecute для выполнения этого файла окна сообщения с таймаутом, скажем, 15 секунд.
Set wshShell = CreateObject( "WScript.Shell" )
tmpPath = wshShell.ExpandEnvironmentStrings( "%TMP%" )
set wshShell = Nothing
msgFile = tmpPath & "\tempmsg.vbs"
Set fs = CreateObject("Scripting.FileSystemObject")
Set objFile = fs.CreateTextFile(msgFile,True)
objFile.Write "MsgBox " & chr(34) & "It worked!" & chr(34) & vbCrLf
objFile.Close
Set fs = Nothing
dim objShell
set objShell = CreateObject("shell.application")
objShell.ShellExecute "cscript.exe", "/I /T:15 " & (char34) & msgFile & chr(34), "", "open", 0
set objShell = Nothing