Powershell使用嵌套引号调用msbuild

时间:2011-06-03 08:17:48

标签: powershell msbuild psake

使用Powershell和Psake为visual studio解决方案创建包和部署。 尝试使用msbuild部署数据库项目 - 使用msdos visual studio命令行正常工作

   msbuild /target:Deploy /p:UseSandboxSettings=false /p:TargetConnectionString="aConnectionWithSpacesAndSemiColons" "aDatabaseProjectPathWithSpaces"

从powershell

调用时,相同的方法调用会导致错误
& msbuild /target:Deploy /p:UseSandboxSettings=false /p:TargetConnectionString="aConnectionWithSpacesAndSemiColons" "aDatabaseProjectPathWithSpaces"

与空格有关 - 无法弄清楚如何在powershell中复制此调用 - 示例数据库连接字符串     数据源=。\ SQL2008;初始目录= DocumentExecution; Integrated Security = True;

6 个答案:

答案 0 :(得分:11)

如果将Start-Process cmdlet与-ArgumentList参数一起使用,则可以使这一切变得更容易。我很惊讶,这已经没有提到过了。

示例:

Start-Process -FilePath msbuild.exe -ArgumentList '/target:Deploy /p:UseSandboxSettings=false /p:TargetConnectionString="aConnectionWithSpacesAndSemiColons" "aDatabaseProjectPathWithSpaces"';

这是我喜欢使用的方法,它允许变量替换:

$ConnectionString = 'aConnectionWithSpacesAndSemiColons';
$DatabaseProjectPath = 'aDatabaseProjectPathWithSpaces';
$MsbuildArguments = '/target:Deploy /p:UseSandboxSettings=false /p:TargetConnectionString="{0}" "{1}"' -f $ConnectionString, $DatabaseProjectPath;
Start-Process -FilePath msbuild.exe -ArgumentList $MsbuildArguments;

答案 1 :(得分:4)

将整个参数放在单引号中:

& msbuild /target:Deploy /p:UseSandboxSettings=false '/p:TargetConnectionString="aConnectionWithSpacesAndSemiColons"' "aDatabaseProjectPathWithSpaces"

额外的引用水平意味着PSH不会使用PSH规则处理内容。 (字符串中的任何单引号都需要加倍 - 这是PSH单引号字符串中唯一的转义类型。)

答案 2 :(得分:1)

@Richard - 测试这会产生一个不同的错误,表示没有提供有效的项目文件。 我通过echoargs pscx helper运行它来显示一些更详细的例子。

  1. 使用单个quoatation标记包装TargetConnectionString - Powershell将连接字符串中的每个空格评估为一个新行:

    & echoargs /target:Deploy /p:UseSandboxSettings=false    /p:TargetDatabase=UpdatedTargetDatabase /p:TargetConnectionString='"Data Source=(local)\SQLEXPRESS;Integrated Security=True;Pooling=False"' "C:\program files\MyProjectName.dbproj"
    
    Arg 0 is </target:Deploy>
    Arg 1 is </p:UseSandboxSettings=false>
    Arg 2 is </p:TargetDatabase=UpdatedTargetDatabase>
    Arg 3 is </p:TargetConnectionString=Data>
    Arg 4 is <Source=(local)\SQLEXPRESS;Integrated>
    Arg 5 is <Security=True;Pooling=False>
    Arg 6 is <C:\program files\MyProjectName.dbproj>
    
  2. 使用反引号分隔每个参数会重新创建初始问题=连接字符串周围没有引号:

    & echoargs /target:Deploy `
    /p:UseSandboxSettings=false `
    

    c /p:TargetConnectionString="Data Source=(local)\SQLEXPRESS;Integrated Security=True;Pooling=False"     “C:\ program files \ MyProjectName.dbproj”

    Arg 0 is </target:Deploy>
    Arg 1 is </p:UseSandboxSettings=false>
    Arg 2 is </p:TargetDatabase=UpdatedTargetDatabase>
    Arg 3 is </p:TargetConnectionString=Data Source=(local)\SQLEXPRESS;Integrated Se
    curity=True;Pooling=False>
    Arg 4 is <C:\program files\MyProjectName.dbproj>
    
  3. 向引号添加反引号的行为与示例1相同:

    & echoargs /target:Deploy `
    /p:UseSandboxSettings=false `
    /p:TargetDatabase=UpdatedTargetDatabase `
    "/p:TargetConnectionString=`"Data Source=(local)\SQLEXPRESS;Integrated Security=True;Pooling=False"`"  `
    "C:\program files\MyProjectName.dbproj"
    
  4. 使用@运算符尝试拆分参数仍然会忽略引号:

    $args = @('/target:Deploy','/p:UseSandboxSettings=false','     /p:TargetDatabase=UpdatedTargetDatabase','/p:TargetConnectionString="Data Source=(local)\SQLEXPRESS;Integrated Security=True;Pooling=False"','C:\program files\MyProjectName.dbproj'); $args 
    
    /target:Deploy
    /p:UseSandboxSettings=false
    /p:TargetDatabase=UpdatedTargetDatabase
    /p:TargetConnectionString="Data Source=(local)\SQLEXPRESS;Integrated           Security=True;Pooling=False"
    C:\program files\MyProjectName.dbproj
    
    & echoargs $args
    
  5. 使用行分隔符反对转义连接字符串 - 与示例1的结果相同:

    & echoargs /target:Deploy `
    /p:UseSandboxSettings=false `
    /p:TargetDatabase=UpdatedTargetDatabase `
    "/p:TargetConnectionString=`"Data Source=(local)\SQLEXPRESS;Integrated Security=True;Pooling=False"`" `
    "C:\program files\MyProjectName.dbproj"
    

答案 3 :(得分:1)

您的问题是PowerShell在将它们传递给命令行应用程序时不会转义引号。我自己遇到了这个,并认为PowerShell正在吃引号。就这样做。

msbuild /target:Deploy /p:UseSandboxSettings=false /p:TargetDatabase=UpdatedTargetDatabase '/p:TargetConnectionString=\"Data Source=(local)\SQLEXPRESS;Integrated Security=True;Pooling=False\"' "C:\program files\MyProjectName.dbproj"

答案 4 :(得分:1)

感谢JohnF的回答,我终于想出了这个。

echoargs /target:clean`;build`;deploy /p:UseSandboxSettings=false /p:TargetConnectionString=`"Data
Source=.`;Integrated Security=True`;Pooling=False`" .\MyProj.dbproj
Arg 0 is </target:clean;build;deploy>
Arg 1 is </p:UseSandboxSettings=false>
Arg 2 is </p:TargetConnectionString=Data Source=.;Integrated Security=True;Pooling=False>
Arg 3 is <.\MyProj.dbproj>

简而言之,但在双引号和分号前面的反推。任何不足(或更多!)都会搞砸了。

答案 5 :(得分:1)

this answer的文章中提到过,但是使用PowerShell 3可以使用 - %来停止PowerShell正常解析。

msbuild --% /target:Deploy /p:UseSandboxSettings=false /p:TargetConnectionString="aConnectionWithSpacesAndSemiColons" "aDatabaseProjectPathWithSpaces"