People have been embedding and executing VBScript within batch files for a long time. But all the published solutions that I have seen (at the time this question was originally posed) involve writing a temporary VBS file. For example: Embed VBScript inside Windows batch file.
Is it possible to execute embedded VBScript within batch without writing a temporary file?
EDIT: My first answer was wrong for VBScript, now my next try...
Nice idea to use CTRL-Z, but I don't like control characters in a batch file, as it is problematic to copy&paste them.
It's depends of your browser, of your editor, of your ...
You could get a hybrid VBScript/Batch also with normal characters, and "normal" code.
The trick is to prepend each batch line with
set n=n'&
it is legal for both, but vbs will ignore the rest of the line, only batch will execute the rest of the line.The other variant is
:'remark ^
, this is a remark for both, but for batch this remarks also the next line by the multiline character.The VbScript sees then
a=1<1
the rest of the line is a remark'
The batch sees only
<1' echo off <nul
, the first redirect from1'
will be override by the second<nul
, so it results to onlyecho off < nul
.The only remaining problem is that you can see the first
echo off
, as it doesn't work in batch to use the@
after a redirection.For JScript exists a simpler solution hybrid scripting
I have tried to assemble all solutions in one script at http://www.dostips.com/forum/viewtopic.php?p=37780#p37780.
There is the batch script converting the most popular languages into a batch file (.js, .vbs, .ps1, .wsf, .hta and historical .pl).
It works as follows:
And my attempt (first posted here).It resembles the jeb's solution ,but (at least according to me) the code is more readable:
And the explanation:
'.exe
subst.exe
anddoskey.exe
doskey.exe
to'.exe
(if it does not already exist) and then continue using it as'&
(as the .exe extension should be in %PATHEXT%).This will be taken as a comment in VBScript and in batch will do nothing - just will continue with the next command on the line.There are some flaws of course .At least for the first run eventually you will need administrator permissions as the coping in
%windir%\System32\
might be denied.For robustness you can also use'>nul 2>&1|| copy /Y %windir%\System32\doskey.exe .\'.exe >nul
and then at the end:'& rem del /q .\'.exe
With
'.exe
left in your path you could unintentially to use it in improper way , and the execution on every line of '.exe eventually could decrease the performance...And in the batch part commands must be only in one line.
Update 9.10.13 (..following the above convention)
Here's one more way which requires self-renaming of the batch file:
And a short explanation:
CSCRIPT.EXE
with.WSF
file.Self-renaming is a little bit risky , but faster than a temp file.& < > ;
so@echo off
andgoto
can be used without worries. But for safety it's good to put batch commands in xml comment (or CDATA ) section .To avoid error messages from the batch I've skipped the<!--
withgoto
here.exit
So the good things are that there's no need to write all batch code in single line commands, there's no annoying
echo off
displayed , jscript code and different jobs could be added to the script.Also no need of special symbols and creation of additional exe files like'.exe
On the other hand self-renaming could be risky.
Note - jump to the UPDATE 2014-04-27 section at the bottom of this answer for the best solution.
I used to think the answer was no. But then DosTips user Liviu discovered that the
<SUB>
character (Ctrl-Z, 0x1A, decimal 26) has bizare effects when embedded within a batch file. If functions somewhat like a line terminator such that it is possible for batch commands that follow a REM (or a :: remark hack) to execute if they are preceded by Ctrl-Z. http://www.dostips.com/forum/viewtopic.php?p=13160#p13160This has been confirmed on XP Home Edition sp3, Vista Home Premium sp2 64 bit, and Vista Enterprise sp2 32 bit. I'm assuming it works on other Windows versions.
Note - the code below is supposed to have embedded Ctrl-Z characters. I swear I used to see them on this site when viewed with IE8. But they seem to have been lost from this post somehow and I cannot figure out how to post them anymore. I've replaced the characters with the string
<SUB>
That is the key to a successful batch/vbs hybrid. As long as each batch command is preceded by
rem<SUB>
or::'<SUB>
, then the vbs engine won't see it, but the batch command will run. Just make sure you terminate the batch portion with anEXIT
orEXIT /B
. Then the remainder of the script can be normal looking vbs.You can even have a batch label if needed.
:'Label
is both a valid vbs comment and a valid batch label.Here is a trivial hybrid script. (again with
<SUB>
in place of embedded Ctrl-Z char)Update 2012-04-15
jeb found a solution that avoids the awkward CTRL-Z, but it prints out ECHO OFF at the start and also sets some extraneous variables.
I have found a solution without CTRL-Z that eliminates the extraneous variables and is simpler to comprehend.
Normally the special characters
&
,|
,<
,>
etc. don't work after aREM
statement in batch. But the special characters do work afterREM.
. I found this nugget of information at http://www.dostips.com/forum/viewtopic.php?p=3500#p3500. A test shows thatREM.
is still a valid VBS comment. EDIT - based on jeb's comment, it is safer to useREM^
(there is a space after the caret).So here is a trivial VBS/batch hybrid using
REM^ &
. The only drawback is it printsREM &
at the beginning, whereas jeb's solution printsECHO OFF
.Here is another trivial example that demonstrates multiple batch commands, including a CALL to a labeled sub-routine.
I still like the CTRL-Z solution because it eliminates all extraneous output.
UPDATE 2012-12-17
Tom Lavedas posted a method to conveniently run dynamic VBS from a batch script over at Google Groups: No file VBS hybrid scripting. The method uses mshta.exe (Microsoft HTML Application Host).
His original batch solution relied on an external small VBS.BAT script to execute the VBS within a FOR /F. I modified the syntax slightly to make it convenient to embed directly within any given batch script.
It is quite slow, but very convenient. It is restricted to executing a single line of VBS.
The VBS is written normally, except all quotes must be doubled: A quote enclosing a string must be written as
""
, and quotes internal to a string must be written as""""
. Normally the mini script is executed within the IN() clause of a FOR /F. It can be executed directly, but only if stdout has been redirected or piped.It should work on any Windows OS from XP onward as long as IE is installed.
UPDATE 2014-04-27
Over at DosTips there is a great compendium of js/vbs/html/hta hybrids and chimeras in cmd/bat. Lots of good stuff from various people.
Within that thread, DosTips user Liviu discovered a beautiful VBS/batch hybrid solution that uses WSF.
I think this solution is fantastic. The batch and WSF sections are clearly separated by nice headers. The batch code is absolutely normal, without any odd syntax. The only restriction is the batch code cannot contain
-->
.Similarly, the VBS code within WSF is absolutely normal. The only restriction is the VBS code cannot contain
</script>
.The only risk is the undocumented use of
"%~f0?.wsf"
as the script to load. Somehow the parser properly finds and loads the running .BAT script"%~f0"
, and the?.wsf
suffix mysteriously instructs CSCRIPT to interpret the script as WSF. Hopefully MicroSoft will never disable that "feature".Since the solution uses WSF, the batch script can contain any number of independent VBS, JScript, or other jobs that can be selectively called. Each job can even utilize multiple languages.
There is a very simple solution for this problem. Just use an Alternate Data Stream (ADS) to store the VBS code. To explain it simply, an ADS is another place where you can store other data in the same file, that is, a file is comprised of its original data plus any number of additional ADS's. Each ADS is identified separating its own name from the original file name via a colon. For example:
You may find a more technicall and extensive description of ADS's in the web, but it is important to mention now that this feature works on NTFS disks only. Now, lets see how use this feature to solve this particular problem.
First, create the original Batch file in the usual way. You may also start notepad.exe from the command line this way:
For my example, I inserted the following lines in
test.bat
:Note the name of the VBS script. After
test.bat
was saved and Notepad closed, create the VBS script using Notepad, so enter this command at the command-line:And create the script in the usual way:
Save this file and run
test.bat
. It works!;)
You may review the ADS's of
test.bat
file via the/R
switch indir
command. You may read a more extensive explanation of this method and its limitations at this post.