打包软件InstallShield提示和技巧:在运行时访问MSI数据库

InstallShield是构建Windows安装程序和MSIX包并直接在Microsoft Visual Studio中创建安装的最快速最简单的方法。借助InstallShield,您可以快速适应行业的变化,更快地进入市场并提供引人入胜的客户体验。

InstallShield最新试用版


访问数据库表

在VBScript中,Session对象提供了Database属性,该属性表示正在运行的MSI数据库。 (在InstallScript和C中,API函数MsiGetActiveDatabase返回相同的信息。)在自定义操作中,您可以对正在运行的数据库执行SQL查询。

执行SQL查询

下面是在运行时访问MSI数据库的步骤。

  • 使用SQL SELECT语句打开正在运行的数据库的视图。
  • 执行视图。
  • 获取视图返回的记录,并从所需字段中提取数据。
  • 关闭视图。

步骤1涉及创建SQL SELECT语句。SELECT语句的一般形式如下。

SELECT Fields FROM Tables

例如,要从FeatureComponents表中选择所有字段,查询将如下显示,并使用星 (*)表示所有字段。

SELECT * FROM `FeatureComponents`

为避免与SQL关键字冲突,建议您将字段名和表名放在反引 (`)中。

执行相同查询的另一种方法是显式标识所需的字段名称:

SELECT `Feature_`,`Component_` FROM `FeatureComponents`

您还可以使用WHERE子句来缩小SELECT语句的范围,然后在字段值和常量字符串之间进行比较,或者在两个字段值之间进行比较。 例如:

SELECT * FROM `Control` WHERE `Dialog_`=’SetupCompleteSuccess’

比较中使用的常数应放在单引 (’)中。

MSI帮助库页面SQL语法描述了可在MSI数据库查询中使用的更多关键字。

注意:MSI仅支持完整SQL语法的子集:例如,不支持LIKE和LEN运算符。

SQL查询返回的是一组与查询匹配的记录。记录或行是一组索引字段,您的自定义操作代码可以使用Record对象的StringData和IntegerData属性检索所需的数据。

例如,假设自定义操作执行以下查询:

SELECT `Feature`,`Level` FROM `Feature`

返回的每个记录将包含两个字段:Feature字段,其中包含功能的字符串标识符,以及该功能的数字Install Level值。在代码中(假设记录对象存储在名为rec的变量中),您将使用以下内容引用所获取记录的第一个(字符串)字段:

rec.StringData(1) ‘ indexing starts with 1

然后,您将使用以下内容引用已获取记录的第二个(整数)字段:

rec.IntegerData(2)

示例:查询属性表

例如,以下代码从属性表中获取ProductName记录,然后显示ProductName值。(此示例仅是为了说明;在此特定情况下,表达式Session.Property(ProductName)返回相同的信息。)

Const IDOK = 1Function ReadProductName( )' open and execute the viewSet oView = Database.OpenView("SELECT `Value` FROM `Property` WHERE ` Property`='ProductName'")oView.Execute' fetch the one and only ProductName recordSet oRecord = oView.Fetch' display the string data from the fetched recordMsgBox "ProductName = " & oRecord.StringData(1)' clean upoView.Close' return success to MSIReadProductName = IDOKEnd Function 

要在自定义操作中使用先前的代码,请将代码放在名为(例如)ReadProductName.vbs的VBScript源文件中。

接下来,在IDE的自定义操作视图中,右键单击Custom Actions(自定义操作图标,然后选择New VBScript(新建VBScript>Stored in the Binary table(存储在二进制表中,将操作图标重命名为(例如)callReadProductName。

在callReadProductName操作的属性列表中,指定以下设置:

  • VBScript文件名: ReadProductName.vbs(ReadProductName.vbs浏览)
  • 脚本功能:ReadProductName(VBS文件中的功能名称)
  • 安装UI序列:SetupInitialization之后

构建并运行产品后,自定义操作将显示一个消息框,如下所示。

打包软件InstallShield提示和技巧:在运行时访问MSI数据库

与访问MSI属性一样,访问正在运行的MSI数据库仅对计划立即执行的自定义操作有效。

修改数据库表

Windows Installer还支持将临时记录添加到正在运行的MSI数据库中。将临时记录添加到正在运行的数据库中,最常见的用途可能是使用直到运行时才可用的数据填充用户界面元素。(当然,此技术仅适用于Basic MSI项目;对于InstallScript MSI项目,您可以使用InstallScript函数CtrlSetText,CtrlSetList,CtrlSetCurSel等填充和操作用户界面控件。)

然后,您可以将以下代码放在名为PropDisplay.vbs的源文件中。

Const msiViewModifyInsertTemporary = 7Const IDOK = 1Function PropDisplay( )' open and execute a view to the ListBox tableSet viewlist = Database.OpenView("SELECT * FROM `ListBox` WH ERE `Property`='LISTBOXPROP'")viewlist.Execute' open and execute a view to the Property tableSet viewprop = Database.OpenView("SELECT * FROM `Property`")viewprop.ExecuteSet recprop = viewprop.Fetchr = 0While Not (recprop Is Nothing)' ListBox record fields are Property, Order, Value, TextSet reclist = Installer.CreateRecord(4) r = r + 1 reclist.StringData(1) = "LISTBOXPROP"reclist.IntegerData(2) = r reclist.StringData(3) = recprop.StringData(1) reclist.StringData(4) = recprop.StringData(1) & "=" & Session.Property(recprop.StringData(1))' insert the temporary ListBox record viewlist.Modify msiViewModifyInsertTemporary, reclist' fetch the next Property recordSet recprop = viewprop.FetchWend' clean upviewprop.Close: viewlist.Close' return success to MSIPropDisplay = IDOKEnd Function 

注意:使用View对象的Modify方法(具有插入临时常量),该方法会修改或添加数据库记录。

在自定义动作视图中,像以前一样,右键单击Custom Actions(自定义操作图标,然后选择New VBScript(新建VBScript>Stored in the Binary table(存储在二进制表中),将该动作重命名为callPropDisplay,在VBScript文件名字段中浏览PropDisplay.vbs,并在脚本功能字段中指定PropDisplay。

然后,您可以在用户界面序列中提前安排操作,也可以在(例如)SetupType对话框的下一步按钮上使用DoAction控件事件。

生成并运行MSI程序包后,显示临时记录的ReadyToInstall对话框可能如下所示。

打包软件InstallShield提示和技巧:在运行时访问MSI数据库

通常,您需要确保插入临时记录的代码仅运行一次:如果先前的代码运行两次,则先前的代码将生成运行时错误,因为如果具有给定记录的调用带有insert-temporary标志的Modify方法失败, 则主键已经存在。

一种替代方法是使用类似于PropDisplay函数开头的以下代码删除存在的任何临时记录:

Set viewlist = Database.OpenView("SELECT * FROM `ListBox` WH ERE `Property`='LISTBOXPROP'")viewlist.ExecuteSet reclist = viewlist.Fetch' delete any existing LISTBOXPROP recordsWhile Not (reclist Is Nothing)viewlist.Modify 6, reclist ' 6 = deleteSet reclist = viewlist.FetchWendviewlist.Close 

此代码块防止与现有ListBox / LISTBOXPROP记录发生冲突,因此,如果用户单击后退按钮然后重新访问ReadyToInstall对话框,则可以防止错误。

与在设计时填充项目的ListBox控件一样,用户在ListBox中的选择(如果有的话)将存储在LISTBOXPROP(在此示例中)属性中。与往常一样,当执行从用户界面序列切换到执行序列时,将仅保留公共属性的值。您可以使用类似的代码在ListBox控件中填充映射的 络驱动器,用户帐户,目录名称或其他数据的列表,这些列表只有在特定目标系统上运行安装时才能发现。

在运行时使用MSI数据库访问时,应牢记以下几点:

  • Windows Installer不支持永久修改正在运行的MSI数据库:您在运行时所做的更改将不会存储在用户系统上缓存的MSI数据库中。
  • 此外,当执行从用户界面序列切换到执行序列时,Windows Installer会重新加载MSI数据库。因此,当执行切换到Execute序列时,对在User Interface序列中对数据库进行的临时修改将丢失。
  • 如前所述,自定义操作只能在立即执行期间访问正在运行的数据库,而不能延迟执行。


以上内容对您使用InstallShield是否有帮助果您有其他的疑惑或者建议都可以在评论区留言。

推荐文章:

MSI功能和组件的使用

InstallShield v2019最新更新说明

=================================================

如果您想要购买正版授权InstallShield,可以联系在线客服>>咨询相关问题。

标签:

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2020年1月17日
下一篇 2020年1月17日

相关推荐

发表回复

登录后才能评论