-1

I have a batch script which basically does some string replacement based on configurations in the prebuild step for visual studio. The batch script runs fine when I run it from the cmd. But if I run it from VS prebuild, the following line doesn't evaluate %replaceStr% and %version% as variable values. I even tried echo-ing out those 2 and they are not evaluated as variables.

if NOT "!line!" == "" call set "line=!line:%replaceStr%=%version%!"

!replaceStr! and !version! is fine though (through echo, I don't think I can use ! within ! for string replacement.

What could be cause this to fail when running from VS prebuild commands but work fine when I run from cmd. I even added C:\windows\system32\cmd /c to the prebuild and still doesn't work. Any thoughts?

Thanks!

user1181950
  • 779
  • 1
  • 9
  • 21
  • A bit more of your code could show the reason, is the line you showed inside of a command block? – jeb Oct 17 '13 at 07:21

2 Answers2

0

Where are you setting the variables. Each process gets a copy of it's parent's environment. But you can't affect your parent process' environment only child processes at the time they start and their own.

Batch files use the cmd.exe they are running in environment. This is the only case of a program affecting it's parent environment.

One cmd's environment is seperate to another's.

And from Vista's Windows Software Development kit

Environment Variables Every process has an environment block that contains a set of environment variables and their values. The command processor provides the set command to display its environment block or to create new environment variables. Programs started by the command processor inherit the command processor's environment variables.

By default, a child process inherits the environment variables of its parent process. However, you can specify a different environment for the child process by creating a new environment block and passing a pointer to it as a parameter to the CreateProcess function.

Each environment block contains the environment variables in the following format:

Var1=Value1\0
Var2=Value2\0
Var3=Value3\0
...
VarN=ValueN\0\0

The name of an environment variable cannot include an equal sign (=). The total size of the environment block for a process may not exceed 32,767 characters.

The GetEnvironmentStrings function returns a pointer to the environment block of the calling process. This should be treated as a read-only block; do not modify it directly. Instead, use the SetEnvironmentVariable function to change an environment variable. When you are finished with the environment block obtained from GetEnvironmentStrings, call the FreeEnvironmentStrings function to free the block.

Calling SetEnvironmentVariable has no effect on the system environment variables. The user can add or modify system environment variables using the Control Panel. To programmatically add or modify system environment variables, add them to the HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment registry key, then broadcast a WM_SETTINGCHANGE message with lParam set to the string "Environment". This allows applications, such as the shell, to pick up your updates. Note that the values of the environment variables listed in this key are limited to 1024 characters.

The GetEnvironmentVariable function determines whether a specified variable is defined in the environment of the calling process, and, if so, what its value is.

David Candy
  • 735
  • 5
  • 8
0

I guess:

Even from the command line your batch file doesn't work.
I assume that the first time it fails, but then it works.

If this is the case, then your code is inside of a parenthesis block.

Perhaps your code look like this

if %a%==%b% (
  set version=%a%
  if NOT "!line!" == "" call set "line=!line:%replaceStr%=%version%!"
)

That is the effect of the expansion time of the percent variables, they expand when the complete block is parsed, but none of the lines is executed at this time.
So the %version% expands to nothing (for the first run), but the next run will expands correctly.

To avoid this you can use different technics, depending how problematic your content is.

  call set "line=%%line:!replaceStr!=!version!%%"

The parser expands this line two times, at first the exclamation marks are expanded and then the call will expand the %line:rep=ver%.

This works if your line doesn't contain critical special characters like carets ^, percents or quotes.

jeb
  • 78,592
  • 17
  • 171
  • 225