包括MajorVersion等的文件名(OutputName)建设MSI文件时(WiX的项目)(In

2019-06-27 13:30发布

在我Defines.wxi我有:

<?define MajorVersion="1" ?>
<?define MinorVersion="08" ?>
<?define BuildVersion="11" ?>

在我MyProject.Setup.wixproj我有:

<OutputName>MyProject</OutputName>
<OutputType>Package</OutputType>

是否有可能在文件名莫名其妙的版本变量,这样我的文件可以被命名为MyProject.1.08.11.msi?

这没有工作(没有这样的变量定义):

<OutputName>MyProject-$(MajorVersion)</OutputName>
<OutputType>Package</OutputType>

这没有工作(没有这样的变量定义):

<Target Name="AfterBuild" Condition="'$(Configuration)' == 'Release'">
    <Copy SourceFiles="$(OutputPath)$(OutputName).msi" DestinationFiles="C:\$(OutputName)-$(MajorVersion).msi" />
</Target>

在我看来很清楚,$(MajorVersion)不取出由Defines.wxi文件定义的正确途径。 什么是?


更新

我试图把这个MyProject.Setup.wixproj:

<InstallerMajorVersion>7</InstallerMajorVersion>
<InstallerMinorVersion>7</InstallerMinorVersion>
<InstallerBuildNumber>7</InstallerBuildNumber>

...

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
    <OutputPath>bin\$(Configuration)\</OutputPath>
    <IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
    <DefineConstants>PrebuildPath=..\..\obj\prebuild\web\;InstallerMajorVersion=$(InstallerMajorVersion);InstallerMinorVersion=$(InstallerMinorVersion);InstallerBuildNumber=$(InstallerBuildNumber)</DefineConstants>
</PropertyGroup>

而这Defines.wxi:

<?define MajorVersion="$(var.InstallerMajorVersion)" ?>
<?define MinorVersion="$(var.InstallerMinorVersion)" ?>
<?define BuildVersion="$(var.InstallerBuildNumber)" ?>
<?define Revision="0" ?>
<?define VersionNumber="$(var.InstallerMajorVersion).$(var.InstallerMinorVersion).$(var.InstallerBuildNumber)" ?>

没有任何工作。 得到了这些错误信息:

  • 产品/ @ Version属性的值,“..”,不是一个有效的版本。 正版值应该像“XXXX”,其中x是从0到65534的整数。
  • 产品/ @ Version属性没有被发现; 它是必需的。

Answer 1:

这是我结束了,和它的作品!

Setup.Version.proj

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <InstallerMajorVersion>55</InstallerMajorVersion>
        <InstallerMinorVersion>66</InstallerMinorVersion>
    <InstallerBuildVersion>$(BuildNumber)</InstallerBuildVersion>
        <InstallerBuildVersion Condition="$(InstallerBuildVersion) == ''">0</InstallerBuildVersion>
  </PropertyGroup>
</Project>

MyProject.Setup.wixproj

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="Setup.Version.proj" />
  <PropertyGroup>
    <OutputName>MyProject_$(InstallerMajorVersion)_$(InstallerMinorVersion)_$(InstallerBuildVersion)</OutputName>
    <OutputType>Package</OutputType>
    <DefineConstants>InstallerMajorVersion=$(InstallerMajorVersion);InstallerMinorVersion=$(InstallerMinorVersion);InstallerBuildVersion=$(InstallerBuildVersion)</DefineConstants>
    ...

Defines.wxi

<?define MajorVersion="$(var.InstallerMajorVersion)" ?>
<?define MinorVersion="$(var.InstallerMinorVersion)" ?>
<?define BuildVersion="$(var.InstallerBuildVersion)" ?>


Answer 2:

这种共同的任务应该在维克斯的未来版本中被简化!

该解决方案结合了@ Wimmel的和这个职位 。 它借鉴的版本从目标.exe文件,否则版本号没有存储在文件中; 它不重命名生成后的输出文件。 但是,有必要更新属性ProjectDefineConstants,从蜡烛参数推导(在wix.targets)。 否则,仅更新TARGETPATH属性不会改变输入candle.exe。

* .wixproj:

<Import Project="$(WixTargetsPath)" />
<Target Name="BeforeBuild">
  <!-- Read the version from the to-be-installed .exe -->
  <GetAssemblyIdentity AssemblyFiles="path.to.primary.exe">
    <Output TaskParameter="Assemblies" ItemName="AsmInfo" />
  </GetAssemblyIdentity>

  <!-- Create the MSBuild property $(VersionNumber) -->
  <CreateProperty Value="%(AsmInfo.Version)">
    <Output TaskParameter="Value" PropertyName="VersionNumber" />
  </CreateProperty>

  <!-- Create the WiX preprocessor variable $(var.VersionNumber) -->
  <CreateProperty Value="$(DefineConstants);VersionNumber=$(VersionNumber)">
    <Output TaskParameter="Value" PropertyName="DefineConstants" />
  </CreateProperty>

  <!-- Update the MSBuild properties $(TargetName), etc. -->
  <CreateProperty Value="$(SolutionName)-$(Platform)-$(VersionNumber)">
    <Output TaskParameter="Value" PropertyName="TargetName" />
  </CreateProperty>
  <CreateProperty Value="$(TargetName)$(TargetExt)">
    <Output TaskParameter="Value" PropertyName="TargetFileName" />
  </CreateProperty>
  <CreateProperty Value="$(TargetName)$(TargetPdbExt)">
    <Output TaskParameter="Value" PropertyName="TargetPdbName" />
  </CreateProperty>
  <CreateProperty Value="$(TargetDir)$(TargetFileName)">
    <Output TaskParameter="Value" PropertyName="TargetPath" />
  </CreateProperty>
  <CreateProperty Value="$(TargetPdbDir)$(TargetPdbName)">
    <Output TaskParameter="Value" PropertyName="TargetPdbPath" />
  </CreateProperty>

  <!-- Update the MSBuild property from which candle.exe args are derived -->
  <CreateProperty Value="
    Configuration=$(ConfigurationName);
    OutDir=$(OutDir);
    Platform=$(PlatformName);
    ProjectDir=$(ProjectDir);
    ProjectExt=$(ProjectExt);
    ProjectFileName=$(ProjectFileName);
    ProjectName=$(ProjectName);
    ProjectPath=$(ProjectPath);
    TargetDir=$(TargetDir);
    TargetExt=$(TargetExt);
    TargetFileName=$(TargetFileName);
    TargetName=$(TargetName);
    TargetPath=$(TargetPath);
  ">
    <Output TaskParameter="Value" PropertyName="ProjectDefineConstants" />
  </CreateProperty>
</Target>

* .wxs

<Product Id="*" Version="$(var.VersionNumber)" ... >
  ...
</Product>


Answer 3:

在你.wixproj文件。 就在之前添加以下部分</Project>标签。

<!-- rename the output msi with Version number -->
  <Target Name="AfterBuild">
    <GetAssemblyIdentity AssemblyFiles="[Path of the main assembly with the assembly version number you want to use]">
      <Output TaskParameter="Assemblies" ItemName="AssemblyVersion"/>
    </GetAssemblyIdentity>
    <Copy SourceFiles=".\bin\$(Configuration)\$(OutputName).msi" DestinationFiles=".\bin\$(Configuration)\$(OutputName)_%(AssemblyVersion.Version).msi" />
    <Delete Files=".\bin\$(Configuration)\$(OutputName).msi" />
  </Target>

这对我的作品。



Answer 4:

这是不可能读取来自.wixproj文件.wxi文件。 所以,你必须用另一种方式来指定版本。 我可以给其中I读取从包括在安装一个组件的版本的示例,并且使用该版本来重命名MSI;

在编辑器中打开.wixproj文件,添加一个ReadVersion目标:

  <Target Name="ReadVersion">
    <GetAssemblyIdentity AssemblyFiles="bin\program.exe">
      <Output TaskParameter="Assemblies" ItemName="MyAssemblyIdentities" />
    </GetAssemblyIdentity>
    <Message Text="AssemblyVersion = %(MyAssemblyIdentities.Version)" />
    <CreateProperty Value="$(TargetName) %(MyAssemblyIdentities.Version)">
      <Output TaskParameter="Value" PropertyName="TargetName" />
    </CreateProperty>
    <CreateProperty Value="$(TargetName)$(TargetExt)">
      <Output TaskParameter="Value" PropertyName="TargetFileName" />
    </CreateProperty>
    <CreateProperty Value="$(OutDir)$(TargetFileName)">
      <Output TaskParameter="Value" PropertyName="TargetPath" />
    </CreateProperty>
  </Target>

这读取版本bin\program.exe ,显示它进行调试,并更改的TargetName,TargetFileName和TARGETPATH。

含有行之后<Import Project="$(WixTargetsPath)" />中,添加以下该目标注入构建过程:

  <PropertyGroup>
    <BuildDependsOn>ReadVersion;$(BuildDependsOn)</BuildDependsOn>
  </PropertyGroup>


Answer 5:

一种方法是在你的MSBuild脚本来定义变量,并将它在构建时更新Defines.wxi,在这个例子中 。

在你的MSBuild脚本,你可以如下定义版本属性:

  <PropertyGroup>
    <MajorVersion>1</MajorVersion>
    <MinorVersion>08</MinorVersion>
    <BuildVersion>11</BuildVersion>
    <WixConfigPath>.\Defines.wxi</WixConfigPath>

    <_VariableDefinitions>
      <Root>
        <VariableDefinition Name="MajorVersion" NewValue="$(MajorVersion)" />
        <VariableDefinition Name="MinorVersion" NewValue="$(MinorVersion)" />
        <VariableDefinition Name="BuildVersion" NewValue="$(BuildVersion)" />
      </Root>
    </_VariableDefinitions>
  </PropertyGroup>

  <Target Name="UpdateWixVars">
    <WixVarSubstitution SourceFile="$(WixConfigPath)" VariableDefinitions="$(_VariableDefinitions)"/>
  </Target>

然后运行UpdateWixVars目标将在您的MSBuild项目中指定的版本号更新Defines.wxi的版本号。

请注意,我找不到与此自定义生成任务的实际编译的.dll文件,所以我不得不来创建它:

  1. 下载源来自这里 。 建立并命名该文件Tranxition.BuildTasks.dll。
  2. 添加引用,像这样构建的任务:

     <UsingTask TaskName="WixVarSubstitution" AssemblyFile="$(MSBuildExtensionsPath)\Tranxition\Tranxition.BuildTasks.dll"/> 


Answer 6:

您可以通过实现这两个答案无缝地实现这一点:

  • 首先,更新项目的AfterBuild任务重命名维克斯建MSI: https://stackoverflow.com/a/10716409/374198
  • 然后,更新您的WiX工程自动使用你的软件包组件的verison数: https://stackoverflow.com/a/641094/374198

其他答案太复杂!

PS:如果你要删除的第四位,以下语义版本,你可以做这样的:

<Target Name="AfterBuild">
    <GetAssemblyIdentity AssemblyFiles="..\Path\To\MyProject\bin\$(Platform)\$(Configuration)\MyProject.dll">
        <Output TaskParameter="Assemblies" ItemName="AssemblyInfo" />
    </GetAssemblyIdentity>
    <PropertyGroup>
        <In>%(AssemblyInfo.Version)</In>
        <Pattern>^(\d+.\d+.\d+)</Pattern>
        <AssemblyVersion>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern)))</AssemblyVersion>
    </PropertyGroup>
    <Move SourceFiles="bin\$(Platform)\$(Configuration)\MyProject.msi" DestinationFiles="bin\$(Platform)\$(Configuration)\CodeGenerator-$(AssemblyVersion).$(Platform).msi" />
</Target>

这将创建一个MSI命名,例如, MyProject-1.2.3.x64.msi 。 见这个答案更多。



Answer 7:

这是一个wixproj文件,您可以设置在UI版本号并用它来修改输出MSI文件名的一个完整的例子。

在Visual Studio中(如2015年):

  • 定义在项目属性窗口中的“定义处理器变量”版本号。 我已经进入VERSIONNUMBER = 1.14这个例子;
  • 卸载在Solution Explorer中的项目;
  • 右键单击在Solution Explorer中,选择编辑yourproject.wixproj文件的项目;
  • 在目标名称=“BeforeBuild”元素添加代码,如下所示。

     <?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" DefaultTargets="Build" InitialTargets="EnsureWixToolsetInstalled" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Platform Condition=" '$(Platform)' == '' ">x86</Platform> <ProductVersion>3.10</ProductVersion> <ProjectGuid>PROJECT-GUID</ProjectGuid> <SchemaVersion>2.0</SchemaVersion> <OutputName>my project</OutputName> <OutputType>Package</OutputType> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' "> <OutputPath>bin\$(Configuration)\</OutputPath> <IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath> <!-- These constants can be set in the UI --> <DefineConstants>VersionNumber=1.14</DefineConstants> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' "> <OutputPath>bin\$(Configuration)\</OutputPath> <IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath> <DefineConstants>VersionNumber=1.14</DefineConstants> </PropertyGroup> <ItemGroup> <Compile Include="Product.wxs" /> </ItemGroup> <ItemGroup> <WixExtension Include="WixUIExtension"> <HintPath>$(WixExtDir)\WixUIExtension.dll</HintPath> <Name>WixUIExtension</Name> </WixExtension> </ItemGroup> <Import Project="$(WixTargetsPath)" Condition=" '$(WixTargetsPath)' != '' " /> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets" Condition=" '$(WixTargetsPath)' == '' AND Exists('$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets') " /> <Target Name="BeforeBuild"> <!-- This extracts the version number from a setting in the UI --> <!-- This method comes from: geekswithblogs.net/alexhildyard/archive/2013/03/09/passing-data-between-msbuild-and-wix.aspx --> <ItemGroup> <DefineConstantsKVPairs Include="$(DefineConstants)" /> </ItemGroup> <!-- Evaluate each key/value pair with task batching, then make a conditional assignment --> <PropertyGroup> <VersionNumber Condition="$([System.String]::new('%(DefineConstantsKVPairs.Identity)').Contains('VersionNumber='))">$([System.String]::new('%(DefineConstantsKVPairs.Identity)').Split('=')[1])</VersionNumber> </PropertyGroup> <CreateProperty Value="$(OutputName)-$(VersionNumber)"> <Output TaskParameter="Value" PropertyName="TargetName" /> </CreateProperty> <CreateProperty Value="$(TargetName)$(TargetExt)"> <Output TaskParameter="Value" PropertyName="TargetFileName" /> </CreateProperty> <CreateProperty Value="$(TargetDir)$(TargetFileName)"> <Output TaskParameter="Value" PropertyName="TargetPath" /> </CreateProperty> </Target> </Project> 


文章来源: Include MajorVersion etc in filename (OutputName) when building MSI file (wix project)