【问题标题】:How can I set the WiX installer version to the current build version?如何将 WiX 安装程序版本设置为当前构建版本?
【发布时间】:2009-03-09 12:32:19
【问题描述】:

我编写了一个应用程序及其 WiX 安装程序,并使用 subversion 将其置于版本控制之下。当 WiX 安装程序构建时,我希望它的版本号是应用程序的当前构建版本。我该如何做到这一点?我使用 c# 编写应用程序。

注意我正在使用 ccnet 来构建这个项目

【问题讨论】:

    标签: c# svn wix


    【解决方案1】:

    您可以使用Product/@Version="!(bind.FileVersion.FileId)"(将FileId 替换为您要从中获取版本号的文件的Id),light.exe 将使用引用的文件的版本填充该值FileId

    【讨论】:

    • 请注意,“Fileid”应该是来自 元素的值,并且显然可以包含点 (.) 字符。
    • 捆绑/引导程序也可以这样做吗?
    • 当我在 product.wxs 中指定 Product/@Version="!(bind.FileVersion.FileId)" 时出现 Light.exe 错误,需要帮助!!!
    • 相关文档的链接,部分:Binder Variables
    • Binder 变量在 WiX 文档中应该有更高的可见性。我花了几个小时来处理预处理器变量,现在我可以用两个简单的 Binder 变量替换它们。
    【解决方案2】:

    我在我的一个项目中通过编写预处理器扩展来从我的可执行文件中读取文件版本来做到这一点。所以 WiX 文件看起来像:

    <?define ProductName="$(fileVersion.ProductName($(var.MyApp.TargetPath)))" ?>
    <?define CompanyName="$(fileVersion.CompanyName($(var.MyApp.TargetPath)))" ?>
    <?define ProductVersion="$(fileVersion.ProductVersion($(var.MyApp.TargetPath)))" ?>
    <Product 
        Id="<product ID>" 
        Name="$(var.ProductName)" 
        Version="$(var.ProductVersion)" 
        Manufacturer="$(var.CompanyName)" 
        Language="1033" 
        UpgradeCode="<upgrade code>">
    

    我已经在 CodePlex 上发布了 in 的代码:http://wixfileversionext.codeplex.com/

    【讨论】:

    • 你的扩展还能用吗?我尝试将其添加为参考,但出现错误。
    • 这个扩展在 Wix 3.5 上运行良好,在更新到 Wix 3.9 后它会抛出 NullPointerException。显然,这些版本之间出现了问题。
    • CodePlex 链接没有为我打开。除了编写自己的预处理器扩展之外,还有其他方法吗?
    【解决方案3】:

    如果有人正在寻找一个实际的 XML 示例,这适用于 .NET 程序集(您不必执行 Assembly 或 KeyPath 属性)。我用 [...] 占位符消除了不相关的代码:

    <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
        <Product [...] Version="!(bind.fileVersion.MyDLL)">
            [...]
            <Directory Id="TARGETDIR" Name="SourceDir">
                <Directory Id="ProgramFilesFolder" Name="PFiles">
                    <Directory Id="INSTALLDIR" Name="MyDLLInstallLocation">
                        <Component Id="MainLib" Guid="[...]">
                            <File Id="MyDLL" Name="MyDll.dll" Source="MyDll.dll" />
                            [...]
                        </Component>
                        [...]
                    </Directory>
                </Directory>
            </Directory>
        </Product>
    </Wix>
    

    【讨论】:

    • 这是一个更好的答案。感谢您的工作示例。
    • 它在哪里获取实际版本号?
    • @foobar 我在这里已经有一段时间了,但是如果您查看字符串!(bind.fileVersion.MyDLL),它使用第三部分引用&lt;File Id="MyDLL"... 部分
    • 这对我来说效果很好。适用于已编译的可执行文件以及 dll,非常适合将安装程序版本和 UI 内容固定到 exe 程序集信息,而无需在多个地方进行更改
    【解决方案4】:

    这是一种非常简单的方法,可以使用 BeforeBuild TargetDefineConstants 让您的 Bootstrapper Bundle 版本与您的 MyApp AssemblyVersion 匹配。

    Bundle.wxs:

    <Bundle Name="$(var.ProductName) Bootstrapper v$(var.BuildVersion)"
         Version="$(var.BuildVersion)"
    

    Bootstrapper.wixproj:

    <Target Name="BeforeBuild">
      <GetAssemblyIdentity AssemblyFiles="..\MyApp\bin\$(Configuration)\MyApp.exe">
        <Output TaskParameter="Assemblies" ItemName="AssemblyVersion" />
      </GetAssemblyIdentity>
      <PropertyGroup>
        <DefineConstants>BuildVersion=%(AssemblyVersion.Version)</DefineConstants>
      </PropertyGroup>
    </Target>
    

    【讨论】:

    • @AliKazmi 您是否在&lt;Bundle&gt; 上方的某个位置定义了var.ProductNamevar.BuildVersion
    • 我试过这个,但不能推荐这个 - 将它与 TeamCity 的装配修补程序结合起来,你就有了一个成功的公式。我没有使用 Bundle 元素,而是使用了产品元素,并且仍然为我工作。
    • VS 只是喜欢忽略 BeforeBuild 目标,因此如果您在 IDE 中构建,可能需要明确指定 AfterTargets="AfterResolveReferences"
    • 我在 *.wixproj 和 Product.wxs 文件中添加了 Bootstrapper.wixproj 代码,我将 buildversion 变量定义为:
    【解决方案5】:

    您可以将版本传递给安装项目的 MSBuild 脚本,就像传递给应用程序的构建脚本一样。

    例如,如果您的 CI 系统定义了变量 AppVersionBuildNumber,并将它们传递给您的 MSBuild 脚本,那么您的 wixproj 可以创建一个相应的 Version 属性,并将其转发给 Wix,如下所示:

    <PropertyGroup>
        <Version Condition=" '$(BuildNumber)' == '' ">0.0.1</Version>
        <Version Condition=" '$(BuildNumber)' != '' ">$(AppVersion).$(BuildNumber)</Version>
        <DefineConstants>Version=$(Version)</DefineConstants>
    </PropertyGroup>
    

    Version 的第一个定义为您在本地构建时提供了一个默认值。无论最终结果如何,都会成为 Wix 中的 Version 变量。在这样的 wsx 文件中使用它:

    <Product Version="$(var.Version)" ...>
        <Package Description="$(var.ProductName) $(var.Version): $(var.ProductDescription)" ... />
    

    我喜欢在描述中包含版本,以便可以轻松地从窗口资源管理器(作为详细信息视图或属性页面中的一列)查找,而与文件名无关。

    与从文件中读取版本相比,将版本作为变量传递给您更多的控制权。当您从文件中读取时,您将获得程序化版本的所有 4 个部分。但是,ProductVersion 仅设计为使用前 3 部分。

    【讨论】:

    • 谢谢,这拯救了我的一天。顺便说一句:截断的上层代码进入你的项目(*.wxiproj)。必须管理 Devops/VSTS CI-Build 这是最好的答案。因为我已经准备好我的最终版本变量。在我的情况下,它变成了:&lt;Version Condition=" '$(BuildVersionOfAsm)' != '' "&gt;$(BuildVersionOfAsm)&lt;/Version&gt; 而 BuildVersionOfAsm 是 devops 管道中的一个变量。
    • 我想动态选择版本,这种方法需要我不断更新 *.wixproj 中的版本。有没有办法在这个领域的任何 dll 的版本?
    • @RDV 这种方法的目的是不更改源代码管理中的任何文件,包括 .wixproj。动态版本号由您的 CI 系统提供(本示例中为 AppVersion 和 BuildNumber)。通常,您将主要和次要版本号设置为 CI 变量,并让 CI 系统动态生成内部版本号。
    • 优秀 - 正是我需要的那种解决方案,包括本地构建的默认值。
    【解决方案6】:

    这看起来与您想要完成的目标相当接近。看看巡航控制中的等价物。

    http://www.ageektrapped.com/blog/setting-properties-for-wix-in-msbuild/

    【讨论】:

    • 感谢分享
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-03
    • 1970-01-01
    • 1970-01-01
    • 2017-11-15
    • 2017-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多