2010-12-10 95 views
0

我正在使用WiX 3.0。我正在嘗試在升級時預先保存所有註冊表設置。升級時保存註冊表設置

我發現下面的鏈接 http://www.mail-archive.com/[email protected]/msg28844.html

我更喜歡使用屬性和RegistrySearch方法,而不是自定義操作方法,因爲我認爲它看起來更簡單。

不幸的是,這種方法對我來說效果不好。我的項目有一些DWORD和SZ類型的註冊表值。對於所有DWORD類型的註冊表值,它在前面附加一個#。我檢查了WiX參考手冊。這是RegistrySearch的工作原理。

因此,升級後,結果是所有我的DWORD類型註冊表被更改爲SZ。該值看起來是一樣的,只是它在前面附加了一個#。例如,我在類型爲DWORD的註冊表值「LogLevel」中獲得了值2。升級後,我在同一位置使用SZ類型的註冊表值「LogLevel」獲得值「#2」。

下面是代碼片段

<Property Id='LOG_LEVEL' Value='Information'> 
    <RegistrySearch Id='LogLevelRegistry' Type='raw' Root='HKLM' Key='Software\Company\Product' Name='LogLevel' Win64='$(var.Win64)'/> 
</Property> 

<Component Id="RegistryKey"> 
    <RegistryKey Root='HKLM' Key='Software\Company\Product' Action='createAndRemoveOnUninstall'> 
     <RegistryValue Type='int' Name='LogLevel' Value='[LOG_LEVEL]'/> 
    </RegistryKey> 
</Component> 

我不知道是否有任何字符串函數,可以幫助我剪掉從LOG_LEVEL屬性「#」我把它放回去了。還是有什麼更聰明的方法來保存註冊表鍵進行升級時?我應該採用自定義操作方法嗎?

回答

5

我終於得到了RegistrySearch方法的工作。我希望這可能會在未來幫助其他人。

我檢查了MSI文檔。註冊表實際上不包含名爲type的列。相反,它以一種奇怪的方式存儲該值,以便MSI知道應該創建什麼類型的註冊表值。在我的情況下,我想創建一個DWORD類型的註冊表值。如果我想將數字值1置於註冊表值,則該值應該在註冊表中存儲爲#1。這是一個鏈接到Registry table

那麼,爲什麼Wix RegistryValue有一個強制屬性類型?我想這是因爲維克斯試圖對你很好。如果將該類型標記爲int,則可以在值屬性中簡單地放入「1」。你不需要記住你必須輸入「#1」而不是「1」。當您編譯Wix源代碼時,編譯器會爲您執行骯髒的工作,並將「1」翻譯爲「#1」。

同樣,RegistrySearch是直接映射到MSI數據庫表RegLocator。它向我返回#1,因爲我的註冊表值類型是DWORD。這次Wix沒有爲我做翻譯太糟糕了。以下代碼將表格中的原始數據返回給我。所以,我的財產LOG_LEVEL被存儲#1而不是1

<Property Id='LOG_LEVEL' Value='3'> 
    <RegistrySearch Id='LogLevelRegistry' Type='raw' Root='HKLM' Key='Software\Company\Product' Name='LogLevel' Win64='$(var.Win64)'/> 
</Property> 

這裏是鏈接存儲在註冊表值到屬性RegistrySearch

我的代碼。然後,我試着用下面的代碼把它放回去。

<Component Id="RegistryKey"> 
    <RegistryKey Root='HKLM' Key='Software\Company\Product' Action='createAndRemoveOnUninstall'> 
    <RegistryValue Type='int' Name='LogLevel' Value='[LOG_LEVEL]'/> 
    </RegistryKey> 
</Component> 

正如我所說的,當看到類型「int」時,Wix會爲我添加一個#號。因此,註冊表中的值現在是## 1。如果您檢查MSDN文檔,## 1將被解釋爲字符串值「#1」。因此,我的註冊表值的新型SZ和新值「#1」

重建要解決這個問題,我改變了我的代碼到althought我指定類型「string」這個

<Property Id='LOG_LEVEL' Value='#3'> 
    <RegistrySearch Id='LogLevelRegistry' Type='raw' Root='HKLM' Key='Software\Company\Product' Name='LogLevel' Win64='$(var.Win64)'/> 
</Property> 

<Component Id="RegistryKey"> 
    <RegistryKey Root='HKLM' Key='Software\Company\Product' Action='createAndRemoveOnUninstall'> 
    <RegistryValue Type='string' Name='LogLevel' Value='[LOG_LEVEL]'/> 
    </RegistryKey> 
</Component> 

注在這裏,我仍然有一個爲我創建的DWORD類型的註冊表值。這是因爲這是MSI如何解釋Registry表內的值。如果註冊表值LogLevel不存在(全新安裝),我將爲其設置默認值#3。如果註冊表值LogLevel存在,它將保留現有的LogLevel。

另請注意,此方法的工作原理是因爲Wix 3.0不對屬性值進行任何處理。它將存儲在屬性中的值直接放入註冊表表中。 出於好奇,我也嘗試了以下。

<RegistryValue Type='string' Name='LogLevel' Value='#1'/> 

這次,Wix正確地轉義#字符並將## 1放入註冊表中。如果後來Wix選擇逃離屬性值中的#字符,我的解決方案將無法工作。

0

無論如何,您需要立即爲此自定義操作。據稱This set of custom actions and extensions有這種行爲。您可能會考慮使用它,因爲它也聲稱在企業中經過了良好測試和使用。

希望這會有所幫助。

+0

謝謝,我今天會檢查出來 – 2010-12-10 15:22:47