翻譯|使用教程|編輯:況魚杰|2020-01-20 14:43:37.863|閱讀 528 次
概述:在某些情況下,對(duì)于正在運(yùn)行的安裝來(lái)說(shuō),訪問正在運(yùn)行的MSI數(shù)據(jù)庫(kù)的表可能很有用。本文提供了使用自定義操作在運(yùn)行時(shí)訪問和臨時(shí)修改MSI數(shù)據(jù)庫(kù)表的概述。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關(guān)鏈接:
InstallShield是構(gòu)建Windows安裝程序和MSIX包并直接在Microsoft Visual Studio中創(chuàng)建安裝的最快速最簡(jiǎn)單的方法。借助InstallShield,您可以快速適應(yīng)行業(yè)的變化,更快地進(jìn)入市場(chǎng)并提供引人入勝的客戶體驗(yàn)。
在某些情況下,對(duì)于正在運(yùn)行的安裝來(lái)說(shuō),訪問正在運(yùn)行的MSI數(shù)據(jù)庫(kù)的表可能很有用。本文提供了使用自定義操作在運(yùn)行時(shí)訪問和臨時(shí)修改MSI數(shù)據(jù)庫(kù)表的概述。
訪問數(shù)據(jù)庫(kù)表
在VBScript中,Session對(duì)象提供了Database屬性,該屬性表示正在運(yùn)行的MSI數(shù)據(jù)庫(kù)。 (在InstallScript和C中,API函數(shù)MsiGetActiveDatabase返回相同的信息。)在自定義操作中,您可以對(duì)正在運(yùn)行的數(shù)據(jù)庫(kù)執(zhí)行SQL查詢。
執(zhí)行SQL查詢
下面是在運(yùn)行時(shí)訪問MSI數(shù)據(jù)庫(kù)的步驟。
步驟1涉及創(chuàng)建SQL SELECT語(yǔ)句。SELECT語(yǔ)句的一般形式如下。
SELECT Fields FROM Tables
例如,要從FeatureComponents表中選擇所有字段,查詢將如下顯示,并使用星號(hào)(*)表示所有字段。
SELECT * FROM `FeatureComponents`
為避免與SQL關(guān)鍵字沖突,建議您將字段名和表名放在反引號(hào)(`)中。
執(zhí)行相同查詢的另一種方法是顯式標(biāo)識(shí)所需的字段名稱:
SELECT `Feature_`,`Component_` FROM `FeatureComponents`
您還可以使用WHERE子句來(lái)縮小SELECT語(yǔ)句的范圍,然后在字段值和常量字符串之間進(jìn)行比較,或者在兩個(gè)字段值之間進(jìn)行比較。 例如:
SELECT * FROM `Control` WHERE `Dialog_`='SetupCompleteSuccess'
比較中使用的常數(shù)應(yīng)放在單引號(hào)(')中。
MSI幫助庫(kù)頁(yè)面SQL語(yǔ)法描述了可在MSI數(shù)據(jù)庫(kù)查詢中使用的更多關(guān)鍵字。
注意:MSI僅支持完整SQL語(yǔ)法的子集:例如,不支持LIKE和LEN運(yùn)算符。
SQL查詢返回的是一組與查詢匹配的記錄。記錄或行是一組索引字段,您的自定義操作代碼可以使用Record對(duì)象的StringData和IntegerData屬性檢索所需的數(shù)據(jù)。
例如,假設(shè)自定義操作執(zhí)行以下查詢:
SELECT `Feature`,`Level` FROM `Feature`
返回的每個(gè)記錄將包含兩個(gè)字段:Feature字段,其中包含功能的字符串標(biāo)識(shí)符,以及該功能的數(shù)字Install Level值。在代碼中(假設(shè)記錄對(duì)象存儲(chǔ)在名為rec的變量中),您將使用以下內(nèi)容引用所獲取記錄的第一個(gè)(字符串)字段:
rec.StringData(1) ' indexing starts with 1
然后,您將使用以下內(nèi)容引用已獲取記錄的第二個(gè)(整數(shù))字段:
rec.IntegerData(2)
要確定字段使用的數(shù)據(jù)類型,可以查看所需表的MSI幫助庫(kù)頁(yè)面。打開特定表幫助頁(yè)面的一種簡(jiǎn)便方法是在InstallShield的直接編輯器視圖中選擇該表,然后按F1鍵。
示例:查詢屬性表
例如,以下代碼從屬性表中獲取ProductName記錄,然后顯示ProductName值。(此示例僅是為了說(shuō)明;在此特定情況下,表達(dá)式Session.Property(ProductName)返回相同的信息。)
Const IDOK = 1 Function ReadProductName( ) ' open and execute the view Set oView = Database.OpenView("SELECT `Value` FROM `Property` WHERE ` Property`='ProductName'") oView.Execute ' fetch the one and only ProductName record Set oRecord = oView.Fetch ' display the string data from the fetched record MsgBox "ProductName = " & oRecord.StringData(1) ' clean up oView.Close ' return success to MSI ReadProductName = IDOK End Function
要在自定義操作中使用先前的代碼,請(qǐng)將代碼放在名為(例如)ReadProductName.vbs的VBScript源文件中。
接下來(lái),在IDE的自定義操作視圖中,右鍵單擊Custom Actions(自定義操作)圖標(biāo),然后選擇New VBScript(新建VBScript)>Stored in the Binary table(存儲(chǔ)在二進(jìn)制表中),將操作圖標(biāo)重命名為(例如)callReadProductName。
在callReadProductName操作的屬性列表中,指定以下設(shè)置:
與訪問MSI屬性一樣,訪問正在運(yùn)行的MSI數(shù)據(jù)庫(kù)僅對(duì)計(jì)劃立即執(zhí)行的自定義操作有效。
修改數(shù)據(jù)庫(kù)表
Windows Installer還支持將臨時(shí)記錄添加到正在運(yùn)行的MSI數(shù)據(jù)庫(kù)中。將臨時(shí)記錄添加到正在運(yùn)行的數(shù)據(jù)庫(kù)中,最常見的用途可能是使用直到運(yùn)行時(shí)才可用的數(shù)據(jù)填充用戶界面元素。(當(dāng)然,此技術(shù)僅適用于Basic MSI項(xiàng)目;對(duì)于InstallScript MSI項(xiàng)目,您可以使用InstallScript函數(shù)CtrlSetText,CtrlSetList,CtrlSetCurSel等填充和操作用戶界面控件。)
例如,假設(shè)您要用屬性表中列出的每個(gè)屬性的當(dāng)前值填充ListBox控件。首先,您可以將ListBox控件添加到ReadyToInstall對(duì)話框中(使用InstallShield的對(duì)話框編輯器),然后將該控件與屬性LISTBOXPROP關(guān)聯(lián)。(如果需要,可以將ListBox屬性的Sorted和Sunken設(shè)置為True。)但是,不是在設(shè)計(jì)時(shí)填充ListBox控件的Items屬性,而是在運(yùn)行時(shí)通過(guò)在ListBox表中插入臨時(shí)記錄來(lái)填充其項(xiàng)目。
然后,您可以將以下代碼放在名為PropDisplay.vbs的源文件中。
Const msiViewModifyInsertTemporary = 7 Const IDOK = 1 Function PropDisplay( ) ' open and execute a view to the ListBox table Set viewlist = Database.OpenView("SELECT * FROM `ListBox` WH ERE `Property`='LISTBOXPROP'") viewlist.Execute ' open and execute a view to the Property table Set viewprop = Database.OpenView("SELECT * FROM `Property`") viewprop.Execute Set recprop = viewprop.Fetch r = 0 While Not (recprop Is Nothing) ' ListBox record fields are Property, Order, Value, Text Set 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 record Set recprop = viewprop.Fetch Wend ' clean up viewprop.Close: viewlist.Close ' return success to MSI PropDisplay = IDOK End Function
注意:使用View對(duì)象的Modify方法(具有插入臨時(shí)常量),該方法會(huì)修改或添加數(shù)據(jù)庫(kù)記錄。
在自定義動(dòng)作視圖中,像以前一樣,右鍵單擊Custom Actions(自定義操作)圖標(biāo),然后選擇New VBScript(新建VBScript)>Stored in the Binary table(存儲(chǔ)在二進(jìn)制表中),將該動(dòng)作重命名為callPropDisplay,在VBScript文件名字段中瀏覽PropDisplay.vbs,并在腳本功能字段中指定PropDisplay。
然后,您可以在用戶界面序列中提前安排操作,也可以在(例如)SetupType對(duì)話框的下一步按鈕上使用DoAction控件事件。
生成并運(yùn)行MSI程序包后,顯示臨時(shí)記錄的ReadyToInstall對(duì)話框可能如下所示。
通常,您需要確保插入臨時(shí)記錄的代碼僅運(yùn)行一次:如果先前的代碼運(yùn)行兩次,則先前的代碼將生成運(yùn)行時(shí)錯(cuò)誤,因?yàn)槿绻哂薪o定記錄的調(diào)用帶有insert-temporary標(biāo)志的Modify方法失敗, 則主鍵已經(jīng)存在。
一種替代方法是使用類似于PropDisplay函數(shù)開頭的以下代碼刪除存在的任何臨時(shí)記錄:
Set viewlist = Database.OpenView("SELECT * FROM `ListBox` WH ERE `Property`='LISTBOXPROP'") viewlist.Execute Set reclist = viewlist.Fetch ' delete any existing LISTBOXPROP records While Not (reclist Is Nothing) viewlist.Modify 6, reclist ' 6 = delete Set reclist = viewlist.Fetch Wend viewlist.Close
此代碼塊防止與現(xiàn)有ListBox / LISTBOXPROP記錄發(fā)生沖突,因此,如果用戶單擊后退按鈕然后重新訪問ReadyToInstall對(duì)話框,則可以防止錯(cuò)誤。
與在設(shè)計(jì)時(shí)填充項(xiàng)目的ListBox控件一樣,用戶在ListBox中的選擇(如果有的話)將存儲(chǔ)在LISTBOXPROP(在此示例中)屬性中。與往常一樣,當(dāng)執(zhí)行從用戶界面序列切換到執(zhí)行序列時(shí),將僅保留公共屬性的值。您可以使用類似的代碼在ListBox控件中填充映射的網(wǎng)絡(luò)驅(qū)動(dòng)器,用戶帳戶,目錄名稱或其他數(shù)據(jù)的列表,這些列表只有在特定目標(biāo)系統(tǒng)上運(yùn)行安裝時(shí)才能發(fā)現(xiàn)。
在運(yùn)行時(shí)使用MSI數(shù)據(jù)庫(kù)訪問時(shí),應(yīng)牢記以下幾點(diǎn):
推薦文章:
InstallShield v2019最新更新說(shuō)明
=================================================
如果您想要購(gòu)買正版授權(quán)InstallShield,可以聯(lián)系咨詢相關(guān)問題。
關(guān)注慧聚IT微信公眾號(hào)???,了解產(chǎn)品的最新動(dòng)態(tài)及最新資訊。
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自: