10

I have a PowerShell script set to execute after an MSBuild is finished. It uses environment variables set in the POSTBUILD section of the build process (build directories and the like.) Currently it looks like this:

  set MAGE="C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\mage.exe"
  set APPFILE=$(TargetDir)$(TargetName).application
  set MANIFEST=$(TargetPath).manifest
  set CERT=$(ProjectDir)$(TargetName).pfx
  set PROJECTNAME=$(TargetName)
  set CONFIGURATION=$(ConfigurationName)
  set TARGETDIR=$(TargetDir)
  set TEAMBUILD=$False
  Powershell -File "$(ProjectDir)POSTBUILD.ps1"

With each set operating on a separate line, but still within the same CMD instance.

Is there a way I can set multiple variables at once using just one line instead of 7?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Masamune_Shadow
  • 181
  • 1
  • 2
  • 7
  • 1
    Why would you want to do that? It's clearer to put them each on their own line. If you really want a single line, put all of the sets in a function. – Robert Harvey Jul 31 '13 at 19:01
  • 2
    I agree it would be clearer how it currently is. However, I want to run them via a task command in MSBuild. And the each task call actually creates its own seperate CMD instance, resulting in the powershell script not seeing any of the declarations. But if I could do it all in one line, that problem would be solved. – Masamune_Shadow Jul 31 '13 at 19:53

2 Answers2

14

As Ansgar points out, a better solution would be to daisy-chain the commands as follows:

set "A=foo" & set "B=bar" & set "C=baz"

You could even inline the script execution also:

set "A=foo" & set "B=bar" & set "C=baz" & Powershell -File "$(ProjectDir)POSTBUILD.ps1"
Nate Anderson
  • 18,334
  • 18
  • 100
  • 135
Matthew Fellows
  • 3,669
  • 1
  • 15
  • 18
  • 10
    Shouldn't it be `set A=foo & set B=bar & set C=baz` instead of `set A=foo & B=bar & C=baz`? – sdbbs Apr 04 '19 at 10:54
  • I agree with @sdbbs (must repeat the `set` keyword), and @Ansgar also repeated the `set` keyword, so I made this edit. I also think it's best to [use quotes, like @Ansgar does](https://stackoverflow.com/questions/17978685/is-it-possible-to-set-multiple-environment-variables-in-one-cmd-line-statement#comment36459234_17978718); otherwise the training whitespace spaces will become part of your variable value: `>set A=foo & set B=bar`, then `>echo _%A%_` -> `_foo _` So I'll make that edit, too... – Nate Anderson Jan 08 '23 at 00:37
11

Yes, you can pipe the commands together:

set A="hi" | set B="bye"
Dan Schnau
  • 1,505
  • 14
  • 17
  • 2
    Works great! That's exactly what I needed. I would +1 if I could, damn +15 rep min... – Masamune_Shadow Jul 31 '13 at 19:54
  • 9
    Using a pipe for this is bad semantic. The pipe is an operator for connecting STDOUT of one command to STDIN of another command. `CMD` provides the `&` operator for daisy-chaining commands. Also, you may want to put the double quotes around the whole assignment, otherwise they'll become part of the value. Like this: `set "A=hi" & set "B=bye" & ...`. – Ansgar Wiechers Jul 31 '13 at 20:22
  • Thanks Ansgar. I had a feeling that pipes weren't the best way to go about it, but it would get the job done. – Dan Schnau Jul 31 '13 at 22:13
  • Hmm, I see... Since implementing the pipes the command now hangs indefinitly during the build. I'll try out the & and double quoting the assignments and see where that gets me. Thanks for the input as well. – Masamune_Shadow Aug 01 '13 at 12:27
  • 1
    @AnsgarWiechers - Careful, you're setting `A` and `B` to `hi ` and `bye ` (with spaces at the end), respectively. I was piping such results to GnuWin32 `sed` and nearly pulling my hair out trying to figure out why the variables weren't matching: it was because of the space. Instead, you have to do `set "A=hi"& set "B=bye"& ...` without spaces preceding the ampersand. – Andrew Cheong May 02 '14 at 02:46
  • 3
    @AndrewCheong No. The double quotes around the assignment expression (`"VAR=value"`) prevent the inclusion of trailing whitespace. You can verify that with something like `echo _%A%_`. – Ansgar Wiechers May 18 '14 at 11:36
  • @AnsgarWiechers - Ah, yes, sorry. I made that comment when I was still learning. Thanks for the clarification. – Andrew Cheong May 18 '14 at 19:24
  • The answer is simply wrong! Using a pipe creates the variables in two sub processes, the processes will be removed directly, so there are no variables set at all – jeb Nov 20 '22 at 15:34