2011-08-10 68 views
0

我一直在使用WiX項目一段時間,並且使用我的安裝程序初始化的註冊表值已被證明是「有趣的」。請在這裏尋找理智檢查。WiX RegistryValue設置爲空(Value =「」)

我有我的WiX的腳本下面一行,創建一個註冊表值:

"polling_manifest"=hex(7):00,00,00,00 

<RegistryValue Type="multiString" Name="polling_manifest" Value="" /> 

這與看起來像這樣(從註冊表編輯器/出口)中的數據創建一個註冊表值

對我來說,它看起來像一個字符串[2],裏面有兩個空字符串。實際上,如果你喜歡的東西打開此註冊表值:

public static string[] pollingManifestValue 
    { 
     get 
     { 
      return (string[])RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64) 
       .OpenSubKey(AppSettingsGet("RegPathKeyConary")) 
       .GetValue(AppSettingsGet("rTISRegKeyPollingManifest")); 
     } 

     set 
     { 
      RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64) 
       .OpenSubKey(AppSettingsGet("RegPathKeyConary"), true) 
       .SetValue(AppSettingsGet("rTISRegKeyPollingManifest"), value); 
     } 
    } 

pollingManifestValue回來爲空。因此,訪問這個構造的所有代碼都必須具有「首先檢查null,然後訪問屬性」類型的代碼。

我知道那些檢查是正確的,我不希望成爲一個更懶惰的程序員。我正在尋找那些比我更有經驗的人的想法和建議,因爲我覺得我沒有做到最好。任何代碼審查/使用指導是非常受歡迎的,我提前感謝你。

回答

0

使用此代碼

<RegistryKey Id="ServiceName" Action="createAndRemoveOnUninstall" Key="SOFTWARE\ProductName\[ProductCode]\FeatureName" Root="HKLM"> 
    <RegistryValue Id="ServiceName" Type="string" Name="ABC" Value="[SERVICENAME]"></RegistryValue> 
    <RegistryValue Id="ServiceInstallLocation" Type="string" Name="ServiceInstallLocation" Value="[INSTALLLOCATION2]"></RegistryValue> 
</RegistryKey> 

對於讀取註冊表,你可以使用簡單的代碼如下面

string processor = System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE"); 
processor = processor.Substring(processor.Length - 2, 2); 

if (processor == "86") 
{ 
    regkey = Registry.LocalMachine.OpenSubKey("Software\\ABC company"); 
} 
else 
{ 
    regkey = Registry.LocalMachine.OpenSubKey("Software\\Wow6432Node\\ABC company"); 
} 

如果返回然後讀取值

Registry.GetValue(regkey + "\\Services", "ServiceName", "0") 

創建註冊表項「0」,那麼值不存在,否則它會給你服務名稱。

+0

請注意,根據[訪問備用註冊表視圖](http://msdn.microsoft.com/zh-cn/library/aa384129.aspx),不建議直接使用'Wow6432Node'鍵。 OP使用'RegistryKey.OpenBaseKey()'指定適當的['RegistryView'](http://msdn.microsoft.com/en-us/library/microsoft.win32.registryview.aspx)訪問備用視圖的方法是非常好。 –

0

在內部,REG_MULTI_SZType="multiString")值由空字符串結尾的序列表示,以空字符串結尾。

雖然this MSDN page明確指出它不可能包括序列在零長度字符串,像WiX的工具並允許寫入空字符串到註冊表中。註冊表編輯器在某些地方正確顯示這些值時,會在保存之前刪除空字符串。

所以,你的例子

<RegistryValue Type="multiString" Name="polling_manifest" Value="" /> 

這也可以寫成如下,以使其意圖更清晰

<RegistryValue Type="multiString" Name="polling_manifest"> 
    <MultiStringValue></MultiStringValue> 
</RegistryValue> 

會被寫入註冊表爲空字符串,然後是\ 0字符,然後是序列終止\ 0字符。每個字符由兩個字節表示,整個序列導出爲"polling_manifest"=hex(7):00,00,00,00

在測試時,我發現.NET至少在版本4中不使用c樣式字符串處理來讀取REG_MULTI_SZ值,並且可以清楚地處理空字符串。使用像你這樣的代碼顯然返回一個包含一個空字符串元素的字符串數組。

我注意到您在代碼中使用了64位註冊表視圖,但是您的值是否會寫入此註冊表視圖尚不清楚。此外,從配置中讀取關鍵路徑和值名稱;你確定他們是正確的嗎?

+0

嗨托馬斯,回覆:註冊表視圖。是的,該應用程序是一款32位應用程序,它在32位和64位系統上維護註冊表的一部分,這些系統也可以通過非Windows平臺解決方案訪問,因此無論Windows的位置如何OS架構,我們採用了一種觀點(HKLM \ Software \ Company \ ...)。 – joebalt

+0

...輸入密碼....對不起。關鍵路徑和值名稱很好,因爲更新發生得很好。在我的代碼中,我沒有得到包含一個空字符串的字符串數組。我得到一個空字符串[]。對該對象的任何引用都會導致NullReferenceException。 – joebalt