当前位置: 首页 > news >正文

使用wix制作安装包

 公司产品的安装包原先是用installshield开发,但是我们采用的installshiled版本是installshiled 2008,无法很好兼容windows 10.公司又不想花钱对其升级。讨论下来有必要使用免费工具重新构建开发包。原来产品安装包是msi格式,比较下,wix是最好的选择。

最终的安装包将会包含5种语言包括界面和EULA.主要功能包括通过custom action检查产品序列号,升级(需要将原先程序退出),自动安装.net 4.0 framework(主要考虑在产品依然需要运行在windows xp和windows 7上)

我们使用wix3.11集成到visual studio 2017中。 wix安装包可以从SourceForge Wix网站下载。

安装包项目结构分为6个目录和一个主文件

 

  • CustomActions:每个custom action的定义在一个wix fragment中,一个wsx文件包含一个fragment
  • Fragments:包含由heat.exe自动生成的fragment和手动生成的修改注册表的fragment
  • Includes:定义变量的wix文件,每个wsx文件都应该include这个wix文件
  • Lang:字符串国际化
  • Packages:保存生成的msi文件
  • Resources:msi需要的资源文件,如icon,bmp
  • Product.wsx:安装包主文件

 

wix文件

主要定义安装包脚本需要用到变量,使用这些变量的wsx文件应该include 这个头文件

<?include "..\includes\ScanAppVariables.wxi"?>

当然可以在项目属性中定义一个变量 properties->Build->“Define preprocessor variables” .但如果多个开发者同时添加一些变量可能导致修改项目文件时产生冲突

ScanAppVariables.wsx

<?xml version="1.0" encoding="utf-8"?>
<Include>
	<!-- TODO: Put your code here. -->
  <?define MajorVersion = "1"?>
  <?define MinorVersion = "1"?>
  <?define PatchVersion = "1"?>
  <?define VersionNumber = "$(var.MajorVersion).$(var.MinorVersion).$(var.PatchVersion)"?>
</Include>

 安装包脚本文件 Product.wsx

基本上分为5个部分:update,condition和action,UI sequence,directory structure及需要安装的feature.

<?xml version="1.0" encoding="UTF-8"?>
<!-- Add xmlns:util namespace definition to be able to use stuff from WixUtilExtension dll-->
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
  <!-- This is how we include wxi files -->
  <?include "..\Includes\ScanAppVariables.wxi" ?>
  <!-- 
  Id="*" is to enable upgrading. * means that the product ID will be autogenerated on each build. 
  Name is made of localized product name and version number.
  -->
  <Product Id="*" Name="!(loc.ProductName) $(var.VersionNumber)" Language="!(loc.LANG)" Version="$(var.VersionNumber)" Manufacturer="!(loc.ManufacturerName)" UpgradeCode="$(var.UpgradeCode)">
    <!-- Define the minimum supported installer version (3.0) and that the install should be done for the whole machine not just the current user -->
    <Package InstallerVersion="300" Compressed="yes" InstallScope="perMachine"/>
    <Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />    
    <!-- Upgrade settings. This will be explained in more detail in a future post -->
    <Upgrade Id="$(var.UpgradeCode)">
      <UpgradeVersion OnlyDetect="yes" Minimum="$(var.VersionNumber)" IncludeMinimum="no" Property="NEWER_VERSION_FOUND" />
      <UpgradeVersion Minimum="0.0.0.0" IncludeMinimum="yes" Maximum="$(var.VersionNumber)" IncludeMaximum="no" Property="OLDER_VERSION_FOUND" />
    </Upgrade>    
    <!-- Reference the global NETFRAMEWORK35 property to check if it exists -->
    <PropertyRef Id="NETFRAMEWORK35"/>    
    <!-- 
    Startup conditions that checks if .Net Framework 3.5 is installed or if 
    we're running the OS higher than Windows XP SP2.
    If not the installation is aborted.
    By doing the (Installed OR ...) property means that this condition will only 
    be evaluated if the app is being installed and not on uninstall or changing
    -->
    <Condition Message="!(loc.DotNetFrameworkNeeded)">
      <![CDATA[Installed OR NETFRAMEWORK35]]>
    </Condition>
    <Condition Message="!(loc.AppNotSupported)">
      <![CDATA[Installed OR ((VersionNT >= 501 AND ServicePackLevel >= 2) OR (VersionNT >= 502))]]>
    </Condition>
    <!-- 
    This custom action in the InstallExecuteSequence is needed to 
    stop silent install (passing /qb to msiexec) from going around it. 
    -->
    <CustomAction Id="NewerVersionFound" Error="!(loc.ScanAppNewerVersionInstalled)" />
    <InstallExecuteSequence>
      <!-- Check for newer versions with FindRelatedProducts and execute the custom action after it -->
      <Custom Action="NewerVersionFound" After="FindRelatedProducts">
        <![CDATA[NEWER_VERSION_FOUND]]>
      </Custom>
      <!-- Remove the previous versions of the product -->
      <RemoveExistingProducts After="InstallInitialize"/>
      <!-- WixCloseApplications is a built in custom action that uses util:CloseApplication below -->
      <Custom Action="WixCloseApplications" Before="InstallInitialize" />
    </InstallExecuteSequence>
    <!-- This will ask the user to close the SuperForm app if it's running while upgrading -->
    <util:CloseApplication Id="CloseSuperForm" CloseMessage="no" Description="!(loc.MustCloseSuperForm)" 
                           ElevatedCloseMessage="no" RebootPrompt="no" Target="$(var.ExeProcessName)" />
    <!-- Use the built in WixUI_InstallDir GUI -->
    <UIRef Id="WixUI_InstallDir" />
    <UI>
      <!-- These dialog references are needed for CloseApplication above to work correctly -->
      <DialogRef Id="FilesInUse" />
      <DialogRef Id="MsiRMFilesInUse" />      
      <!-- Here we'll add the GUI logic for installation and updating in a future post-->      
    </UI>
    <!-- Set the icon to show next to the program name in Add/Remove programs -->
    <Icon Id="ScanAppIcon.ico" SourceFile="..\resources\device.ico" />
    <Property Id="ARPPRODUCTICON" Value="ScanAppIcon.ico" />
    <!-- Installer UI custom pictures. File names are made up. Add path to your pics. –>
    <!--
    <WixVariable Id="WixUIDialogBmp" Value="MyAppLogo.jpg" />
    <WixVariable Id="WixUIBannerBmp" Value="installBanner.jpg" />
    -->
    <!-- the default directory structure -->
    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder">
        <Directory Id="INSTALLLOCATION" Name="!(loc.ProductName)" />
      </Directory>
    </Directory>
    <!-- 
    Set the default install location to the value of 
    INSTALLLOCATION (usually c:\Program Files\YourProductName) 
    -->
    <Property Id="WIXUI_INSTALLDIR" Value="INSTALLLOCATION" />
    <!-- Set the components defined in our fragment files that will be used for our feature  -->
    <Feature Id="ScanAppFeature" Title="!(loc.ProductName)" Level="1">
      <ComponentGroupRef Id="ScanAppFiles" />
      <ComponentRef Id="cmpVersionInRegistry" />
      <ComponentRef Id="cmpIsThisUpdateInRegistry" />

    </Feature>
  </Product>
</Wix>

通过 heat.exe 生成文件或文件夹Fragment

因为项目要安装的文件比较多,手工输入到wsx比较麻烦,可以通过heat.exe自动生成componentgourp,然后加入到feature中

"$(WIX)bin\heat.exe" dir "..\Artifact\Main" -cg ScanAppFiles -gg -scom -sreg -sfrag -srd -dr INSTALLLOCATION -var var.FilesDir -out "$(ProjectDir)Fragments\FilesFragment.wxs"

 

  1. dir "..\Artifact\Main":需要安装的文件所在的目录
  2. –cg ScanAppFiles : 生成的component group的名字
  3. -dr INSTALLLOCATION: 生成Fragment对应的directory
  4. -var var.FilesDir: 替换生成的Fragment文件中$(SourceDir)字段
  5. -out "$(ProjectDir)Fragments\FilesFragment.wxs":输出文件路径

FilesFragment.wxs

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Fragment>
        <ComponentGroup Id="ScanAppFiles">
            <ComponentRef Id="cmp5BB40DB822CAA7C5295227894A07502E" />
            <ComponentRef Id="cmpCFD331F5E0E471FC42A1334A1098E144" />
            <ComponentRef Id="cmp4614DD03D8974B7C1FC39E7B82F19574" />
            <ComponentRef Id="cmpDF166522884E2454382277128BD866EC" />
        </ComponentGroup>
    </Fragment>
    <Fragment>
        <DirectoryRef Id="INSTALLLOCATION">
            <Component Id="cmp5BB40DB822CAA7C5295227894A07502E" Guid="{117E3352-2F0C-4E19-AD96-03D354751B8D}">
                <File Id="filDCA561ABF8964292B6BC0D0726E8EFAD" KeyPath="yes" Source="$(var.FilesDir)\ScanApp.exe" />
            </Component>
            <Component Id="cmpCFD331F5E0E471FC42A1334A1098E144" Guid="{369A2347-97DD-45CA-A4D1-62BB706EA329}">
                <File Id="filA9BE65B2AB60F3CE41105364EDE33D27" KeyPath="yes" Source="$(var.FilesDir)\ScanApp.pdb" />
            </Component>
            <Component Id="cmp4614DD03D8974B7C1FC39E7B82F19574" Guid="{3443EBE2-168F-4380-BC41-26D71A0DB1C7}">
                <File Id="fil5102E75B91F3DAFA6F70DA57F4C126ED" KeyPath="yes" Source="$(var.FilesDir)\ScanApp.vshost.exe" />
            </Component>
            <Component Id="cmpDF166522884E2454382277128BD866EC" Guid="{0C0F3D18-56EB-41FE-B0BD-FD2C131572DB}">
                <File Id="filF7CA5083B4997E1DEC435554423E675C" KeyPath="yes" Source="$(var.Files)\ScanApp.vshost.exe.manifest" />
            </Component>
        </DirectoryRef>
    </Fragment>
</Wix>

 

转载于:https://www.cnblogs.com/myhw/p/8311537.html

相关文章:

  • 使用Windows8开发Metro风格应用七
  • 黑马程序猿——15,String,StringBuffer,基本数据类型包装对象
  • linux libpcap的性能问题,请大家注意绕行。
  • LVS与KEEPALIVED实现高性能高可用负载均衡服务器
  • Vue(二)header组件开发
  • Yii性能调整
  • predict_proba 的使用
  • shell环境变量以及set,env,export的区别
  • 【PHP】富文本HTML过滤器:HTMLPurifier使用教程(防止XSS)
  • 让 webpack 加载 Source Map
  • 常见Oracle HINT的用法
  • vSphere虚拟化之外部存储部署(上)
  • C#枚举-避免不合理赋值
  • python3基础2--变量-字符编码-缩进-注释-用户输入-模块初识
  • 【强烈推荐】Kindle3下使用的提供加密功能的记事本,可以输入中文 -- KindleNote...
  • IE9 : DOM Exception: INVALID_CHARACTER_ERR (5)
  • 【391天】每日项目总结系列128(2018.03.03)
  • 【Linux系统编程】快速查找errno错误码信息
  • el-input获取焦点 input输入框为空时高亮 el-input值非法时
  • FineReport中如何实现自动滚屏效果
  • github指令
  • HTTP那些事
  • js写一个简单的选项卡
  • Just for fun——迅速写完快速排序
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • Markdown 语法简单说明
  • maven工程打包jar以及java jar命令的classpath使用
  • python 装饰器(一)
  • Spring技术内幕笔记(2):Spring MVC 与 Web
  • Swoft 源码剖析 - 代码自动更新机制
  • VUE es6技巧写法(持续更新中~~~)
  • Webpack入门之遇到的那些坑,系列示例Demo
  • 基于OpenResty的Lua Web框架lor0.0.2预览版发布
  • 聊聊sentinel的DegradeSlot
  • 普通函数和构造函数的区别
  • 使用Envoy 作Sidecar Proxy的微服务模式-4.Prometheus的指标收集
  • 世界上最简单的无等待算法(getAndIncrement)
  • ionic异常记录
  • 说说我为什么看好Spring Cloud Alibaba
  • (1)虚拟机的安装与使用,linux系统安装
  • (C语言)fgets与fputs函数详解
  • (js)循环条件满足时终止循环
  • (Matalb时序预测)PSO-BP粒子群算法优化BP神经网络的多维时序回归预测
  • (附源码)基于ssm的模具配件账单管理系统 毕业设计 081848
  • (免费领源码)python+django+mysql线上兼职平台系统83320-计算机毕业设计项目选题推荐
  • (十五)devops持续集成开发——jenkins流水线构建策略配置及触发器的使用
  • (一) storm的集群安装与配置
  • .equal()和==的区别 怎样判断字符串为空问题: Illegal invoke-super to void nio.file.AccessDeniedException
  • .NET C#版本和.NET版本以及VS版本的对应关系
  • .Net Remoting常用部署结构
  • .NET/C# 反射的的性能数据,以及高性能开发建议(反射获取 Attribute 和反射调用方法)
  • .net6Api后台+uniapp导出Excel
  • .NET上SQLite的连接
  • .NET学习教程二——.net基础定义+VS常用设置
  • .net与java建立WebService再互相调用