Bagaimana saya bisa mengatur versi penginstal WiX ke versi build saat ini?

134

Saya menulis sebuah aplikasi dan penginstal WiX-nya dan meletakkannya di bawah kendali versi menggunakan subversi. Ketika penginstal WiX membangun, saya ingin nomor versinya menjadi versi build aplikasi saat ini. Bagaimana saya mencapai ini? Saya menggunakan c # untuk kode aplikasi.

NB Saya menggunakan ccnet untuk membangun proyek ini

Draco
sumber

Jawaban:

181

Anda dapat menggunakan Product/@Version="!(bind.FileVersion.FileId)"(ganti FileIddengan Idfile dari mana Anda ingin mendapatkan nomor versi) dan light.exe akan mengisi nilai dengan versi file yang dirujuk oleh FileId.

Rob Mensching
sumber
4
Apa yang saya cari! Meskipun saya harus menggunakan "! (Bind.FileVersion.FileId)" (a "!" Bukannya "$"), kalau tidak saya mendapat kesalahan direktif preprocessor.
Nicholas Piasecki
8
Ya, maaf, kesalahan mental yang terus-menerus saya buat. $ adalah variabel preprocessor dan! adalah variabel pengikat.
Rob Mensching
20
Perhatikan bahwa "Fileid" harus berupa nilai dari elemen <File Id = "Fileid" ...>, dan tampaknya dapat menyertakan karakter titik (.).
James Hugard
6
Apakah mungkin untuk melakukan ini untuk bundle / bootstrapper juga?
noelicus
6
Tautan ke dokumentasi terkait, bagian: Variabel
Pengikat
39

Saya melakukan ini di salah satu proyek saya dengan menulis ekstensi preprocessor untuk membaca versi file dari executable saya. Jadi file WiX terlihat seperti:

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

Saya telah memposting kode untuk di pada CodePlex: http://wixfileversionext.codeplex.com/

Chris Kaczor
sumber
Apakah ekstensi Anda masih berfungsi? Saya mencoba menambahkannya sebagai referensi dan saya mendapat kesalahan.
Stefan Vasiljevic
Ekstensi ini bekerja sangat baik dengan Wix 3.5, setelah memperbarui ke Wix 3.9 ia melempar NullPointerException. Jelas ada sesuatu yang pecah di antara versi-versi ini.
Gigo
2
@Gigo Saya mendapatkannya berfungsi via <?define ProductName="!(bind.property.ProductName)" ?><?define CompanyName="!(bind.property.Manufacturer)" ?><?define ProductVersion=!(bind.FileVersion.FileId) ?> Di mana FileIdnilai Idatribut salah satu Fileelemen Anda di dalam a Component.
Jared
Tautan CodePlex tidak terbuka untuk saya. Apakah ada cara lain selain menulis ekstensi pra-prosesor Anda sendiri?
RDV
28

Jika seseorang mencari contoh XML yang sebenarnya, ini berfungsi dengan .NET assemblies (dan Anda tidak harus melakukan atribut Assembly atau KeyPath). Saya menghapus kode yang tidak terkait dengan tempat tempat [...]:

<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
sumber
1
Ini jawaban yang jauh lebih baik. Terima kasih atas contohnya.
gulungan
di mana itu mengambil nomor versi aktual?
foobar
@foobar Sudah lama sejak saya di sini, tetapi jika Anda melihat string !(bind.fileVersion.MyDLL)itu menggunakan bagian ke-3 dalam referensi ke <File Id="MyDLL"...bagian
K0D4
Ini bekerja dengan baik untuk saya. Bekerja untuk executable yang telah dikompilasi serta dll yang sangat bagus untuk menyematkan versi pemasang dan konten UI ke info perakitan exe, tanpa harus mengubah banyak hal di banyak tempat
rcbevans
21

Berikut adalah cara yang sangat sederhana untuk mendapatkan Versi Bundel Bootstrapper Anda agar sesuai dengan MyApp AssemblyVersion Anda menggunakan a BeforeBuild Targetdan 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
sumber
@AliKazmi Sudahkah Anda menentukan Anda var.ProductNamedan var.BuildVersionsuatu tempat di atas Anda <Bundle>?
Brock Hensley
2
Saya mencoba ini dan tidak bisa merekomendasikan ini cukup - kombinasikan dengan patcher perakitan untuk TeamCity dan Anda sudah mendapat formula kemenangan. Saya tidak menggunakan elemen Bundle tetapi elemen produk sebagai gantinya dan masih bekerja untuk saya.
IbrarMumtaz
VS hanya suka mengabaikan BeforeBuildtarget sehingga mungkin perlu untuk menentukan secara eksplisit AfterTargets="AfterResolveReferences"jika Anda sedang membangun di IDE
Dmitry
Saya menambahkan kode Bootstrapper.wixproj dalam file * .wixproj dan dalam file Product.wxs saya, saya mendefinisikan variabel buildversion sebagai:
RDV
4

Anda bisa meneruskan versi ke skrip MSBuild untuk proyek setup Anda sama seperti Anda bisa lulus untuk skrip build aplikasi.

Misalnya, jika sistem CI Anda mendefinisikan variabel AppVersiondan BuildNumber, dan meneruskannya ke skrip MSBuild Anda, wixproj Anda dapat membuat Versionproperti terkait yang meneruskannya ke Wix seperti ini:

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

Definisi pertama dari Versionmemberikan default ketika Anda membangun secara lokal. Apapun itu akhirnya menjadi Versionvariabel di Wix. Gunakan dalam file wsx seperti ini:

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

Saya ingin memasukkan versi dalam deskripsi sehingga mudah untuk mencari dari Window Explorer (sebagai kolom dalam tampilan Detail atau pada halaman Properties) terlepas dari nama file.

Melewati versi sebagai variabel memberi Anda lebih banyak kontrol daripada membacanya dari file. Ketika Anda membaca dari file, Anda mendapatkan semua 4 bagian dari versi program. Namun, ProductVersion hanya dirancang untuk menggunakan 3 bagian pertama.

Edward Brey
sumber
Terima kasih, ini menyelamatkan hari saya. BTW: Kode bagian atas dimasukkan ke proyek Anda (* .wxiproj). Harus mengelola Devops / VSTS CI-Build ini adalah jawaban terbaik. Karena saya sudah menyiapkan variabel versi final saya. Ternyata dalam kasus saya untuk: <Version Condition=" '$(BuildVersionOfAsm)' != '' ">$(BuildVersionOfAsm)</Version>sementara BuildVersionOfAsm adalah variabel dalam pipa-pipa devops.
Robetto
Saya ingin memilih Versi secara dinamis, metode ini akan mengharuskan saya untuk terus memperbarui versi di * .wixproj. Apakah ada cara untuk versi dll di bidang ini?
RDV
@RDV Tujuan dengan pendekatan ini tidak mengubah file apa pun dalam kontrol sumber, termasuk .wixproj. Nomor versi dinamis disediakan oleh sistem CI Anda (AppVersion dan BuildNumber dalam contoh ini). Biasanya, Anda menetapkan nomor versi utama dan minor sebagai variabel CI dan membiarkan sistem CI menghasilkan angka build secara dinamis.
Edward Brey
Luar biasa - hanya jenis solusi yang saya butuhkan, termasuk default untuk build lokal.
ColH