原文:【C#】WixToolset快速入门教程

介绍

给windows系统做软件,常见的打包工具大家可能都听说过,如:大名鼎鼎的Installshield、Inno setup等。在遇见Wix之前InstallShield时我的主力打包工具,操作简单方便项目使用到的dll文件会自动添加,多语言支持也很好,不过不好的是免费版的功能就那几样,越来越无法满足自己的要求。后来就尝试了下Inno setup,这个是用脚本进行配置并生成安装包的,简单尝试之后发现实在麻烦还不好配置,于是就放弃了。再后来就遇到了WixToolSet,这个瑞士军刀一样的打包工具还是免费开源的,已经与VS整合到了一起,安装界面还可以根据WPF一样的xaml标签自定义样式,很是不错,但是国内教程较少而且有些说的也不是很清楚,学起来比较有难度。

之前的老项目升级了,打包时发现wix的打包流程又忘记了,所以这篇教程给自己提个醒,也就给大家带来了一个简单的快速入门教程。

要求

一个winform做的程序:

  1. 可以自定义安装位置
  2. 升级包可覆盖安装,不允许降级安装
  3. 桌面和开始菜单有启动/卸载的快捷方式
  4. 支持中文

开始

1.wix安装方法简单提一下:

Wix官网下载wix的安装包,然后进行安装。完了之后打开vs2017(vs2015)的扩展和更新,搜索【wix】,搜索到之后下载安装,然后重启vs即可。

2.新建wix项目



如图,选择v3类型的项目,不然本文接下来的代码可能不能用。

3.项目结构

具体结构简介,参考Wix 安装部署(一)同MSBuild 自动生成打包文件 这里不再赘述。

我的项目结构:

其中Product.wxs文件中有个Product节点:

这个节点里有三个属性比较重要,涉及到了上面要求中的软件升级部分。分别是:Id,Version,UpgradeCode。Id和UpgradeCode是GUID码,Version与微软定义的那一套Version一致,一共四部分组成,前三部分有变化才认为你的程序版本有变化。

我的项目中:

1. LibFiles文件夹:是我的项目中用到的所有的dll、config等文件。

2. Icons文件夹:是用到的一些图标。

3. References中添加了四个引用:第一个是我的winform程序要的库项目(dll),第二个是我的winfrom程序,这两个项目引用添加进来的目的就是为了项目代码有任何改动时,wix生成的包一直都是最新的。第三个和第四个是前面的那个链接中讲过,自定义安装界面所需要的两个dll。

4. license.rtf:是你程序的license。

4.Product.wxs的配置代码

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Product Id="*" Name="软件名称v2.0.0" Language="2052" Codepage="936" Version="2.0.0.0" Manufacturer="公司名称" UpgradeCode="6b89c3a7-f25c-4399-9df8-d0b40105cd82">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<!--安装清单-->
<Feature Id="ProductFeature" Title="SetupWixTest" Level="1"> <!--Feature安装清单-->
<ComponentGroupRef Id="ProductComponents" />
<ComponentRef Id="LibsAndFiles"/>
<ComponentRef Id="ApplicationShortcut"/>
<ComponentRef Id="DesktopFolderShortcut"/>
</Feature>
<WixVariable Id="WixUILicenseRtf" Value="license.rtf"/>
<UI> <!--安装风格-->
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLDIR"/>
<UIRef Id="WixUI_InstallDir"/>
</UI>
</Product> <Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder" Name="PFiles">
<Directory Id="INSTALLDIR" Name="SmartTool"> <!--用户选择安装位置-->
</Directory>
</Directory> <Directory Id="ProgramMenuFolder"> <!--在windows开始菜单中显示-->
<Directory Id="ApplicationProgramsFolder" Name="软件名称"/>
</Directory>
<Directory Id="DesktopFolder" Name="Desktop"/>
</Directory>
</Fragment> <Fragment> <!--定义需要添加的文件的位置-->
<ComponentGroup Id="ProductComponents" Directory="INSTALLDIR">
<!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
<Component Id="ProductComponent">
<File Id="SmartTool.exe" Source="$(var.TianHuangPing.TargetPath)"/>
</Component>
<Component Id="LibOne">
<File Source="$(var.OrderFoodLib.TargetPath)"/>
</Component>
</ComponentGroup> <DirectoryRef Id="INSTALLDIR">
<Component Id="LibsAndFiles" Guid="ae8c83a1-7615-4439-bf90-4c39db24986f">
<File Id="AutoChangComboBox1.dll" Source="LibFiles/AutoChangComboBox.dll"/>
<File Id="AutoChangCombo1Box.dll" Source="LibFiles/DevExpress.BonusSkins.v16.2.dll"/>
<File Id="AutoCha1ngComboBox.dll" Source="LibFiles/DevExpress.Data.v16.2.dll"/>
<File Id="AutoChang1ComboBox.dll" Source="LibFiles/DevExpress.Printing.v16.2.Core.dll"/>
<File Id="AutoChangC1omboBox.dll" Source="LibFiles/DevExpress.Sparkline.v16.2.Core.dll"/>
<File Id="AutoC1hangComboBox.dll" Source="LibFiles/DevExpress.Utils.v16.2.dll"/>
<File Id="AutoChangComboww1Box.dll" Source="LibFiles/DevExpress.XtraBars.v16.2.dll"/>
<File Id="Aut1oChangComboBox.dll" Source="LibFiles/DevExpress.XtraEditors.v16.2.dll"/>
<File Id="AutoChangCo1mboBox.dll" Source="LibFiles/DevExpress.XtraGrid.v16.2.dll"/>
<File Id="AutoCh2angComboBox.dll" Source="LibFiles/DevExpress.XtraLayout.v16.2.dll"/>
<File Id="AutoChangC2omboBox.dll" Source="LibFiles/DevExpress.XtraPrinting.v16.2.dll"/>
<File Id="Au2toChangComboBox.dll" Source="LibFiles/Impinj.OctaneSdk.dll"/>
<File Id="AutoC2hangComboBox.dll" Source="LibFiles/LLRP.dll"/>
<File Id="AutoChangCombo2Box.dll" Source="LibFiles/LLRP.Impinj.dll"/>
<File Id="AutoChangCombo22Box.dll" Source="LibFiles/MR6100Api.dll"/>
<File Id="configFile" Source="LibFiles/TianHuangPing.exe.config"/>
<File Id="mannifestFile" Source="LibFiles/TianHuangPing.exe.manifest"/>
</Component>
</DirectoryRef> <DirectoryRef Id="ApplicationProgramsFolder">
<Component Id="ApplicationShortcut" Guid="5A254682-DD5F-453D-8333-144457282026">
<Shortcut Id="LunchApplicationShortcut" Name="软件名称" Description="启动软件名称" Target="[INSTALLDIR]TianHuangPing.exe" WorkingDirectory="INSTALLDIR">
<Icon Id="ico_install" SourceFile="Icons/logo.ico"/>
</Shortcut>
<Shortcut Id="UninstallApplicationShortcut" Name="卸载软件名称" Description="卸载软件名称" Target="[SystemFolder]msiexec.exe" WorkingDirectory="SystemFolder" Arguments="/x [ProductCode]">
<Icon Id="ico_uninstall" SourceFile="Icons/logo.ico"/>
</Shortcut>
<RemoveFolder Id="ApplicationProgramsFolder" On ="uninstall"/>
<RegistryValue Root="HKCU" Key="Software\Microsoft\SmartTool" Name="installed" Type="integer" Value="1" KeyPath="yes"/>
<util:InternetShortcut Id="OnlineDocumentationShortcut" Name="获取在线帮助" Target="http://www.hdu.edu.cn"/>
</Component>
</DirectoryRef> <DirectoryRef Id="DesktopFolder">
<Component Id="DesktopFolderShortcut" Guid="5A254676-DD1F-453D-8333-144457282027">
<Shortcut Id="DesktopShortcut" Directory="DesktopFolder" Name="软件名称" Target="[INSTALLDIR]TianHuangPing.exe" WorkingDirectory="INSTALLDIR" Icon="ico_install">
</Shortcut>
<RegistryValue Root="HKCU" Key="Software\Microsoft\SmartTool" Name="installed" Type="integer" Value="1" KeyPath="yes"/> </Component>
</DirectoryRef> </Fragment>
</Wix>

这个配置文件不是很难懂,大部分都可参考Wix 安装部署(一)同MSBuild 自动生成打包文件 进行理解。这个链接看完之后,我们要求里的第1,2,3点你应该都可以实现了。不过第2点中的升级包如何安装覆盖,我再详细解释一下:

Product标签中的id、upgradecode、version属性来控制版本的升级和降级。你的产品每次发布一个新版本,id都要分配一个新的GUID,version都要分配一个新的version,但是upgradecode要用同一个(不能改变)。即:同一个产品只用同一个upgradecode,不同的upgradecode认为是不同的产品,同一个产品的不同版本用不同的id和version。这里id属性我赋值为“*”,表示每次生成安装包wix会自动在这里分配一个新的GUID,不用我自己管。

所以,新版本安装包的制作流程是:

  1. upgradecode保持不变。
  2. version从1.0.0.0换成1.0.1.0.
  3. id设置为*,或者赋值一个新的GUID。

这样新的安装包安装时才不会提示与旧的冲突,也不会变成安装了两个完全一模一样的软件。

对于需求中的第4点,制作一个中文安装包:

此时如果你编译项目的话肯定时编译不过去的,因为Product.wxs中有中文的存在。如果需要安装界面时中文的,而且配置文件中的中文也要能够显示在界面上,就需要在这里配置成zh-CN。如要制作其他的语言包,请自行参考官方文档。

右键你的项目–属性:

5.展示


重要提示:在编写你的Product.wxs配置文件过程中一定要记得把bin文件下的所有dll、.config、.manifest等重要的文件配置进去,否则会有问题。

参考:

随笔分类 -Wix

WiX Toolset Manual Table of Contents

【C#】WixToolset快速入门教程的更多相关文章

  1. 专为设计师而写的GitHub快速入门教程

    专为设计师而写的GitHub快速入门教程 来源: 伯乐在线 作者:Kevin Li     原文出处: Kevin Li 在互联网行业工作的想必都多多少少听说过GitHub的大名,除了是最大的开源项目 ...

  2. EntityFramework6 快速入门教程

    EntityFramework6 快速入门教程 不得不说EF在国内实在是太小众,相关的技术文章真实屈指可数,而且很多文章都很旧了,里面使用的版本跟如今的EF6差别还是比较大.我刚开始弄这个的时候真是绕 ...

  3. Apple Watch开发快速入门教程

     Apple Watch开发快速入门教程  试读下载地址:http://pan.baidu.com/s/1eQ8JdR0 介绍:苹果为Watch提供全新的开发框架WatchKit.本教程是国内第一本A ...

  4. 指示灯组与3个复位按钮的介绍Arduino Yun快速入门教程

    指示灯组与3个复位按钮的介绍Arduino Yun快速入门教程 1.4.2  指示灯组 指示灯组的放大图如图1.5所示. 图1.5  指示灯组 各个指示灯对应的功能如下: q  RX:对应于0号端口, ...

  5. 游戏控制杆OUYA游戏开发快速入门教程

    游戏控制杆OUYA游戏开发快速入门教程 1.2.2  游戏控制杆 游戏控制杆各个角度的视图,如图1-4所示,它的硬件规格是本文选自OUYA游戏开发快速入门教程大学霸: 图1-4  游戏控制杆各个角度的 ...

  6. Query 快速入门教程

    Query 快速入门教程 http://www.365mini.com/page/jquery-quickstart.htm#what_is_jquery jquery常用方法及使用示例汇总 http ...

  7. Realm for Android快速入门教程

    介绍 如果你关注安卓开发的最新趋势,你可能已经听说过Realm.Realm是一个可以替代SQLite以及ORMlibraries的轻量级数据库. 相比SQLite,Realm更快并且具有很多现代数据库 ...

  8. CMake快速入门教程-实战

    http://www.ibm.com/developerworks/cn/linux/l-cn-cmake/ http://blog.csdn.net/dbzhang800/article/detai ...

  9. .NET Core 快速入门教程

    .NET Core 快速学习.入门系列教程.这个入门系列教程主要跟大家聊聊.NET Core的前世今生,以及Windows.Linux(CentOS.Ubuntu)基础开发环境的搭建.第一个.NET ...

随机推荐

  1. ajax 发送请求无法重定向问题

    原因: ajax请求默认就是不支持重定向的,因为它是局部刷新,不重新加载页面. 解决方案: 开发中需要多处使用重定向的情况下,大多都是在Spring mvc 的拦截器中,或过滤器中使用,此方法是在sp ...

  2. [NPM] Run npm scripts when files change with onchange

    In this lesson we will look at how we can setup our npm scripts to execute when the file system has ...

  3. show binlog events 命令查看某个binlog日志内容

    mysql> show binlog events [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count];   选项解析:   IN 'l ...

  4. 免费的 C/C++ 编译&解释 器列表

    摘自<C++编程网>,详细介绍请参考http://www.cpp-prog.com/2009/0520/118.html MicrosoftVisual C++ 2008 Express  ...

  5. 使用RpcLite构建SOA/Web服务

    使用RpcLite构建SOA/Web服务 SOA框架系列 1. 使用RpcLite构建SOA/Web服务 提到Web服务最先想到的就是WebService此外常用的还有WCF.ServiceStack ...

  6. Android获取Context(任意位置任意地方,全局上下文)

    一般获取context的方法 1.Activity.this的context (一般用法)返回当前activity的上下文,属于activity ,activity 摧毁他就摧毁 2.getAppli ...

  7. 设置aspx页面的地址栏中的Session ID的显示与隐藏

    设置aspx页面的地址栏中的Session ID的显示与隐藏修改web.config文件中的sessionState节点下的cookieless的值 1.cookieless的值是false的时候隐藏 ...

  8. OpenCL编译环境配置(VS+Nvidia)

    英伟达的显卡首先要下载安装CUDA开发包,可以参考这里的步骤:   VS2015编译环境下CUDA安装配置 安装好CUDA之后,OpenCL的配置就已经完成了80%了,剩下的工作就是把OpenCL的路 ...

  9. Android开发之 shape的使用

    android shape的使用 shape用于设定形状,能够在selector,layout等里面使用,有6个子标签,各属性例如以下: <?xml version="1.0" ...

  10. 3 Task中的一些枚举 创建时候的、continue时候的

    创建时常用的枚举: None.PreferFairness.LongRunning.AttacthedToParent.DenyChildAttach.HideScheduler AttacthedT ...