Wix 安装部署教程(十四) -- 多语言安装包之用户许可协议
在上一篇中,留下了许可协议的问题,目前已经解决。感谢网友武全的指点!
问题
一般我们是用WixVariable 来设定许可协议。如下所示:
<WixVariable Id="WixUILicenseRtf" Value="license.rtf" />
但在多语言中我们写成下面这样是不识别的。它会被直接当成文件路径,而报错,找不到文件。
<WixVariable Id="WixUILicenseRtf" Value="!(loc.LicenseRtf)" />
string:
<String Id="LicenseRtf">Languages\license.rtf</String>

自定义CustomLicenseDlg
这样我们需要自定义一个许可证书对话框。不过我们可以在源码的基础上稍作修改。在源码中找到LicenseAgreementDlg.wxs。
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<UI>
<Dialog Id="LicenseAgreementDlg" Width="370" Height="270" Title="!(loc.LicenseAgreementDlg_Title)">
<Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="!(loc.LicenseAgreementDlgBannerBitmap)" />
<Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
<Control Id="Description" Type="Text" X="25" Y="23" Width="340" Height="15" Transparent="yes" NoPrefix="yes" Text="!(loc.LicenseAgreementDlgDescription)" />
<Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes" Text="!(loc.LicenseAgreementDlgTitle)" />
<Control Id="LicenseAcceptedCheckBox" Type="CheckBox" X="20" Y="207" Width="330" Height="18" CheckBoxValue="1" Property="LicenseAccepted" Text="!(loc.LicenseAgreementDlgLicenseAcceptedCheckBox)" />
<Control Id="Print" Type="PushButton" X="112" Y="243" Width="56" Height="17" Text="!(loc.WixUIPrint)">
<Publish Event="DoAction" Value="WixUIPrintEula">1</Publish>
</Control>
<Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="!(loc.WixUIBack)" />
<Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.WixUINext)">
<Publish Event="SpawnWaitDialog" Value="WaitForCostingDlg">!(wix.WixUICostingPopupOptOut) OR CostingComplete = 1</Publish>
<Condition Action="disable"><![CDATA[LicenseAccepted <> "1"]]></Condition>
<Condition Action="enable">LicenseAccepted = "1"</Condition>
</Control>
<Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.WixUICancel)">
<Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
</Control>
<Control Id="LicenseText" Type="ScrollableText" X="20" Y="60" Width="330" Height="140" Sunken="yes" TabSkip="no">
<Text SourceFile="!(wix.WixUILicenseRtf=$(var.licenseRtf))" />
</Control>
</Dialog>
</UI>
</Fragment>
</Wix>
我们在工程中添加一个wxs文件,命名为CustomLicenseDlg.wxs。
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<UI>
<Dialog Id="CustomLicenseDlg" Width="370" Height="270" Title="!(loc.LicenseAgreementDlg_Title)">
<Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="!(loc.LicenseAgreementDlgBannerBitmap)" />
<Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
<Control Id="Description" Type="Text" X="25" Y="23" Width="340" Height="15" Transparent="yes" NoPrefix="yes" Text="!(loc.LicenseAgreementDlgDescription)" />
<Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes" Text="!(loc.LicenseAgreementDlgTitle)" />
<Control Id="LicenseAcceptedCheckBox" Type="CheckBox" X="20" Y="207" Width="330" Height="18" CheckBoxValue="1" Property="LicenseAccepted" Text="!(loc.LicenseAgreementDlgLicenseAcceptedCheckBox)" />
<Control Id="Print" Type="PushButton" X="112" Y="243" Width="56" Height="17" Text="!(loc.WixUIPrint)">
<Publish Event="DoAction" Value="WixUIPrintEula">1</Publish>
</Control>
<Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="!(loc.WixUIBack)" />
<Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.WixUINext)">
<Publish Event="SpawnWaitDialog" Value="WaitForCostingDlg">!(wix.WixUICostingPopupOptOut) OR CostingComplete = 1</Publish>
<Condition Action="disable"><![CDATA[LicenseAccepted <> "1"]]></Condition>
<Condition Action="enable">LicenseAccepted = "1"</Condition>
</Control>
<Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.WixUICancel)">
<Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
</Control>
<Control Id="TextArea" Type="ScrollableText" X="5" Y="50" Width="360"
Height="140" Sunken="yes" TabSkip="no">
<Text SourceFile="!(loc.LicenseRtf)" />
</Control> </Dialog>
</UI>
</Fragment>
</Wix>
注意修改Id和 Text部分。注意到源码中的Text是这样写的:
<Text SourceFile="!(wix.WixUILicenseRtf=$(var.licenseRtf))" />
var,wix,loc 这些前缀都表示不同的作用域。替换之后,我们就可以设置不同的LicenseRtf
zh-cn:
<String Id="LicenseRtf">Languages\license-cn.rtf</String>
zh-tw:
<String Id="LicenseRtf">Languages\license-tw.rtf</String>
设置UI顺序
另外,我们还需要设置UI顺序,也就是将默认的许可证书对话框换成自定义的。这些在Product元素中修改。
<!--自定义界面-->
<UI Id="WixUI_InstallDir">
<TextStyle Id="WixUI_Font_Normal" FaceName="Tahoma" Size="8" />
<TextStyle Id="WixUI_Font_Bigger" FaceName="Tahoma" Size="12" />
<TextStyle Id="WixUI_Font_Title" FaceName="Tahoma" Size="9" Bold="yes" /> <Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
<Property Id="WixUI_Mode" Value="InstallDir" /> <DialogRef Id="BrowseDlg" />
<DialogRef Id="CustomLicenseDlg" />
<DialogRef Id="DiskCostDlg" />
<DialogRef Id="ErrorDlg" />
<DialogRef Id="FatalError" />
<DialogRef Id="FilesInUse" />
<DialogRef Id="MsiRMFilesInUse" />
<DialogRef Id="PrepareDlg" />
<DialogRef Id="ProgressDlg" />
<DialogRef Id="ResumeDlg" />
<DialogRef Id="UserExit" /> <Publish Dialog="BrowseDlg" Control="OK" Event="DoAction" Value="WixUIValidatePath" Order="3">1</Publish>
<Publish Dialog="BrowseDlg" Control="OK" Event="SpawnDialog" Value="InvalidDirDlg" Order="4"><![CDATA[WIXUI_INSTALLDIR_VALID<>"1"]]></Publish> <Publish Dialog="ExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999">1</Publish> <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="CustomLicenseDlg">NOT Installed</Publish>
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">Installed AND PATCH</Publish> <Publish Dialog="CustomLicenseDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg">1</Publish>
<Publish Dialog="CustomLicenseDlg" Control="Next" Event="NewDialog" Value="InstallDirDlg">LicenseAccepted = "1"</Publish> <Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="CustomLicenseDlg">1</Publish>
<Publish Dialog="InstallDirDlg" Control="Next" Event="SetTargetPath" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
<Publish Dialog="InstallDirDlg" Control="Next" Event="DoAction" Value="WixUIValidatePath" Order="2">NOT WIXUI_DONTVALIDATEPATH</Publish>
<Publish Dialog="InstallDirDlg" Control="Next" Event="SpawnDialog" Value="InvalidDirDlg" Order="3"><![CDATA[NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>
<Publish Dialog="InstallDirDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg" Order="4">WIXUI_DONTVALIDATEPATH OR WIXUI_INSTALLDIR_VALID="1"</Publish>
<Publish Dialog="InstallDirDlg" Control="ChangeFolder" Property="_BrowseProperty" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
<Publish Dialog="InstallDirDlg" Control="ChangeFolder" Event="SpawnDialog" Value="BrowseDlg" Order="2">1</Publish> <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="InstallDirDlg" Order="1">NOT Installed</Publish>
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" Order="2">Installed AND NOT PATCH</Publish>
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" Order="2">Installed AND PATCH</Publish> <Publish Dialog="MaintenanceWelcomeDlg" Control="Next" Event="NewDialog" Value="MaintenanceTypeDlg">1</Publish> <Publish Dialog="MaintenanceTypeDlg" Control="RepairButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
<Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
<Publish Dialog="MaintenanceTypeDlg" Control="Back" Event="NewDialog" Value="MaintenanceWelcomeDlg">1</Publish> <Property Id="ARPNOMODIFY" Value="1" />
</UI>
<UIRef Id="WixUI_Common" />
这样就完成了。编译后,打开安装包发现英文安装包就是英文的许可协议,中文就是中文。
之前论坛还有这样的一种方式,是将内容直接写在wxl文件中。ScrollableText 的Text对应的内容如下。(抱歉,我也不懂那些乱七八糟的字符是什么,看着像是定义格式和字体的)
<Text>{\rtf1\ansi\ansicpg1252\deff0\deftab720
{\fonttbl{\f0\froman\fprq2 Times New Roman;}}
{\colortbl\red0\green0\blue0;}
\deflang1033\horzdoc{\*\fchars }{\*\lchars }
\pard\plain\f0\fs20
!(loc.License_Agreement)\par
}</Text>
然后设置不同的License_Agreement String:
<String Id="License_Agreement">
XXX用户许可协议 重要须知━请认真阅读:
</String>
但是内容完全没有格式,空格和换行好像都被处理了,很难看。即使使用<br>或者/r/n 也没有作用。

小结:Setup工程的多语言主要内容已经讲完。如果要做的更精细,你可能还需要根据语言长度来调整控件的长度。另外还需要和应用程序的多语言配合。这些都还要下工夫。Bundle的多语言和Setup的做法不同。它也需要wxl文件,但是不能同时编译支持多种语言。这个后面有机会再分享。另外繁体 的codepage 设置成936 才行,950老是报错。
Wix 安装部署教程(十四) -- 多语言安装包之用户许可协议的更多相关文章
- Wix 安装部署教程(十六) -- 自动生成多语言文件
因为持续集成需要,所有项目编译完之后生成一个多语言的安装包.之前生成mst文件都是手动操作,而且mst文件必须每次重新和新的安装包“关联”,否则中文的安装包去调用英文的资源的时候就会报类似于“类型转换 ...
- Wix 安装部署教程(十五) --CustomAction的七种用法
在WIX中,CustomAction用来在安装过程中执行自定义行为.比如注册.修改文件.触发其他可执行文件等.这一节主要是介绍一下CustomAction的7种用法. 在此之前要了解InstallEx ...
- Wix 安装部署教程(十) --来,用WPF做个漂亮的安装界面
在上一篇中曾留下两个问题,.Net捆绑安装不触发以及路径选择的问题现在都已经解决,这段时间花的最多的地方还是WPF调样式上面,奈何WPF功力不够,暂时还是没有达到自己想要的效果.另外ViewModel ...
- Wix 安装部署教程(四) 添加安装文件及快捷方式
通过之前三篇的介绍,大家对wix的xml部署方式也应该有一些认识,今天天气不错,再来一发.主要介绍桌面,开始菜单,卸载等功能的如何添加.希望园友们支持! 一.如何添加文件 Demo打包程序很简单,就一 ...
- Wix 安装部署教程(十二) -- 自动更新WXS文件
上一篇分享了一个QuickWIX,用来对比两个工程前后的差异,但是这样还是很繁琐,而且昨天发现有Bug,目录对比有问题.这次改变做法,完全让程序自动去更新WXS文件,然后再用CCNet去自动编译,这样 ...
- Wix 安装部署教程(十三) -- 多语言安装包
这几天摸索WIX的多语言安装包(这里是Wix的setup 工程,不是Bundle),终于走通了,感谢网友uni的指点.WIX的多语言安装包能够根据系统环境自动切换界面语言,你也可以通过命令指定语言.下 ...
- WIX 安装部署教程(六) 为你收集的七个知识点
前段时间整理5篇WIX(Windows Installer XML)的安装教程,但还不够完善,这里继续整理了七个知识点分享给大家.WIX最新版本3.8,点击下载 WIX安装部署(一)同MSBuild自 ...
- Wix 安装部署教程 -CustomAction的七种用法
在WIX中,CustomAction用来在安装过程中执行自定义行为.比如注册.修改文件.触发其他可执行文件等.这一节主要是介绍一下CustomAction的7种用法. 在此之前要了解InstallEx ...
- Wix 安装部署教程(九) --用WPF做安装界面
经常安装PC端的应用,特别是重装系统之后,大致分为两类.一类像QQ,搜狗输入法这样的.分三步走的:第一个页面可以自定义安装路径和软件许可.第二个页面显示安装进度条,第三个页面推荐其他应用.先不管人家怎 ...
随机推荐
- [linux]windows无法访问samba的安全性问题(关闭selinux)
背景 在某一天重启了虚拟机的 linux 之后,我的 windows 在连接上 samba 之后,点击某些文件夹的时候,会出现没有权限打开的情况.这问题折腾了我一度重新配置了好几次 samba 的配置 ...
- page、pageContext、servletContext的区别
ServletContext是容器上下文,指当前的一个web应用的上下文 JSP网页本身,page对象是当前页面转换后的Servlet类的实例.从转换后的Servlet类的代码中,可以看到这种关系:O ...
- 大前端学习笔记整理【七】HTTP协议以及http与https的区别
前言 还是老样子,新博客开始前总是想先啰嗦几句...HTTP协议其实在当初学习java时老师就有提过...但是...反正就那么过去了... 这段时间公司的项目正好要求做https的转换和迁移,然后自己 ...
- iOSview整体上移下移(点击键盘)
首先创建一个textFiled 并实现起代理方法 - (void)textFieldDidBeginEditing:(UITextField *)textField { //设置动画的名字 [UIVi ...
- android 模拟器上网问题
android 模拟器上网问题 1.配置Adroid环境变量(Win7为例) ,启动模拟器 第一步:桌面右键——>我的电脑——>高级系统设置 第二步:高级——>环境变量——&g ...
- hdu 1142(DFS+dijkstra)
#include<iostream> #include<cstdio> #include<cmath> #include<map> #include&l ...
- 自动挂载文件/etc/fstab功能详解
今天看了这篇文章,对于自动挂载中的一些小细节和参数有了更深的理解,所以这次把它摘下来,留做查询 一./etc/fstab文件的作用 1.我们把磁盘手动挂载之后如果不把它写入/etc/fstab这个文件 ...
- 【微信要跪】 iOS 应用如何完全支持 IPv6-ONLY 网络?
var appInsights=window.appInsights||function(config){ function r(config){t[config]=function(){var i= ...
- 数据快照 (Database Snapshot)
数据库快照是指数据库某一指定时刻的情况,数据库快照提供了源数据库在创建快照时刻的只读,静态视图 . 数据库快照一旦创建就不会改变. 数据库快照在被数据库所有者显示删除前始终存在. 数据库快照用途: 快 ...
- 图片浏览(CATransition)转场动画
Main.storyboard ViewController.m // // ViewController.m // 8A04.图片浏览(转场动画) // // Created by huan ...