Powershell not interpreting spaces correctly

Welcome Forums General PowerShell Q&A Powershell not interpreting spaces correctly

This topic contains 4 replies, has 2 voices, and was last updated by

bob
 
Participant
3 months, 2 weeks ago.

  • Author
    Posts
  • #104131
    bob

    Participant
    Points: 0
    Rank: Member

    I have a script that is used to copy common binaries to known folders. This script is invoked by the build system after a successful build. This script is failing because Powershell is not parsing the arguments correctly that have spaces in them.

    I tried searching for "Powershell -File" and "running a script from cmd.exe" but I didn't find an answer.
    Any help in determining whether the failure is user error or a bug would be appreciated.

    The shell the build system uses in the NT command shell so I need call Powershell.exe with the -File parameter passing in the script and arguments. The arguments have spaces so must be quoted

    Here is a script that will demonstrate the problem

    "The number of parameters passed in is $($Args.Count)"
    $i = 0
    foreach ($arg in $Args) { echo "The $i parameter is $arg"; $i++ }
    

    Here is the output of the above command line ran from the "NT shell" using single quotes
    The number of parameters passed in is 7
    The 0 parameter is 'D:\Users\robertla\Documents\Visual
    The 1 parameter is Studio
    The 2 parameter is 2017\Samples\Debug_Utilities\'
    The 3 parameter is 'Debug
    The 4 parameter is Utilities'
    The 5 parameter is '.dll'
    The 6 parameter is 'Debug'

    Using double quotes fails differently. The behavior is the same way as if the script was invoked from a Powershell shell
    The number of parameters passed in is 2
    The 0 parameter is D:\Users\robertla\Documents\Visual Studio 2017\Samples\Debug_Utilities" Debug
    The 1 parameter is Utilities .dll Debug

    thx
    bob

  • #104149

    Participant
    Points: 0
    Rank: Member

    Double quotes should work fine e.g.

    #Saved as E:\temp\testme.ps1
    foreach ($arg in $args) {
    	Write-Host $arg
    }

    From cmd:

    powershell.exe -file E:\temp\testme.ps1 "D:\Users\robertla\Documents\Visual Studio 2017\Samples\Debug_Utilities\Debug Utilities.dll"

    Output

    D:\Users\robertla\Documents\Visual Studio 2017\Samples\Debug_Utilities\Debug Utilities.dll
    

    What's the source of the argument? Does the source have any extra quotes or line breaks that might screw things up?

  • #104218
    bob

    Participant
    Points: 0
    Rank: Member

    The source is Visual Studio (VS) which has a number of macros. However the problem can be duplicated outside of Visual Studio

    The macros I'm using to pass to the script are the: Project Name and Directory, type of binary (LIB/DLL) and whether this is a retail or debug build. This gives me enough information to copy the PDB and binary files to the LIB or BIN folder and the header to the Include folder so that other projects can access them.

    To reproduce this behavior outside VS I've copied values of these macros, here they are again. Note this is a partial and not full path. Please try this as is either in NT shell (cmd.exe) or Powershell

    powershell.exe -file E:\temp\testme.ps1 "D:\Users\robertla\Documents\Visual Studio 2017\Samples\Debug_Utilities\" "Debug Utilities.dll"
    

    I find it interesting that Powershell correctly interprets the strings when one of the string values are a complete path to a file c:\\...\ rather than a partial path c:\\...\ but that doesn't help me.

    The behavior is slightly different when using single vs double quotes in the NT shell rather than Powershell. The reason I'm testing in NT's shell is this is what VS will spawn in the Post-Build event. The reason for single quotes is Powershell pass the string along literally unlike double quotes where it pre-processes the string prior to passing it along

  • #104219

    Participant
    Points: 0
    Rank: Member

    Ok, I understand now.

    So what's happening is that the final \ on the path is causing the second " to be escaped.

    If you want to pass two arguments you can escape the \ by making the first argument

    "D:\Users\robertla\Documents\Visual Studio 2017\Samples\Debug_Utilities\\"

    Or you can join the items and pass as one argument using single quotes:

    "'D:\Users\robertla\Documents\Visual Studio 2017\Samples\Debug_Utilities\' 'Debug Utilities.dll'"
  • #104222
    bob

    Participant
    Points: 0
    Rank: Member

    Thanks Matt,

    I understand I can add a second \ or remove the trailing \ either would work. Trouble is I'm not the one that is passing the arguments VS is.

    I am passing this

    powershell  -ExecutionPolicy remotesigned -File "%SampleDir%\update.ps1"  "$(ProjectDir)"   "$(TargetName)"  "$(TargetExt)"   "$(Configuration)"
    

    VS will call the script filling in these values for the macro's

    powershell  -ExecutionPolicy remotesigned -File "%SampleDir%\update.ps1"  "D:\Users\robertla\Documents\Visual Studio 2017\Samples\Debug_Utilities\"   "Debug Utilities"  ".dll"   "Debug"
    

    While under the covers these two commands may work quite differently. I think we all agree that the input passed to the script should be the same

    powershell  -ExecutionPolicy remotesigned -File "$env:SampleDir\echo-args.ps1"  "D:\Users\robertla\Documents\Visual Studio 2017\Samples\Debug_Utilities\"   "Debug Utilities"  ".dll"   "Debug"
     & "$env:SampleDir\echo-args.ps1"  "D:\Users\robertla\Documents\Visual Studio 2017\Samples\Debug_Utilities\"   "Debug Utilities"  ".dll"   "Debug"
    

The topic ‘Powershell not interpreting spaces correctly’ is closed to new replies.