Làm cách nào tôi có thể đặt phiên bản trình cài đặt WiX thành phiên bản xây dựng hiện tại?


134

Tôi đã viết một ứng dụng và trình cài đặt WiX của nó và đặt nó dưới sự kiểm soát phiên bản bằng cách sử dụng subversion. Khi trình cài đặt WiX xây dựng, tôi muốn số phiên bản của nó là phiên bản xây dựng hiện tại của ứng dụng. Làm thế nào để tôi thực hiện điều này? Tôi đã sử dụng c # để mã ứng dụng.

NB Tôi đang sử dụng ccnet để xây dựng dự án này

Câu trả lời:


181

Bạn có thể sử dụng Product/@Version="!(bind.FileVersion.FileId)"(thay thế FileIdbằng Idtệp mà bạn muốn lấy số phiên bản) và light.exe sẽ điền giá trị bằng phiên bản của tệp được tham chiếu bởi FileId.


4
Chỉ cần những gì tôi đang tìm kiếm! Mặc dù tôi đã phải sử dụng "! (Bind.FileVersion.FileId)" (a "!" Thay vì "$"), nếu không tôi đã gặp lỗi chỉ thị tiền xử lý.
Nicholas Piasecki 17/03/2016

8
Vâng, xin lỗi, tôi mắc lỗi tinh thần liên tục. $ là biến tiền xử lý và! là biến chất kết dính.
Rob Mensking

20
Lưu ý rằng "Fileid" phải là giá trị từ phần tử <File Id = "Fileid" ...> và rõ ràng có thể bao gồm ký tự dấu chấm (.).
James Hugard

6
Có thể làm điều này cho một gói / bootstrapper không?
noelicus

6
Liên kết đến tài liệu liên quan, phần: Biến Binder
mcdon

39

Tôi đã làm điều này trong một trong các dự án của mình bằng cách viết một phần mở rộng tiền xử lý để đọc phiên bản tệp từ tệp thực thi của tôi. Vì vậy, tệp WiX trông giống như:

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

Tôi đã đăng mã cho trên CodePlex: http://wixfileversionext.codeplex.com/


Phần mở rộng của bạn vẫn hoạt động? Tôi đã thử thêm nó làm tài liệu tham khảo và tôi đã gặp lỗi.
Stefan Vasiljevic

Tiện ích mở rộng này hoạt động rất tốt với Wix 3.5, sau khi cập nhật lên Wix 3.9, nó ném ra một NullPulumException. Rõ ràng là một cái gì đó đã phá vỡ giữa các phiên bản.
Gigo

2
@Gigo Tôi đã làm cho nó hoạt động thông qua <?define ProductName="!(bind.property.ProductName)" ?><?define CompanyName="!(bind.property.Manufacturer)" ?><?define ProductVersion=!(bind.FileVersion.FileId) ?> Đâu FileIdlà giá trị Idthuộc tính của một trong các Filethành phần của bạn bên trong a Component.
Jared

Liên kết CodePlex không mở cho tôi. Có cách nào khác ngoài việc viết phần mở rộng tiền xử lý của riêng bạn không?
RDV

28

Trong trường hợp ai đó đang tìm kiếm một ví dụ XML thực tế, thì điều này hoạt động với các cụm .NET (và bạn không phải thực hiện các thuộc tính hội hoặc KeyPath). Tôi đã loại bỏ mã không liên quan với [...] chủ sở hữu địa điểm:

<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
Đây là một câu trả lời tốt hơn nhiều. Cảm ơn bạn cho ví dụ làm việc.
cuộn

nó lấy số phiên bản thực ở đâu?
foobar

@foobar Đã được một thời gian kể từ khi tôi ở đây, nhưng nếu bạn nhìn vào chuỗi, !(bind.fileVersion.MyDLL)nó sử dụng phần thứ 3 để tham khảo <File Id="MyDLL"...phần
K0D4

Điều này làm việc tốt cho tôi. Hoạt động cho các tệp thực thi được biên dịch cũng như dll, rất phù hợp để ghim phiên bản trình cài đặt và nội dung UI vào thông tin lắp ráp exe, mà không phải thay đổi mọi thứ ở nhiều nơi
RCbevans

21

Đây là một cách rất đơn giản để có được Phiên bản Gói Bootstrapper phù hợp với MyApp hộiVersion của bạn bằng cách sử dụng BeforeBuild TargetDefineConstants.

Gói.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 Bạn đã xác định var.ProductNamevar.BuildVersionở đâu đó trên của bạn <Bundle>?
Brock Hensley

2
Tôi đã thử điều này và không thể đề xuất điều này đủ - kết hợp nó với bộ vá lắp ráp cho TeamCity và bạn đã có một công thức chiến thắng. Tôi đã không sử dụng phần tử Bundle mà thay vào đó là một phần tử sản phẩm và vẫn hoạt động cho tôi.
IbrarMumtaz

VS chỉ thích bỏ qua BeforeBuildmục tiêu nên có thể cần chỉ định rõ ràng AfterTargets="AfterResolveReferences"nếu bạn đang xây dựng trong IDE
Dmitry

Tôi đã thêm mã Bootstrapper.wixproj trong tệp * .wixproj và trong tệp Product.wxs, tôi đã xác định biến xây dựng là:
RDV

4

Bạn có thể chuyển phiên bản cho tập lệnh MSBuild cho dự án thiết lập của mình giống như bạn có thể chuyển cho tập lệnh xây dựng của ứng dụng.

Ví dụ: nếu hệ thống CI của bạn xác định các biến AppVersionBuildNumberchuyển chúng vào các tập lệnh MSBuild của bạn, wixproj của bạn có thể tạo một thuộc tính tương ứng Versionmà nó chuyển tiếp đến Wix như thế này:

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

Định nghĩa đầu tiên Versioncung cấp mặc định khi bạn xây dựng cục bộ. Bất cứ điều gì nó kết thúc với trở thành một Versionbiến trong Wix. Sử dụng nó trong một tập tin wsx như thế này:

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

Tôi muốn đưa phiên bản vào phần mô tả để dễ dàng tra cứu từ Window Explorer (dưới dạng cột trong dạng xem chi tiết hoặc trên trang Thuộc tính) độc lập với tên tệp.

Truyền phiên bản dưới dạng một biến cho phép bạn kiểm soát nhiều hơn là đọc nó từ một tệp. Khi bạn đọc từ một tập tin, bạn nhận được tất cả 4 phần của phiên bản lập trình. Tuy nhiên, ProductVersion chỉ được thiết kế để sử dụng 3 phần đầu tiên.


Cảm ơn, điều này đã cứu ngày của tôi. BTW: Đoạn mã trên được cắt vào dự án yur (* .wxiproj). Phải quản lý Devops / VSTS CI-Build đây là câu trả lời tốt nhất. Vì tôi đã có sẵn phiên bản cuối cùng của mình. Trong trường hợp của tôi, nó biến thành: <Version Condition=" '$(BuildVersionOfAsm)' != '' ">$(BuildVersionOfAsm)</Version>trong khi BuildVersionOfAsm là một biến trong các đường ống devops.
Robetto

Tôi muốn chọn Phiên bản động, phương pháp này sẽ yêu cầu tôi tiếp tục cập nhật phiên bản trong * .wixproj. Có cách nào để phiên bản của dll trong lĩnh vực này không?
RDV

@RDV Ý định với phương pháp này không thay đổi bất kỳ tệp nào trong kiểm soát nguồn, bao gồm cả .wixproj. Số phiên bản động được cung cấp bởi hệ thống CI của bạn (AppVersion và BuildNumber trong ví dụ này). Thông thường, bạn đặt số phiên bản chính và số phụ là biến CI và để hệ thống CI tự động tạo số bản dựng.
Edward Brey

Tuyệt vời - chỉ là loại giải pháp tôi cần, bao gồm mặc định cho các bản dựng cục bộ.
ColH

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.