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.