4

I am writing a Batch Script that creates a VB Script by echoing each line and directing the output to the created file. It works for the most part, except for two lines that get Command Line variables and uses it as VBS variables. This is the code:

ECHO:strHomeFolder = oShell.ExpandEnvironmentStrings^(^"^%USERPROFILE^%^"^) >> uninstallBeta.vbs
ECHO:strProgramData = oShell.ExpandEnvironmentStrings^(^"^%ProgramData^%^"^) >> uninstallBeta.vbs

It should look like this in the VB Script:

strHomeFolder = oShell.ExpandEnvironmentStrings("%USERPROFILE%")
strProgramData = oShell.ExpandEnvironmentStrings("%ProgramData%")

But what happens is the Batch Script is it just echos the entire line, including >> uninstallBeta.vbs. Any idea why this happens? I have similar lines for creating other VBS and Batch scripts that I think work just fine doing it this way. I have checked for typos and found none. It works just fine in Command Prompt, but not in a Batch Script.

  • I discovered a solution that fixes it, but I still want to know why this happened. – A Child of God Oct 21 '17 at 19:03
  • You might want to look at stackoverflow.com/a/9074483/1012053, especially the UPDATE 2014-04-27 section at the bottom, for a method to entirely avoid creating a separate VBS file. You can actually run VBS directly within a batch script! – dbenham Oct 21 '17 at 20:16
  • @dbenham I saw that yesterday before anybody answered. In will consider trying that. – A Child of God Oct 22 '17 at 14:01
6

It helps to understand how cmd.exe parses batch scripts:
Part 1 - Overview
Part 2 - Percent expansion details

I'll work through the processing of the first faulty line:

echo strHomeFolder = oShell.ExpandEnvironmentStrings^(^"^%USERPROFILE^%^"^) >> uninstallBeta.vbs

The Percent processing in phase 1 happens before ^ escape processing in phase 2. So the parser looks for an environment variable named USERPROFILE^, and fails to find it. So that expands to an empty string, leaving:

echo strHomeFolder = oShell.ExpandEnvironmentStrings^(^"^^"^) >> uninstallBeta.vbs

Next, the carets are processed to escape characters in phase two. The important thing is the first ^" is an escaped quote, so the characters after are not quoted. The next ^^ is an escaped caret. Than follows the first quote that is not escaped, so all characters afterward are quoted. I signify that with Q above each quoted character:

                                                        QQQQQQQQQQQQQQQQQQQQQQQ
echo strHomeFolder = oShell.ExpandEnvironmentStrings("^"^) >> uninstallBeta.vbs

It should be obvious why the >> redirection is not working - it is quoted so it functions as a string literal instead.

You attempted to escape the % as ^% to prevent variable expansion within the batch. That does not work. The correct thing is to double the percents:

echo strHomeFolder = oShell.ExpandEnvironmentStrings("%%USERPROFILE%%") >> uninstallBeta.vbs

If the line is within a parenthesized block, then you would need to escape the ), but the ( would never need to be escaped

for .... do (
    ...
    echo strHomeFolder = oShell.ExpandEnvironmentStrings("%%USERPROFILE%%"^) >> uninstallBeta.vbs
    ...
)

Note that the rules are different from the command line. There is no mechanism to truly escape a % within the command line, and the command line preserves %undefinedVar% text if the variable is undefined. However, you can effectively prevent expansion of the variable by including one or more ^ between the percents so that the variable is not found. The caret then disappears in phase 2. But the first quote needs to be escaped so that the internal ^ disappears. And the last quote must be escaped so that the redirection is active.

This works from the command line (but not within a batch script):

echo strHomeFolder = oShell.ExpandEnvironmentStrings(^"%USERPROFILE^%^") >> uninstallBeta.vbs

The caret can appear anywhere between the percents. All of the following would work just as well:

%USER^PROFILE%
%^USERPROFILE%
etc.
  • @Facebook - I have no idea what situation you are referring to. I would have to see a concrete example. If you figure out the exact troublesome scenario, then post a new question, either here or on StackOverflow. – dbenham Oct 21 '17 at 20:20
  • Here it is man.... superuser.com/questions/1261588/… – Pimp Juice IT Oct 23 '17 at 12:39
2

I tried this and it works as expected too .....

set a=userprofile
set b=ProgramData
> uninstallBeta.vbs ECHO strHomeFolder = oShell.ExpandEnvironmentStrings^("%%%a%%%%"^)
>> %DESKTOP%\uninstallBeta.vbs ECHO strProgramData = oShell.ExpandEnvironmentStrings^("%%%b%%%%"^)

I am also a beginner in batch-scripting I found this working through trying. hope someone explain how it works.

  • See dbenham's answer for why that works. – A Child of God Oct 21 '17 at 20:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.