Примечание. Перейдите к разделу ОБНОВЛЕНИЕ 2014-04-27 в нижней части этого ответа, чтобы найти лучшее решение.
Раньше я думал, что ответ был отрицательным.Но затем пользователь DosTips Ливиу обнаружил, что символ <SUB>
(Ctrl-Z, 0x1A, десятичное число 26) имеет причудливые эффекты при внедрении в пакетный файл.Если функции в некоторой степени похожи на терминатор строки, то есть возможно выполнение пакетных команд, следующих за REM (или хаком :: notes), если им предшествует Ctrl-Zhttp://www.dostips.com/forum/viewtopic.php?p=13160#p13160
Это было подтверждено в XP Home Edition sp3, Vista Home Premium sp2 64-битной и Vista Enterprise sp2 32-битной.Я предполагаю, что это работает на других версиях Windows.
Примечание - код ниже должен содержать символы Ctrl-Z.Клянусь, я видел их на этом сайте при просмотре с IE8.Но они, похоже, были потеряны из этого поста, и я не могу понять, как их опубликовать.Я заменил символы на строку <SUB>
::<sub>echo This will execute in batch, but it will fail as vbs.
rem<SUB>echo This will execute in batch, and it is also a valid vbs comment
::'<SUB>echo This will execute in batch and it is also a valid vbs comment
Это ключ к успешному пакетному / VBS-гибриду.До тех пор, пока каждой пакетной команде предшествует rem<SUB>
или ::'<SUB>
, механизм vbs не увидит ее, но будет запущена пакетная команда.Просто убедитесь, что вы заканчиваете пакетную часть с EXIT
или EXIT /B
.Тогда оставшаяся часть скрипта может выглядеть как vbs.
При необходимости вы даже можете иметь метку пакета.:'Label
является действительным комментарием VBS и допустимой меткой пакета.
Вот тривиальный гибридный скрипт. (снова с <SUB>
вместо встроенного символа Ctrl-Z)
::'<SUB>@cscript //nologo //e:vbscript "%~f0" & exit /b
WScript.Echo "Example of a hybrid VBS / batch file"
Обновление 2012-04-15
Джеб нашел решение, которое позволяет избежать неуклюжего нажатия CTRL-Z, но вначале выводит ECHO OFF, а также задает некоторые посторонние переменные.
Я нашел решение без CTRL-Z, которое устраняетпосторонние переменные и проще для понимания.
Обычно специальные символы &
, |
, <
, >
и т. д. не работают после оператора REM
в пакете.Но специальные символы работают после REM.
.Я нашел этот фрагмент информации в http://www.dostips.com/forum/viewtopic.php?p=3500#p3500.. Тест показывает, что REM.
все еще является действительным комментарием VBS. EDIT - исходя из комментария Джеба, безопаснее использовать REM^
(после каретки есть пробел).
ИтакВот тривиальный гибрид VBS / batch с использованием REM^ &
.Единственным недостатком является то, что он печатает REM &
в начале, тогда как решение jeb печатает ECHO OFF
.
rem^ &@cscript //nologo //e:vbscript "%~f0" & exit /b
WScript.Echo "Example of a hybrid VBS / batch file"
. Вот еще один тривиальный пример, который демонстрирует несколько пакетных команд, включая CALL для помеченной подпрограммы..
::' VBS/Batch Hybrid
::' --- Batch portion ---------
rem^ &@echo off
rem^ &call :'sub
rem^ &exit /b
:'sub
rem^ &echo begin batch
rem^ &cscript //nologo //e:vbscript "%~f0"
rem^ &echo end batch
rem^ &exit /b
'----- VBS portion ------------
wscript.echo "begin VBS"
wscript.echo "end VBS"
'wscript.quit(0)
Мне все еще нравится решение CTRL-Z, потому что оно устраняет все посторонние результаты.
ОБНОВЛЕНИЕ 2012-12-17
Том Лаведас опубликовал метод для удобного запуска динамического VBS из пакетного сценария в группах Google: Нет файла гибридного сценария VBS .В этом методе используется mshta.exe (узел приложения Microsoft HTML).
Его оригинальное пакетное решение основывалось на внешнем небольшом сценарии VBS.BAT для выполнения VBS в FOR / F.Я немного изменил синтаксис, чтобы было удобно встраивать его непосредственно в любой пакетный скрипт.
Это довольно медленно, но очень удобно.Он ограничен выполнением одной строки VBS.
VBS пишется нормально, за исключением того, что все кавычки должны быть удвоены: кавычка, содержащая строку, должна быть записана как ""
, а кавычки, являющиеся внутренними для строкизаписывается как """"
.Обычно мини-скрипт выполняется в предложении IN () FOR / F.Это может быть выполнено напрямую, но только если stdout был перенаправлен или передан по каналу.
Он должен работать на любой ОС Windows начиная с XP, если установлен IE.
@echo off
setlocal
:: Define simple batch "macros" to implement VBS within batch
set "vbsBegin=mshta vbscript:Execute("createobject(""scripting.filesystemobject"")"
set "vbsBegin=%vbsBegin%.GetStandardStream(1).write("
set ^"vbsEnd=):close"^)"
:: Get yesterday's date
for /f %%Y in ('%vbsBegin% date-1 %vbsEnd%') do set Yesterday=%%Y
set Yesterday
pause
echo(
:: Get pi
for /f %%P in ('%vbsBegin% 4*atn(1) %vbsEnd%') do set PI=%%P
set PI
pause
echo(
set "var=name=value"
echo Before - %var%
:: Replace =
for /f "delims=" %%S in (
'%vbsBegin% replace(""%var%"",""="","": "") %vbsEnd%'
) do set "var=%%S"
echo After - %var%
pause
echo(
echo Extended ASCII:
for /l %%N in (0,1,255) do (
%= Get extended ASCII char, except can't work for 0x00, 0x0A. =%
%= Quotes are only needed for 0x0D =%
%= Enclosing string quote must be coded as "" =%
%= Internal string quote must be coded as """" =%
for /f delims^=^ eol^= %%C in (
'%vbsBegin% """"""""+chr(%%N)+"""""""" %vbsEnd%'
) do set "char.%%N=%%~C"
%= Display result =%
if defined char.%%N (
setlocal enableDelayedExpansion
echo( %%N: [ !char.%%N! ]
endlocal
) else echo( %%N: Doesn't work :(
)
pause
echo(
:: Executing the mini VBS script directly like the commented code below
:: will not work because mshta fails unless stdout has been redirected
:: or piped.
::
:: %vbsBegin% ""Hello world"" %vbsEnd%
::
:: But this works because output has been piped
%vbsBegin% ""Hello world"" %vbsEnd% | findstr "^"
pause
ОБНОВЛЕНИЕ 2014-04-27
В DosTips есть большой сборник js / vbs / html / hta гибридов и химер в cmd / bat .Много хороших вещей от разных людей.
В этой теме пользователь DosTips, Ливиу, обнаружил красивое VBS / гибридное решение , использующее WSF.
<!-- : Begin batch script
@echo off
cscript //nologo "%~f0?.wsf"
exit /b
----- Begin wsf script --->
<job><script language="VBScript">
WScript.Echo "VBScript output called by batch"
</script></job>
Я думаю, что это фантастическое решение.Секции batch и WSF четко разделены красивыми заголовками.Пакетный код абсолютно нормальный, без какого-либо странного синтаксиса.Единственное ограничение - код пакета не может содержать -->
.
Аналогично, код VBS в WSF абсолютно нормален.Единственным ограничением является то, что код VBS не может содержать </script>
.
Единственным риском является недокументированное использование "%~f0?.wsf"
в качестве сценария для загрузки.Каким-то образом синтаксический анализатор правильно находит и загружает работающий скрипт .BAT "%~f0"
, а суффикс ?.wsf
таинственным образом инструктирует CSCRIPT интерпретировать скрипт как WSF.Надеемся, что MicroSoft никогда не отключит эту «функцию».
Поскольку решение использует WSF, пакетный сценарий может содержать любое количество независимых VBS, JScript или других заданий, которые можно вызывать выборочно.Каждая работа может даже использовать несколько языков.
<!-- : Begin batch script
@echo off
echo batch output
cscript //nologo "%~f0?.wsf" //job:JS
cscript //nologo "%~f0?.wsf" //job:VBS
exit /b
----- Begin wsf script --->
<package>
<job id="JS">
<script language="VBScript">
sub vbsEcho()
WScript.Echo "VBScript output called by JScript called by batch"
end sub
</script>
<script language="JScript">
WScript.Echo("JScript output called by batch");
vbsEcho();
</script>
</job>
<job id="VBS">
<script language="JScript">
function jsEcho() {
WScript.Echo("JScript output called by VBScript called by batch");
}
</script>
<script language="VBScript">
WScript.Echo "VBScript output called by batch"
call jsEcho
</script>
</job>
</package>