Como posso definir a versão do instalador do WiX para a versão de compilação atual?

134

Eu escrevi um aplicativo e seu instalador WiX e o coloquei sob controle de versão usando o subversion. Quando o instalador do WiX cria, quero que o número da versão seja a versão atual do aplicativo. Como eu faço isso? Eu usei c # para codificar o aplicativo.

NB eu estou usando o ccnet para construir este projeto

Draco
fonte

Respostas:

181

Você poderia usar Product/@Version="!(bind.FileVersion.FileId)"(substitua FileIdcom o Iddo arquivo a partir do qual você gostaria de obter o número da versão) e light.exe irá preencher o valor com a versão do arquivo referenciado pelo FileId.

Rob Mensching
fonte
4
É mesmo o que eu procurava! Embora eu tivesse que usar "! (Bind.FileVersion.FileId)" (a "!" Em vez de "$"), caso contrário, recebi um erro de diretiva de pré-processador.
Nicholas Piasecki
8
Sim, desculpe, erro mental constante que eu faço. $ é variável de pré-processador e! é variável do fichário.
Rob Mensching
20
Observe que "Fileid" deve ser o valor de um elemento <File Id = "Fileid" ...> e, aparentemente, pode incluir o caractere de ponto (.).
precisa saber é o seguinte
6
Também é possível fazer isso para um pacote configurável / bootstrapper?
Noelicus
6
Um link para a documentação relacionada, seção: Variáveis ​​do fichário
mcdon
39

Eu fiz isso em um dos meus projetos escrevendo uma extensão do pré-processador para ler a versão do arquivo do meu executável. Portanto, o arquivo WiX se parece com:

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

Publiquei o código no CodePlex: http://wixfileversionext.codeplex.com/

Chris Kaczor
fonte
Sua extensão ainda funciona? Tentei adicioná-lo como referência e recebi um erro.
Stefan Vasiljevic
Esta extensão funcionou muito bem com o Wix 3.5, após a atualização para o Wix 3.9, ele lança uma NullPointerException. Obviamente, algo quebrou entre essas versões.
Gigo 13/07/2015
2
@ Gigo eu consegui trabalhar via <?define ProductName="!(bind.property.ProductName)" ?><?define CompanyName="!(bind.property.Manufacturer)" ?><?define ProductVersion=!(bind.FileVersion.FileId) ?> Where FileIdé o valor do Idatributo de um dos seus Fileelementos dentro de um Component.
Jared
O link do CodePlex não está abrindo para mim. Existe outra maneira, exceto escrever sua própria extensão de pré-processador?
RDV
28

Caso alguém esteja procurando um exemplo XML real, isso funciona com assemblies .NET (e você não precisa executar os atributos Assembly ou KeyPath). Eu eliminei o código não relacionado com [...] marcadores de posição:

<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>
K0D4
fonte
1
Esta é uma resposta muito melhor. Obrigado pelo exemplo de trabalho.
rola
onde está buscando o número da versão real?
foobar
@foobar Sua sido um tempo desde que eu estava aqui, mas se você olhar para a string !(bind.fileVersion.MyDLL)que usa a terceira parte em referência à <File Id="MyDLL"...seção
K0D4
Isto funcionou bem para mim. Obras para executáveis compilados, bem como dll que é ótimo para prendendo a versão do instalador e conteúdo UI às informações de montagem exe, sem ter que as coisas mudam em vários lugares
rcbevans
21

Aqui está uma maneira muito simples de fazer com que sua versão do pacote do Bootstrapper corresponda ao seu MyApp AssemblyVersion usando BeforeBuild Targete DefineConstants.

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>
Brock Hensley
fonte
@AliKazmi Você já definiu seu var.ProductNamee em var.BuildVersionalgum lugar acima do seu <Bundle>?
Brock Hensley 27/03
2
Eu tentei isso e não posso recomendar o suficiente - combine-o com o patcher de montagem do TeamCity e você terá uma fórmula vencedora. Eu não usei o elemento Bundle, mas um elemento de produto e ainda funcionava para mim.
IbrarMumtaz
VS adora ignorar BeforeBuilddestino, portanto, pode ser necessário especificar explicitamente AfterTargets="AfterResolveReferences"se você está construindo no IDE
Dmitry
Adicionei o código Bootstrapper.wixproj no meu arquivo * .wixproj e no arquivo Product.wxs, defini a variável buildversion como:
RDV
4

Você pode passar a versão para o script MSBuild para o seu projeto de instalação da mesma forma que pode passar para o script de compilação do aplicativo.

Por exemplo, se o seu sistema de IC define variáveis AppVersione as BuildNumbertransmite aos scripts do MSBuild, seu wixproj pode criar uma Versionpropriedade correspondente que encaminha para o Wix assim:

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

A primeira definição de Versionfornece um padrão para quando você está construindo localmente. Tudo o que acaba se torna uma Versionvariável no Wix. Use-o em um arquivo wsx como este:

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

Eu gosto de incluir a versão na descrição, para que seja fácil procurar no Windows Explorer (como uma coluna na exibição Detalhes ou na página Propriedades) independentemente do nome do arquivo.

Passar a versão como uma variável oferece mais controle do que lê-la em um arquivo. Ao ler de um arquivo, você obtém todas as 4 partes da versão programática. No entanto, ProductVersion foi projetado apenas para usar as três primeiras partes.

Edward Brey
fonte
Obrigado, isso salvou meu dia. BTW: O código superior capturado entra no seu projeto (* .wxiproj). Ter que gerenciar um Devops / VSTS CI-Build é a melhor resposta. Como eu já tenho minha variável de versão final pronta. No meu caso, virou-se para: <Version Condition=" '$(BuildVersionOfAsm)' != '' ">$(BuildVersionOfAsm)</Version>enquanto BuildVersionOfAsm é uma variável nos pipeline de devops.
Robetto 28/08/19
Quero escolher a versão dinamicamente, esse método exigirá que eu continue atualizando a versão em * .wixproj. Existe um caminho para a versão de qualquer DLL neste campo?
RDV
@RDV A intenção dessa abordagem não é alterar nenhum arquivo no controle de origem, incluindo o .wixproj. O número da versão dinâmica é fornecido pelo seu sistema de IC (AppVersion e BuildNumber neste exemplo). Normalmente, você define os números de versão principais e secundários como variáveis ​​de IC e permite que o sistema de IC gere o número de compilação dinamicamente.
Edward Brey
Excelente - exatamente o tipo de solução que eu precisava, incluindo um padrão para compilações locais.
ColH