Spaced paths, msbuild, and psake
Asked Answered
M

1

1

Related question here.

This works properly for compiling an mvc3 application.

task Compile 
{
    $config = $script:siteConfig.config

    exec { & "C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe" $webproject_path `
    /p:Configuration=$config /p:WebProjectOutputDir="$publish_dir" `
    /p:Outdir="$out_dir" /p:CleanWebProjectOutputDir=False `
    /T:_WPPCopyWebApplication /T:ResolveReferences /verbosity:quiet /nologo }
}

All of those path variables are script properties. However, when spaces are introduced in those calculated paths (e.g. the project is moved from C:\Projects\ to C:\Users\ASDFG1\Documents\Visual Studio 2010\Projects) msbuild thinks there's multiple project files. This makes sense but I have to be missing something, getting a parsed variable into quotes shouldn't be this hard.

Variations tried

exec { Invoke-Expression "& C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe '$webproject_path' /p:Configuration=$config /p:WebProjectOutputDir='$publish_dir' /p:Outdir='$out_dir' /p:CleanWebProjectOutputDir=False /T:_WPPCopyWebApplication /T:ResolveReferences /verbosity:quiet /nologo" }

exec { C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe "`"$webproject_path`"" `
/p:Configuration=$config /p:WebProjectOutputDir="`"$publish_dir`"" `
/p:Outdir="`"$out_dir`"" /p:CleanWebProjectOutputDir=False `
/T:_WPPCopyWebApplication /T:ResolveReferences /verbosity:quiet /nologo }
Meson answered 18/4, 2012 at 16:47 Comment(4)
Just a suggestion: Invoke-Expression is rarely a good choice in running commands and applications.Activator
Thanks, could you elaborate? I was trying whatever I could to get it to work but would be curious to know your logic.Meson
That's often the problem. PowerShell's handling of arguments to native commands is a bit strange at time and often people try whatever they can think of to get it working and often Invoke-Expression sneaks in. The point is that Invoke-Expression doesn't change anything about how the command is run, it just adds a layer of indirection that incurs its own problems sometimes. Unless you're really building a PowerShell command at runtime to execute, Invoke-Expression is best avoided.Activator
when you use single quotes you stop the string interpolation from being applied. For example '$webproject_path' will be output as msbuild $webproject_path instead of the actual path to the project. use "" instead.Dunkin
S
0

Using EchoArgs.exe to reproduce the problem, we see that quotes are not being passed to the executable as desired:

PS> $publish_dir = 'C:\Users\Documents\Visual Studio 2010\Projects'
PS> ./echoargs /p:WebProjectOutputDir="$publish_dir"
Arg 0 is </p:WebProjectOutputDir=C:\Users\Documents\Visual Studio 2010\Projects>

PS> ./echoargs /p:WebProjectOutputDir="`"$publish_dir`""
Arg 0 is </p:WebProjectOutputDir=C:\Users\Documents\Visual>
Arg 1 is <Studio>
Arg 2 is <2010\Projects>


Using the backslash-escaping option from this answer, we can preserve the variable expansion and the enclosing quotes:

PS> ./echoargs /p:WebProjectOutputDir=\`"$publish_dir\`"
Arg 0 is </p:WebProjectOutputDir="C:\Users\Documents\Visual Studio 2010\Projects">

Here, the backticks tell PowerShell to treat the quote characters as literal values, and the backslash tells the call invocation to preserve the quotes.


Alternatively, we could stick with a single level of escaping by evaluating the full argument beforehand, instead of inlining the $publish_dir variable:

PS> $publishArg = '/p:WebProjectOutputDir=\"{0}\"' -f $publish_dir
PS> ./echoargs $publishArg
Arg 0 is </p:WebProjectOutputDir="C:\Users\Documents\Visual Studio 2010\Projects">
Simper answered 23/6, 2012 at 21:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.