ฉันจะตั้งค่าเวอร์ชันตัวติดตั้ง WiX เป็นเวอร์ชันบิวด์ปัจจุบันได้อย่างไร


134

ฉันเขียนแอปพลิเคชันและตัวติดตั้ง WiX และวางไว้ภายใต้การควบคุมเวอร์ชันโดยใช้การโค่นล้ม เมื่อตัวติดตั้ง WiX สร้างฉันต้องการให้หมายเลขเวอร์ชันเป็นเวอร์ชันบิลด์ปัจจุบันของแอปพลิเคชัน ฉันจะทำสิ่งนี้ให้สำเร็จได้อย่างไร? ฉันใช้ c # เพื่อเขียนโค้ดแอปพลิเคชัน

หมายเหตุฉันใช้ ccnet เพื่อสร้างโครงการนี้

คำตอบ:


181

คุณสามารถใช้Product/@Version="!(bind.FileVersion.FileId)"(แทนที่FileIdด้วยIdไฟล์ที่คุณต้องการรับหมายเลขเวอร์ชัน) และ light.exe จะเติมค่าด้วยเวอร์ชันของไฟล์ที่อ้างอิงโดยไฟล์FileId.


4
สิ่งที่ฉันกำลังมองหา! แม้ว่าฉันจะต้องใช้ "! (bind.FileVersion.FileId)" (a "!" แทน "$") ไม่เช่นนั้นฉันได้รับข้อผิดพลาดคำสั่งพรีโปรเซสเซอร์
Nicholas Piasecki

8
ใช่ขอโทษฉันทำผิดทางจิตอย่างต่อเนื่อง $ เป็นตัวแปรตัวประมวลผลก่อนและ! เป็นตัวแปรสารยึดเกาะ
Rob Mensching

20
โปรดทราบว่า "Fileid" ควรเป็นค่าจากองค์ประกอบ <File Id = "Fileid" ... > และดูเหมือนว่าสามารถรวมอักขระจุด (.) ได้
James Hugard

6
เป็นไปได้ไหมที่จะทำสำหรับบันเดิล / bootstrapper ด้วย?
noelicus

6
ลิงก์ไปยังเอกสารที่เกี่ยวข้องหัวข้อ: Binder Variables
mcdon

39

ฉันทำสิ่งนี้ในหนึ่งในโครงการของฉันโดยเขียนส่วนขยายของตัวประมวลผลล่วงหน้าเพื่ออ่านเวอร์ชันไฟล์จากไฟล์ปฏิบัติการ ดังนั้นไฟล์ WiX จึงมีลักษณะดังนี้:

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

ฉันโพสต์รหัสสำหรับใน CodePlex: http://wixfileversionext.codeplex.com/


ส่วนขยายของคุณยังใช้งานได้หรือไม่ ฉันลองเพิ่มเป็นข้อมูลอ้างอิงและพบข้อผิดพลาด
Stefan Vasiljevic

ส่วนขยายนี้ใช้งานได้ดีกับ Wix 3.5 หลังจากอัปเดตเป็น Wix 3.9 มันจะพ่น NullPointerException เห็นได้ชัดว่ามีบางอย่างเกิดขึ้นระหว่างเวอร์ชันเหล่านี้
Gigo

2
@Gigo ฉันได้มันทำงานผ่านทาง<?define ProductName="!(bind.property.ProductName)" ?><?define CompanyName="!(bind.property.Manufacturer)" ?><?define ProductVersion=!(bind.FileVersion.FileId) ?> ไหนFileIdคุ้มค่าของIdแอตทริบิวต์ของหนึ่งขององค์ประกอบภายในFile Component
Jared

ลิงก์ CodePlex ไม่เปิดให้ฉัน มีวิธีอื่นนอกจากเขียนส่วนขยายก่อนโปรเซสเซอร์ของคุณเองหรือไม่?
RDV

30

ในกรณีที่มีคนกำลังมองหาตัวอย่าง XML จริงสิ่งนี้ใช้ได้กับ. ฉันกำจัดรหัสที่ไม่เกี่ยวข้องกับ [... ] ตัวยึด:

<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
นี่คือคำตอบที่ดีกว่ามาก ขอบคุณสำหรับตัวอย่างการทำงาน
ม้วน

มันดึงหมายเลขเวอร์ชันจริงมาจากไหน
foobar

@foobar เป็นเวลานานแล้วที่ฉันอยู่ที่นี่ แต่ถ้าคุณดูสตริง!(bind.fileVersion.MyDLL)มันใช้ส่วนที่ 3 ในการอ้างอิงถึง<File Id="MyDLL"...ส่วน
K0D4

นี้ทำงานได้ดีสำหรับฉัน. ธิสำหรับ executables รวบรวมเช่นเดียวกับ dll ซึ่งเป็นที่ดีสำหรับการตรึงรุ่นติดตั้งและเนื้อหา UI ไปยังข้อมูลประกอบ exe โดยไม่ต้องไปสู่สิ่งที่เปลี่ยนแปลงในหลายสถานที่
rcbevans

21

นี่คือวิธีที่ง่ายมากที่จะได้รับ Bootstrapper Bundle เวอร์ชันของคุณให้ตรง MyApp AssemblyVersion ของคุณโดยใช้และBeforeBuild TargetDefineConstants

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 คุณกำหนดของคุณvar.ProductNameและvar.BuildVersionอยู่เหนือของคุณ<Bundle>หรือไม่?
Brock Hensley

2
ฉันลองสิ่งนี้แล้วและไม่สามารถแนะนำสิ่งนี้ได้เพียงพอ - รวมเข้ากับแอสเซมบลีแพตช์สำหรับ TeamCity และคุณมีสูตรที่ชนะ ฉันไม่ได้ใช้องค์ประกอบ Bundle แต่เป็นองค์ประกอบผลิตภัณฑ์แทนและยังใช้งานได้สำหรับฉัน
IbrarMumtaz

VS ชอบที่จะเพิกเฉยต่อBeforeBuildเป้าหมายดังนั้นจึงจำเป็นต้องระบุอย่างชัดเจนAfterTargets="AfterResolveReferences"หากคุณกำลังสร้างใน IDE
Dmitry

ฉันเพิ่มรหัส Bootstrapper.wixproj ใน * .wixproj ของฉันและในไฟล์ Product.wxs ฉันกำหนดตัวแปร buildversion เป็น:
RDV

5

คุณสามารถส่งผ่านเวอร์ชันไปยังสคริปต์ MSBuild สำหรับโปรเจ็กต์การตั้งค่าของคุณได้เช่นเดียวกับที่คุณสามารถส่งผ่านสำหรับสคริปต์บิลด์ของแอปพลิเคชัน

ตัวอย่างเช่นหากระบบ CI ของคุณกำหนดตัวแปรAppVersionและBuildNumberและส่งต่อไปยังสคริปต์ MSBuild ของคุณ wixproj ของคุณสามารถสร้างVersionคุณสมบัติที่เกี่ยวข้องซึ่งส่งต่อไปยัง Wix ดังนี้:

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

คำจำกัดความแรกของVersionระบุค่าเริ่มต้นเมื่อคุณสร้างในเครื่อง สิ่งที่ลงท้ายด้วยกลายเป็นVersionตัวแปรใน Wix ใช้ในไฟล์ wsx ดังนี้:

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

ฉันต้องการรวมเวอร์ชันไว้ในคำอธิบายเพื่อให้ง่ายต่อการค้นหาจาก Window Explorer (เป็นคอลัมน์ในมุมมองรายละเอียดหรือในหน้าคุณสมบัติ) โดยไม่ขึ้นกับชื่อไฟล์

การส่งผ่านเวอร์ชันเป็นตัวแปรจะช่วยให้คุณควบคุมได้มากกว่าการอ่านจากไฟล์ เมื่อคุณอ่านจากไฟล์คุณจะได้รับทั้ง 4 ส่วนของเวอร์ชันแบบเป็นโปรแกรม อย่างไรก็ตามProductVersionได้รับการออกแบบให้ใช้ 3 ส่วนแรกเท่านั้น


ขอบคุณสิ่งนี้ช่วยชีวิตฉัน BTW: โค้ดด้านบนจะถูกตัดเข้าไปในโปรเจ็กต์ของคุณ (* .wxiproj) ต้องจัดการ Devops / VSTS CI-Build นี่คือคำตอบที่ดีที่สุด เนื่องจากฉันมีตัวแปรเวอร์ชันสุดท้ายของฉันพร้อมแล้ว ในกรณีของฉันเปลี่ยนเป็น: <Version Condition=" '$(BuildVersionOfAsm)' != '' ">$(BuildVersionOfAsm)</Version>ในขณะที่ BuildVersionOfAsm เป็นตัวแปรในไปป์ไลน์ devops
Robetto

ฉันต้องการเลือกเวอร์ชันแบบไดนามิกวิธีนี้จะทำให้ฉันต้องอัปเดตเวอร์ชันใน * .wixproj มีวิธีไปยังเวอร์ชันของ dll ในฟิลด์นี้หรือไม่?
RDV

@RDV เจตจำนงของแนวทางนี้คือไม่เปลี่ยนแปลงไฟล์ใด ๆ ในการควบคุมแหล่งที่มารวมถึง. หมายเลขเวอร์ชันไดนามิกจัดเตรียมโดยระบบ CI ของคุณ (AppVersion และ BuildNumber ในตัวอย่างนี้) โดยทั่วไปคุณตั้งค่าหมายเลขเวอร์ชันหลักและรองเป็นตัวแปร CI และปล่อยให้ระบบ CI สร้างหมายเลขรุ่นแบบไดนามิก
Edward Brey

ยอดเยี่ยม - เป็นวิธีแก้ปัญหาที่ฉันต้องการรวมถึงค่าเริ่มต้นสำหรับงานสร้างในพื้นที่
ColH

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.