利用WIX制作安装包(2)

这一篇文章将为大家介绍如何使用WIX自定义UI。上一篇文章我们讲过WIX为我们提供了五种安装界面。每种安装界面都是由不同的Dialog组成。在这里我们挑选一种比较常用的界面WixUI_FeatureTree Dialog Set 来为大家介绍一下。

WixUI_FeatureTree Dialog Set 中一共包含了如下几种Dialog。

First-time install dialog sequence:
- WixUI_WelcomeDlg
- WixUI_LicenseAgreementDlg
- WixUI_CustomizeDlg
- WixUI_VerifyReadyDlg
- WixUI_DiskCostDlg

Maintenance dialog sequence:
- WixUI_MaintenanceWelcomeDlg
- WixUI_MaintenanceTypeDlg
- WixUI_CustomizeDlg
- WixUI_VerifyReadyDlg

Patch dialog sequence:
- WixUI_WelcomeDlg
- WixUI_VerifyReadyDlg

通过其中的注释我们可以看到:当我们程序第一次安装的时候我们所看见的界面顺序应该是:

- WixUI_WelcomeDlg            欢迎界面
- WixUI_LicenseAgreementDlg   协议同意
- WixUI_CustomizeDlg          自定义功能选择
- WixUI_VerifyReadyDlg        确认安装界面
- WixUI_DiskCostDlg           磁盘消耗

在WIX上处界面中(除开WixUI_WelcomeDlg之外)每个界面上都有三个按钮:next backcancel 。其中nextback 把这所有的界面组成一个双向链表。如果我们需要完全自定义一个界面,我们只需要在界面定义完成之后,把它加入到这个双向链表中来。这样我们自定义的界面就可以显示来。具体操作如下。

  1. 创建Dialog。在项目中添加一个文件customDialog.wxs 并且添加代码如下:
<!--
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <Fragment>
    <UI>
      <Dialog Id="DatabaseInformationDlg" Width="370" Height="270" Title="[ProductName] [Setup]" NoMinimize="yes">
        <Control Id="ServerLabel" Type="Text" X="20" Y="62" Width="80" Height="25" NoPrefix="yes" Text="SQL Database:" />
        <Control Id="Server" Type="ComboBox" Height="16" Width="180" X="110" Y="60" Property="DATABASE_SERVER">
          <ComboBox Property="DATABASE_SERVER">
            <ListItem Text="[DATABASE_SERVER]" Value="[DATABASE_SERVER]" />
          </ComboBox>
        </Control>

        <Control Id="DatabaseType" Type="RadioButtonGroup" X="20" Y="100" Width="290" Height="40" Property="DATABASE_LOGON_TYPE">
          <RadioButtonGroup Property="DATABASE_LOGON_TYPE">
            <RadioButton Value="DatabaseIntegratedAuth" X="0" Y="0" Width="290" Height="16" Text="Trusted (Windows Authentication)" />
            <RadioButton Value="DatabaseAccount" X="0" Y="20" Width="290" Height="16" Text="Specify Username and Password (SQL Authentication)" />
          </RadioButtonGroup>
        </Control>

        <!-- Login -->
        <Control Type="Text" Id="UsernameLabel" Width="50" Height="15" X="40" Y="150" Text="&amp;Login:">
          <Condition Action="disable"><![CDATA[DATABASE_LOGON_TYPE <> "DatabaseAccount"]]></Condition>
          <Condition Action="enable"><![CDATA[DATABASE_LOGON_TYPE = "DatabaseAccount"]]></Condition>
        </Control>
        <Control Id="Username" Type="Edit" X="110" Y="145" Width="180" Height="18" Property="DATABASE_USERNAME" Text="{80}">
          <Condition Action="disable"><![CDATA[DATABASE_LOGON_TYPE <> "DatabaseAccount"]]></Condition>
          <Condition Action="enable"><![CDATA[DATABASE_LOGON_TYPE = "DatabaseAccount"]]></Condition>
        </Control>

        <!-- Password -->
        <Control Type="Text" Id="PasswordLabel" Width="50" Height="15" X="40" Y="173" Text="&amp;Password:">
          <Condition Action="disable"><![CDATA[DATABASE_LOGON_TYPE <> "DatabaseAccount"]]></Condition>
          <Condition Action="enable"><![CDATA[DATABASE_LOGON_TYPE = "DatabaseAccount"]]></Condition>
        </Control>
        <Control Id="Password" Type="Edit" X="110" Y="170" Width="180" Height="18" Property="DATABASE_PASSWORD" Text="{80}" Password="yes" >
          <Condition Action="disable"><![CDATA[DATABASE_LOGON_TYPE <> "DatabaseAccount"]]></Condition>
          <Condition Action="enable"><![CDATA[DATABASE_LOGON_TYPE = "DatabaseAccount"]]></Condition>
        </Control>

        <Control Id="Test" Type="PushButton" X="40" Y="197" Width="100" Height="17" Text="Test Connection">
          <Condition Action="disable"><![CDATA[DATABASE_SERVER = ""]]></Condition>
          <Condition Action="enable"><![CDATA[DATABASE_SERVER <> ""]]></Condition>
          <!--test connection-->
          <Publish Event="DoAction" Value="VerifySqlConnection" Order="1">1</Publish>
          <Publish Event="SpawnDialog" Value="InvalidLogonDlg" Order="2"><![CDATA[NOT CONNECT_SUCCEED]]></Publish>
        </Control>

        <!-- Back button -->
        <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="&amp;Back"></Control>

        <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="&amp;Next"></Control>

        <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="Cancel">
          <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
        </Control>

        <Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="WixUI_Bmp_Banner" />
        <Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="15" Transparent="yes" NoPrefix="yes">
          <Text>Please enter a SQL instance and database name.</Text>
        </Control>
        <Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
        <Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes">
          <Text>{\WixUI_Font_Title}SQL instance and database information.</Text>
        </Control>
        <Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
      </Dialog>

      <!-- INVALIDE SQL LOGIN -->
      <Dialog Id="InvalidLogonDlg" Width="260" Height="105" Title="Invalid Logon">
        <Control Id="Return" Type="PushButton" X="102" Y="77" Width="56" Height="17" Default="yes" Cancel="yes" Text="OK">
          <Publish Event="EndDialog" Value="Return">1</Publish>
        </Control>
        <Control Id="Text" Type="Text" X="48" Y="15" Width="194" Height="50" Text="[ODBC_ERROR]" />
        <Control Id="Icon" Type="Icon" X="15" Y="15" Width="24" Height="24" FixedSize="yes" IconSize="32" Text="WixUI_Ico_Exclam" />
      </Dialog>

      <!--设置默认值-->

      <Property Id="DATABASE_SERVER" Value="(local)"/>
      <Property Id="DATABASE_LOGON_TYPE" Value="DatabaseIntegratedAuth"/>
      <Property Id="DATABASE_USERNAME"/>
      <Property Id="DATABASE_PASSWORD"/>

    </UI>

  </Fragment>
</Wix>

在上述界面中我们自定义了一个数据库连接界面。用户在此界面可以选择登录方式:集成登录或者账号密码登录。并且有一个Test Connection的按钮。用户在配置完成之后可以点击按钮测试连接。这里的TestConnection就是用CustomAction完成的。

在上述的代码中大家可以看到有如下一些代码:

<Property Id="DATABASE_SERVER" Value="(local)"/>
<Property Id="DATABASE_LOGON_TYPE" Value="DatabaseIntegratedAuth"/>
<Property Id="DATABASE_USERNAME"/>
<Property Id="DATABASE_PASSWORD"/>

这些是用来保存用户输入的值的东西。 在WIX中我们可以用Property去定义一个属性,当我们把创建的属性赋值给Control的Value之后,它就跟控件的Value进行了“双向绑定“。我们可以读取Property的值去获取用户的输入,也可以设置Property的初始值去设置界面显示的默认值。

当界面创建完成之后,我们就需要去修改WixUI_FeatureTree Dialog Set 中默认的UI sequence从而让我们的自定义界面得到显示。我们在项目中创建文件UI.wxs 并添加如下代码:

<?xml version="1.0" encoding="UTF-8"?>
<!--
 <copyright file="WixUI_FeatureTree.wxs" company="Outercurve Foundation">
   Copyright (c) 2004, Outercurve Foundation.
   This software is released under Microsoft Reciprocal License (MS-RL).
   The license and further copyright text can be found in the file
   LICENSE.TXT at the root directory of the distribution.
 </copyright>
-->

<!--
First-time install dialog sequence:
- WixUI_WelcomeDlg
- WixUI_LicenseAgreementDlg
- WixUI_CustomizeDlg
- WixUI_VerifyReadyDlg
- WixUI_DiskCostDlg

Maintenance dialog sequence:
- WixUI_MaintenanceWelcomeDlg
- WixUI_MaintenanceTypeDlg
- WixUI_CustomizeDlg
- WixUI_VerifyReadyDlg

Patch dialog sequence:
- WixUI_WelcomeDlg
- WixUI_VerifyReadyDlg
-->

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" >
  <Fragment>
    <UI Id="WixUI_CustomerSequence">
      <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="FeatureTree" />

      <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="ExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999">1</Publish>
      <!--保留LicenseAgreementDlg-->
      <!--
      <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="LicenseAgreementDlg">NOT Installed</Publish>
      <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">Installed AND PATCH</Publish>

      <Publish Dialog="LicenseAgreementDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg">1</Publish>
      <Publish Dialog="LicenseAgreementDlg" Control="Next" Event="NewDialog" Value="CustomizeDlg">LicenseAccepted = "1"</Publish>

      <Publish Dialog="CustomizeDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" Order="1">Installed</Publish>
      <Publish Dialog="CustomizeDlg" Control="Back" Event="NewDialog" Value="LicenseAgreementDlg" Order="2">NOT Installed</Publish>
      <Publish Dialog="CustomizeDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
      -->

      <!--去除LicenseAgreementDlg 添加DatabaseDlg-->
      <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="DatabaseInformationDlg">NOT Installed</Publish>
      <Publish Dialog="WelcomeDlg" Control="Next" Event="DoAction" Value="EnumerateSqlServers" Order="1">NOT Installed</Publish>
      <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg" Order="2">Installed AND PATCH</Publish>

      <Publish Dialog="DatabaseInformationDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg">1</Publish>
      <Publish Dialog="DatabaseInformationDlg" Control="Next" Event="DoAction" Value="VerifySqlConnection"  Order="1">1</Publish>
      <Publish Dialog="DatabaseInformationDlg" Control="Next" Event="SpawnDialog" Value="InvalidLogonDlg" Order="2"><![CDATA[NOT CONNECT_SUCCEED]]></Publish>
      <Publish Dialog="DatabaseInformationDlg" Control="Next" Event="NewDialog" Value="CustomizeDlg" Order="2"><![CDATA[CONNECT_SUCCEED]]></Publish>

      <Publish Dialog="CustomizeDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" Order="1">Installed</Publish>
      <Publish Dialog="CustomizeDlg" Control="Back" Event="NewDialog" Value="DatabaseInformationDlg" Order="2">NOT Installed</Publish>
      <Publish Dialog="CustomizeDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>

      <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="CustomizeDlg" Order="1">NOT Installed OR WixUI_InstallMode = "Change"</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="3">Installed AND PATCH</Publish>

      <Publish Dialog="MaintenanceWelcomeDlg" Control="Next" Event="NewDialog" Value="MaintenanceTypeDlg">1</Publish>

      <Publish Dialog="MaintenanceTypeDlg" Control="ChangeButton" Event="NewDialog" Value="CustomizeDlg">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>
    </UI>

    <UIRef Id="WixUI_Common" />
  </Fragment>
</Wix>

上面的代码是我们修改了原本WIX中的WixUI_FeatureTree Dialog Set 的代码之后的。 在上面的代码中,我们把我们自定义的Dialog添加到了WelcomeDlgCustomizeDlg 之间。

 <Publish Dialog="DatabaseInformationDlg"
          Control="Back"
          Event="NewDialog"
          Value="WelcomeDlg">1</Publish>
<Publish  Dialog="DatabaseInformationDlg"
          Control="Next" Event="DoAction"
          Value="VerifySqlConnection"
          Order="1">1</Publish>
<Publish  Dialog="DatabaseInformationDlg"
          Control="Next"
          Value="InvalidLogonDlg"
          Order="2"><![CDATA[NOT CONNECT_SUCCEED]]></Publish>
<Publish  Dialog="DatabaseInformationDlg"
          Control="Next"
          Value="CustomizeDlg"
          Order="2"><![CDATA[CONNECT_SUCCEED]]></Publish>

在WIX中Publish 表示出发一个事件。Dialog 表示出发这个事件的控件所属于的Dialog,Control 表示触发这个事件的控件的ID,Event 表示所触发事件的类型,可选有:doActionnewDialog,spawnDialog.分别表示执行自定义方法,跳转到另一对话框和弹出模态对话框。

添加完成之后我们在编译运行就可以看到我们添加的自定义界面生效了。

下一篇讲介绍如何安装服务。

时间: 2024-08-08 11:32:03

利用WIX制作安装包(2)的相关文章

利用WIX制作安装包(1)

#installation 下载最新版本的WIX toolset 并安装DOWNLOAD Wix toolset V3.5之后的版本已经可以集成到visual studio,我们可以直接在vs中编写代码,并借助vs进行编译. #demo 首先打开 Visual Studio,然后选择创建WIX Setup Project. 创建完成之后的在项目中我们可以看到一个名为Product.wxs 的文件,其代码如下: <?xml version="1.0" encoding="

利用WIX制作安装包(3)

利用WIX安装服务非常简单.只需要短短几句话就可以.当我们创建好一个Windows服务之后.我们在项目中创建一个Service.wxs 文件来安装服务,并且编辑代码如下: <?xml version="1.0" encoding="UTF-8"?> <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> <Fragment> <Component Id

InstallShield 12 制作安装包

目  录 一.       InstallShield安装... 2 二.       InstallShield 破解... 2 三.       制作安装包... 2 (一) 打开project... 2 (二) project助手页面... 3 1.Application Information:程序信息... 4 2.Installation Architecture: 安装包结构... 4 3.Application Files:指定安装的文件默认目标路径... 5 4.Applica

为自己编写的windows应用程序制作安装包

1 写好了一个windows程序之后如何制作安装包 这个在vs中就可以直接发布了,可以制作msi的安装包和exe的安装包. 2 window应用程序安装包做了哪些事情 rpm安装包的话,只是把相应的文件拷贝到不同的目录.那么window安装包做了什么呢? msi里面有一个table,里面是一条条的指令,windows installer会解释并执行这些指令. 它还是会把安装包里面的文件拷贝到相应的目录.关键是它除了拷贝还做了哪些事情呢? 3 安装包除了把相应的文件放到不同的目录下,还做了哪些事情

使用Qt installer framework制作安装包(不知道是否适合Mac和Linux?)

一.介绍 使用Qt库开发的应用程序,一般有两种发布方式:(1)静态编译发布.这种方式使得程序在编译的时候会将Qt核心库全部编译到一个可执行文件中.其优势是简单单一,所有的依赖库都集中在一起,其缺点也很明显,可执行程序体量较大,光Qt核心库加起来就得十多兆.(2)制作安装包发布.这种方式的原理也简单,就是将可执行程序和其依赖的库文件一起打包压缩,制作成安装包发布.制作安装包的工具挺多,今天要说的是Qt官方的安装包制作框架Qt installer framework.这个框架由Qt官方出品,广泛应用

java程序打包jre以及制作安装包

分享一篇文章: java程序打包jre以及制作安装包 传智&黑马咨询郑老师 java程序打包jre以及制作安装包Java的桌面程序写好以后只能在eclipse下运行是不可以的,还需要将程序拷贝到其他电脑上运行才可以,所以需要制作成其他电脑可以运行的文件,当然在安装有jdk的电脑上只需要将程序导出为jar文件就可以运行了,但是除了开发java程序人员的电脑上会安装jdk,其他人的电脑上不会有这个环境,所以还需要将java可运行的环境一同打包到程序中去,这样,在用户不安装jdk的情况下也可以运行.制

installshield 制作安装包中执行其他程序LaunchAppAndWait的简介

最近在研究用instanllshield来制作安装包,并进行数据的创建,掌握到installshield中的LaunchAppAndWait 函数该函数是在运行的时候,运行其他程序,并能传递参数以及是否静默运行的效果. 例如: szScriptPath =SUPPORTDIR+"\\CREATEORACLEUSER.SQL";    LongPathToQuote(szScriptPath, TRUE);    szCmdLine = DBUSER + "/" +

python制作安装包(setup.py)

1.制作setup.py from distutils.core import setup setup(name='Myblog', version='1.0', description='My Blog Distribution Utilities', author='lujianxing', author_email='[email protected]', url='http://blog.lujianxing.com', py_modules=['foo'] ) py_modules 定

使用Qt installer framework制作安装包

一.介绍 使用Qt库开发的应用程序,一般有两种发布方式:(1)静态编译发布.这种方式使得程序在编译的时候会将Qt核心库全部编译到一个可执行文件中.其优势是简单单一,所有的依赖库都集中在一起,其缺点也很明显,可执行程序体量较大,光Qt核心库加起来就得十多兆.(2)制作安装包发布.这种方式的原理也简单,就是将可执行程序和其依赖的库文件一起打包压缩,制作成安装包发布.制作安装包的工具挺多,今天要说的是Qt官方的安装包制作框架Qt installer framework.这个框架由Qt官方出品,广泛应用