Visual studio 2010 WIX Heat.exe命令参数-var不接受空格?

Visual studio 2010 WIX Heat.exe命令参数-var不接受空格?,visual-studio-2010,visual-studio,wix,wix3.7,Visual Studio 2010,Visual Studio,Wix,Wix3.7,我有一个WIX命令,它使用所有不变路径,不需要系统环境(与本例不同): 它工作得很好,除了在我们的构建服务器上,解决方案路径中有一个空间,并且会引发以下错误: heat.exe错误HEAT5057:开关'-var'不允许使用值中的空格。请从以下值中删除中的空格:wix.PackageSource=C:\Build\Builds 1\26e27895ae75b7cb\CADPortal\src\trunk\Web\obj\Debug\Package 我不能改变这条路,在我看来,这也不必要 我的问题

我有一个WIX命令,它使用所有不变路径,不需要系统环境(与本例不同):

它工作得很好,除了在我们的构建服务器上,解决方案路径中有一个空间,并且会引发以下错误:

heat.exe错误HEAT5057:开关'-var'不允许使用值中的空格。请从以下值中删除中的空格:wix.PackageSource=C:\Build\Builds 1\26e27895ae75b7cb\CADPortal\src\trunk\Web\obj\Debug\Package

我不能改变这条路,在我看来,这也不必要

我的问题是:
我如何解决这个问题?(我甚至不明白为什么WIX会在带空格的引用路径/字符串var上制造麻烦)

开关
-var
提供预处理器变量的名称。类似于
var.Foo
。预处理器变量名中不能包含空格。值
wix.PackageSource=SolutionDir展开为\Web\obj\which Configuration展开为\Package
的值不是预处理器变量的有效名称,因为其中包含空格。我预计反斜杠也会有问题。

因此我最终编写了一些构建事件代码,将必要的定义插入顶部的热生成文件中,但位于起始WIX标记下。就我个人而言,如果你需要做这种恶作剧/黑客,我开始质疑WIX的力量

无论如何,这是我的完整构建事件代码,适合任何需要它的人。(它还查找MSBuild.exe的不变路径并创建web包。)

echo关闭
设置主题\u REGKEY=HKLM\Software\Microsoft\MSBuild\4.0
设置主题_REGVAL=MSBuildOverrideTasksPath
REM首先检查钥匙是否存在。
reg query%THEME_REGKEY%/v%THEME_REGVAL%2>nul||(回显不存在主题名称!&退出/b 1)
REM查询该值。通过findstr对其进行管道传输,以找到具有该值的匹配行。仅获取令牌3和行的其余部分。%%b是我们在这里感兴趣的。
设置主题名称=
对于/f“tokens=2,*”%%a in('reg query%THEME\u REGKEY%/v%THEME\u REGVAL%^ findstr%THEME\u REGVAL%')do(
设置主题名称=%%b
)
REM可能没有设置值
如果未定义主题名称(回显不存在主题名称!&退出/b 1)
REM将所有空格替换为+
设置主题名称=%THEME\u NAME:=+%
如果errorlevel 1转到BuildEventFailed
%主题名称%MSBuild“$(SolutionDir)Web\Web.csproj”/t:Build;包/p:Configuration=$(配置)
如果errorlevel 1转到BuildEventFailed
%wix%bin\heat.exe“dir”$(SolutionDir)Web\obj\$(配置)\Package-cg PACKAGEFILES-gg-g1-sreg-srd-dr DEPLOYFOLDER-var.PackageSource-out“$(SolutionDir)WebInstaller\PackageFragment.wxs”
REM FUNC“热修复”-在热生成片段顶部插入变量定义:
移动/Y“$(SolutionDir)WebInstaller\PackageFragment.wxs”temp.txt
(
对于(temp.txt)DO中的/F“tokens=*”%%A(
回声%%A
如果“%%A”等于(
回音^
)
)
)>“$(SolutionDir)WebInstaller\temp.txt”
移动/Y“$(SolutionDir)WebInstaller\temp.txt”“$(SolutionDir)WebInstaller\PackageFragment.wxs”
REM END FUNC“热修复”
转到BuildEventOK
:BuildEventFailed
$(ProjectName)的echo POSTBUILDSTEP失败
出口1
:BuildEventOK
$(ProjectName)的echo POSTBUILDSTEP已完成确定

对于这种情况,您可以在项目属性的“生成”部分中定义一个前置处理器变量,在您的情况下是
PackageSource=Web\obj\$(配置)\Package

在热火中的参考电话

"%wix%bin\heat.exe" dir "$(SolutionDir)Web\obj\$(Configuration)\Package"
                   -cg PACKAGEFILES -gg -g1 -sreg -srd -dr DEPLOYFOLDER
                   -var var.PackageSource
                   -out "$(SolutionDir)WebInstaller\PackageFragment.wxs"

要使用heat包含变量及其定义,请使用以下机制

  • 创建一个include(myinclude.wxi)文件,在其中定义变量及其值:
  • 
    
  • 创建一个xsl文件(mytransform.xsl),用于将
    添加到wxs文件:
  • 
    myInclude.wxi
    
  • 运行heat并指定指向变换的-t参数:

    heat.exe dir“c:\somePath”-cg PACKAGEFILES-gg-g1-sreg-srd-dr DEPLOYFOLDER-var PackageSource-t mytransform.xsl-out PackageFragment.wxs


  • 这将按预期创建PackageFragment.wxs文件,使用xsl转换添加include语句,并在编译msi时使用wxi文件中的变量值(稍后使用candle)。

    因此,将
    -var.PackageSource
    传递到heat。它只是将
    var.PackageSource
    写入到输出中,以后必须对其进行解析。您可以将它绑定到其他命令或.wxs文件中的值。您能描述一下如何做到这一点吗?我尝试将一个var传递给Heat,然后在另一个WXS文件中定义了这个var,该文件在Heat生成的文件中包含Heat file/references ComponentGroup。热文件似乎并没有包括在内。如果我禁用Heat并手动将var定义放入Heat生成的文件中,它就不起作用了。感谢Peter Shirtcliff的xsl语法,这帮了我一整天节省了很多时间……因为我从硬编码的组件文件列表切换到了Heat.exe生成的组件文件列表。非常感谢。
    echo off
    
    set THEME_REGKEY=HKLM\Software\Microsoft\MSBuild\4.0
    set THEME_REGVAL=MSBuildOverrideTasksPath
    
    REM Check for presence of key first.
    reg query %THEME_REGKEY% /v %THEME_REGVAL% 2>nul || (echo No theme name present! & exit /b 1)
    
    REM query the value. pipe it through findstr in order to find the matching line that has the value. only grab token 3 and the remainder of the line. %%b is what we are interested in here.
    set THEME_NAME=
    for /f "tokens=2,*" %%a in ('reg query %THEME_REGKEY% /v %THEME_REGVAL% ^| findstr %THEME_REGVAL%') do (
        set THEME_NAME=%%b
    )
    
    REM Possibly no value set
    if not defined THEME_NAME (echo No theme name present! & exit /b 1)
    
    REM replace any spaces with +
    set THEME_NAME=%THEME_NAME: =+%
    
    if errorlevel 1 goto BuildEventFailed
    %THEME_NAME%MSBuild  "$(SolutionDir)Web\Web.csproj" /t:Build;Package /p:Configuration=$(Configuration)
    if errorlevel 1 goto BuildEventFailed
    
    "%wix%bin\heat.exe" dir "$(SolutionDir)Web\obj\$(Configuration)\Package" -cg PACKAGEFILES -gg -g1 -sreg -srd -dr DEPLOYFOLDER -var var.PackageSource -out "$(SolutionDir)WebInstaller\PackageFragment.wxs"
    
    REM FUNC "HeatFix" - This inserts the var. definition in top of the heat generated fragment:
     MOVE /Y "$(SolutionDir)WebInstaller\PackageFragment.wxs" temp.txt
    (
      FOR /F "tokens=*" %%A IN (temp.txt) DO (
        ECHO %%A
        IF "%%A" EQU "<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">" (
          ECHO ^<^?define PackageSource^=^"$(SolutionDir)Web\obj\$(Configuration)\Package^"^?^>
        )
      )
    ) > "$(SolutionDir)WebInstaller\temp.txt"
    move /Y "$(SolutionDir)WebInstaller\temp.txt" "$(SolutionDir)WebInstaller\PackageFragment.wxs"
    REM END FUNC "HeatFix"
    
    goto BuildEventOK
    :BuildEventFailed
    echo POSTBUILDSTEP for $(ProjectName) FAILED
    exit 1
    :BuildEventOK
    echo POSTBUILDSTEP for $(ProjectName) COMPLETED OK
    
    "%wix%bin\heat.exe" dir "$(SolutionDir)Web\obj\$(Configuration)\Package"
                       -cg PACKAGEFILES -gg -g1 -sreg -srd -dr DEPLOYFOLDER
                       -var var.PackageSource
                       -out "$(SolutionDir)WebInstaller\PackageFragment.wxs"