Jak mogę ustawić wersję instalatora WiX na aktualną wersję kompilacji?


134

Napisałem aplikację i jej instalator WiX i umieściłem ją pod kontrolą wersji za pomocą subversion. Podczas kompilacji instalatora WiX chcę, aby jego numer wersji był aktualną wersją kompilacji aplikacji. Jak to osiągnąć? Użyłem C # do zakodowania aplikacji.

NB używam ccnet do budowania tego projektu

Odpowiedzi:


181

Można używać Product/@Version="!(bind.FileVersion.FileId)"(zamiast FileIdz Idpliku, z którego chcesz uzyskać numer wersji) i light.exe propaguje wartości z wersją pliku odwołuje się FileId.


4
Właśnie tego szukałem! Chociaż musiałem użyć „! (Bind.FileVersion.FileId)” (a „!” Zamiast „$”), w przeciwnym razie otrzymałem błąd dyrektywy preprocesora.
— Nicholas Piasecki

8
Tak, przepraszam, popełniam ciągły mentalny błąd. $ jest zmienną preprocesora i! jest zmienną wiążącą.
— Rob Mensching

20
Zauważ, że „Fileid” powinno być wartością z elementu <File Id = „Fileid” ...> i najwyraźniej może zawierać kropkę (.).
— James Hugard

6
Czy można to zrobić również dla pakietu / programu ładującego?
— noelicus

6
Link do powiązanej dokumentacji, sekcja: Binder Variables
— mcdon

39

Zrobiłem to w jednym z moich projektów, pisząc rozszerzenie preprocesora, aby odczytać wersję pliku z mojego pliku wykonywalnego. Więc plik WiX wygląda mniej więcej tak:

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

Opublikowałem kod w witrynie CodePlex: http://wixfileversionext.codeplex.com/


Czy Twoje rozszerzenie nadal działa? Próbowałem dodać go jako odniesienie i otrzymałem błąd.
— Stefan Vasiljevic

To rozszerzenie działało świetnie z Wix 3.5, po aktualizacji do Wix 3.9 zgłasza wyjątek NullPointerException. Oczywiście między tymi wersjami coś się zepsuło.
— Gigo,

2
@Gigo Mam to działające przez <?define ProductName="!(bind.property.ProductName)" ?><?define CompanyName="!(bind.property.Manufacturer)" ?><?define ProductVersion=!(bind.FileVersion.FileId) ?> Gdzie FileIdjest wartość Idatrybutu jednego z twoich Fileelementów wewnątrz Component.
— Jared

Link CodePlex nie otwiera się dla mnie. Czy jest inny sposób niż napisanie własnego rozszerzenia preprocesora?
— RDV,

28

Jeśli ktoś szuka rzeczywistego przykładu XML, działa to z zespołami .NET (i nie musisz wykonywać atrybutów Assembly lub KeyPath). Usunąłem niepowiązany kod z [...] posiadaczami miejsc:

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

1
To znacznie lepsza odpowiedź. Dziękuję za działający przykład.
— rolki

gdzie pobiera aktualny numer wersji?
— foobar

@foobar Minęło trochę czasu, odkąd tu byłem, ale jeśli spojrzysz na ciąg !(bind.fileVersion.MyDLL), używa on trzeciej części w odniesieniu do <File Id="MyDLL"...sekcji
— K0D4

To działało dobrze dla mnie. Roboty skompilowanych plików wykonywalnych oraz bibliotek DLL, który doskonale nadaje się do przypinania wersję instalatora i zawartość UI do informacji montażowej exe, bez konieczności zmiany rzeczy w wielu miejscach
— rcbevans

21

Oto bardzo prosty sposób na dopasowanie wersji pakietu Bootstrapper do wersji zestawu MyApp przy użyciu rozszerzenia BeforeBuild Targeti 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>

@AliKazmi Czy zdefiniowałeś swoje var.ProductNamei var.BuildVersiongdzieś powyżej <Bundle>?
— Brock Hensley,

2
Próbowałem tego i nie mogę tego wystarczająco polecić - połącz go z łatką do montażu dla TeamCity i masz zwycięską formułę. Nie użyłem elementu Bundle, ale element produktu i nadal dla mnie działało.
— IbrarMumtaz

VS uwielbia ignorować BeforeBuildcel, więc może być konieczne wyraźne określenie, AfterTargets="AfterResolveReferences"czy budujesz w IDE
— Dmitry

Dodałem kod Bootstrapper.wixproj w moim * .wixproj oraz w pliku Product.wxs, zdefiniowałem zmienną buildversion jako:
— RDV

4

Wersję można przekazać do skryptu programu MSBuild dla projektu instalacji w taki sam sposób, jak w przypadku skryptu kompilacji aplikacji.

Na przykład, jeśli twój system CI definiuje zmienne AppVersioni BuildNumberprzekazuje je do twoich skryptów MSBuild, twój wixproj może stworzyć odpowiednią Versionwłaściwość, którą przekaże do Wix w następujący sposób:

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

Pierwsza definicja Versionzawiera wartość domyślną podczas tworzenia lokalnego. Cokolwiek się skończy, stanie się Versionzmienną w Wix. Użyj go w pliku wsx takim jak ten:

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

Chciałbym dołączyć wersję do opisu, aby można było łatwo wyszukać ją z Eksploratora Windows (jako kolumna w widoku szczegółowym lub na stronie Właściwości) niezależnie od nazwy pliku.

Przekazanie wersji jako zmiennej zapewnia większą kontrolę niż odczytanie jej z pliku. Kiedy czytasz z pliku, otrzymujesz wszystkie 4 części wersji programistycznej. Jednak ProductVersion jest przeznaczony tylko do korzystania z pierwszych 3 części.


Dzięki, to uratowało mi dzień. Przy okazji: wycięty górny kod trafia do twojego projektu (* .wxiproj). Konieczność zarządzania Devops / VSTS CI-Build to najlepsza odpowiedź. Ponieważ mam już gotową zmienną ostatecznej wersji. W moim przypadku okazało się, że: <Version Condition=" '$(BuildVersionOfAsm)' != '' ">$(BuildVersionOfAsm)</Version>podczas gdy BuildVersionOfAsm jest zmienną w potokach DevOps.
— Robetto

Chcę dynamicznie wybierać wersję, ta metoda będzie wymagać ciągłego aktualizowania wersji w * .wixproj. Czy istnieje sposób na jakąkolwiek wersję dll w tym polu?
— RDV,

@RDV Celem tego podejścia nie jest zmiana żadnych plików w kontroli źródła, w tym .wixproj. Dynamiczny numer wersji jest dostarczany przez system CI (w tym przykładzie AppVersion i BuildNumber). Zazwyczaj numer wersji głównej i pomocniczej ustawia się jako zmienne CI i pozwala systemowi CI dynamicznie generować numer kompilacji.
— Edward Brey,

Doskonale - właśnie takie rozwiązanie, jakiego potrzebowałem, w tym domyślne dla kompilacji lokalnych.
— ColH

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.