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

时间:2013-05-28 09:33:39

标签: visual-studio-2010 visual-studio wix wix3.7

我有这个使用所有不变路径的WIX命令,它不需要系统环境(不像这个例子http://weblogs.sqlteam.com/mladenp/archive/2010/02/23/WiX-3-Tutorial-Generating-filedirectory-fragments-with-Heat.exe.aspx):

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

它工作得很好,除了我们的构建服务器,其中解决方案路径中有一个空格并抛出此错误:

  

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

我无法改变路径,在我看来无论如何都不应该。

我的问题是: 我该如何解决这个问题? (我甚至不知道为什么WIX会为带引号的带引号的路径/字符串var制造麻烦)

5 个答案:

答案 0 :(得分:7)

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

  1. 创建一个include(myinclude.wxi)文件,您可以在其中定义变量及其值:
  2. <?xml version="1.0" encoding="utf-8"?>
    <Include> 
      <?define PackageSource="c:\somePath"?>
    </Include>
    
    1. 创建一个xsl文件(mytransform.xsl),用于将<?include myinclude.wxi?>添加到wxs文件中:
    2. <?xml version="1.0" encoding="UTF-8"?>
      <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:wix="http://schemas.microsoft.com/wix/2006/wi">
        <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
      
        <xsl:template match="wix:Wix">
          <xsl:copy>
            <xsl:processing-instruction name="include">myInclude.wxi</xsl:processing-instruction>
            <xsl:apply-templates/>
          </xsl:copy>
        </xsl:template>
      
        <!-- Identity transform. -->
        <xsl:template match="@*|node()">
          <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
          </xsl:copy>
        </xsl:template>
      </xsl:stylesheet>
      
      1. 运行heat并指定指向转换的-t参数:

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

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

答案 1 :(得分:5)

对于这种情况,您可以在项目属性的“构建”部分中定义预处理器变量,在您的情况下PackageSource=Web\obj\$(Configuration)\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"

答案 2 :(得分:3)

-var开关提供预处理器变量的名称。像var.Foo这样的东西。预处理程序变量名称中不能包含空格。值wix.PackageSource=Whatever SolutionDir Expands To\Web\obj\Whatever Configuration Expands To\Package不是预处理器变量的有效名称,因为它中包含空格。我希望反斜杠也是一个问题。

答案 3 :(得分:2)

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

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

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

答案 4 :(得分:0)

我刚刚遇到了这个问题,并通过在解决方案文件夹中执行并使用相对路径解决了它。

这是可行的,因为我碰巧在 Jenkins 正在执行的 PowerShell 脚本中运行热量。

基于以下假设:

  • 执行 PowerShell 脚本符合您的构建方法
  • PowerShell 脚本位于解决方案目录中的文件夹中

提问者的脚本可能如下所示:

$SolutionDir = (get-item $PSScriptRoot).Parent.FullName
Set-Location $SolutionDir
& $env:WIX\bin\heat.exe" dir "$SolutionDir\Web\obj\$(Configuration)\Package" 
    -cg PACKAGEFILES -gg -g1 -sreg -srd -dr DEPLOYFOLDER 
    -var wix.PackageSource=".\Web\obj\$(Configuration)\Package"
    -out "$SolutionDir\WebInstaller\PackageFragment.wxs"