2012-08-30 16 views
19

Nel mio Defines.wxi ho:Includere MajorVersion etc nel nome del file (OutputName) durante la creazione di file MSI (progetto Wix)

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

Nel mio MyProject.Setup.wixproj ho:

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

È possibile includere le variabili di versione nel nome del file in qualche modo, in modo che il mio file possa essere denominato MyProject.1.08.11.msi?

Questo non ha funzionato (tale variabile è definita):

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

questo non ha funzionato (tale variabile è definita):

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

Mi sembra molto chiaro per me che $ (MajorVersion) non è il modo corretto di recuperare la definizione dal file Defines.wxi. Cosa è?


Aggiornamento

Ho cercato di mettere questo in 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> 

E questo in 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)" ?> 

Non ha funzionato neanche. Hai ricevuto questi messaggi di errore:

  • Il valore dell'attributo Product/@ Version, '..', non è una versione valida. I valori della versione legale devono essere come 'x.x.x.x' dove x è un numero intero da 0 a 65534.
  • L'attributo Product/@ Version non è stato trovato; è richiesto .

risposta

12

Questo è quello che ho finito con, e funziona!

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)" ?> 
+1

quindi ... dopo aver provato parecchio, ho trovato che funziona come descritto, inoltre il ** define.wxi ** non è necessario. comunque sono rimasto bloccato per un po 'perché ho fatto copia-incolla del bit '' dal web, e in qualche modo c'era un personaggio speciale o qualcosa che VS non ha accettato - ho sempre avuto l'errore 'var.InstallerMajorVersion not found' . dopotutto funziona alla grande, soluzione davvero elegante! –

+0

appena identificato un altro potenziale errore: vuoi assicurarti che il tag '' non sia definito in un altro 'PropertyGroup', altrimenti ottieni un errore' var.InstallerMajorVersion non trovato'. –

4

Un modo sarebbe definire le variabili nello script MSBuild e aggiornarlo in Defines.wxi in fase di compilazione, come in this example.

Nello script MSBuild, è possibile definire le proprietà di versione come segue:

<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> 

poi eseguire il bersaglio UpdateWixVars aggiornerà i numeri di versione in Defines.wxi con i numeri di versione specificati nel progetto MSBuild.

Nota che non riuscivo a trovare una dll reale compilato con questo compito di generazione personalizzata, così ho dovuto crearlo:

  1. Scarica la fonte from here. Costruirlo e denominare il file Tranxition.BuildTasks.dll.
  2. aggiungere il riferimento al compito costruire in questo modo:

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

Grazie per la risposta. Mi piacerebbe risolverlo senza usare Tranxition. Ho aggiornato le mie domande con il mio ultimo tentativo che è in qualche modo simile. Avete qualche input su questo? –

+0

mentre questa risposta funziona, comporta l'aggiornamento manuale di un file per ogni build, preferisco la risposta di seguito che automatizza il processo – nrjohnstone

4

Non è possibile leggere il file .wxi dal file .wixproj. Quindi devi usare un altro modo per specificare la versione. Posso dare un esempio in cui leggo la versione da un assembly incluso nel programma di installazione, e uso quella versione per rinominare l'msi;

Aprire il file .wixproj in un editor e aggiungere una destinazione 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> 

Questa legge la versione da bin\program.exe, visualizza per scopi di debug, e cambia il TargetName, TargetFileName e TargetPath.

Dopo la riga contenente <Import Project="$(WixTargetsPath)" />, aggiungere il seguente per iniettare questo obiettivo nel processo di generazione:

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

Ho aggiornato la mia domanda con il mio ultimo tentativo. Potrebbe essere più chiaro ora. –

+0

Quindi devi usare 'DefineConstants' in un PropertyGroup' wixproj', vedi http://stackoverflow.com/a/627279/33499 – wimh

+0

sì l'ho fatto anch'io, incollato ora. mi sembra corretto, ma ottengo ancora quell'errore –

4

Nel file .wixproj. Aggiungi la seguente sezione poco prima del tag </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> 

Questo funziona per me.

8

Questa attività comune dovrebbe essere semplificata nelle versioni future di WiX!

Questa soluzione combina @Wimmel's e this post. Disegna la versione da un exe di destinazione, e in caso contrario non memorizza i numeri di versione nei file; non rinomina il file di output in post-build. Ma è necessario aggiornare la proprietà ProjectDefineConstants, da cui derivano gli argomenti della candela (in wix.targets). In caso contrario, l'aggiornamento della proprietà TargetPath non modifica gli input su 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> 
+0

Eccellente. La migliore soluzione qui. –

+0

Non farlo! http://wixtoolset.org/issues/4555/ – l33t

1

È possibile raggiungere questo obiettivo senza soluzione di continuità mediante l'attuazione di queste due risposte:

Le altre risposte sono troppo complesse!

PS: Se si vuole far cadere la quarta cifra, a seguito delle versioni semantica, si può fare in questo modo:

<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> 

Questo creerà un MSI di nome, per esempio, MyProject-1.2.3.x64.msi. Vedi this answer per ulteriori informazioni.

0

Questo è un esempio completo di un file wixproj in cui è possibile impostare un numero di versione nell'interfaccia utente e utilizzarlo per modificare il nome file di output msi.

In Visual Studio (ad esempio, 2015):

  • definire un numero di versione in "Definire le variabili preprocessore" nella finestra delle proprietà del progetto. Ho inserito VersionNumber = 1.14 per questo esempio ;
  • scaricare il progetto in solution explorer;
  • fare clic con il tasto destro del mouse sul progetto in Esplora soluzioni e selezionare modificare il file yourproject.wixproj;
  • aggiungere il codice nel Target Name = elemento "BeforeBuild" come mostrato di seguito.

    <?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> 
    
Problemi correlati