WiX RegistryValue设置为null(Value =“”)

时间:2011-08-10 13:44:38

标签: wix

我已经在WiX项目上工作了一段时间,并且使用我的设置初始化的注册表值已被证明是“有趣的”。我在这里寻找理智的检查。

我的WiX脚本中有以下行,用于创建注册表值:

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

这会创建一个注册表值,其数据看起来像这样(来自regedit / export):

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

对我来说,它看起来像一个字符串[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。因此,访问此构造的所有代码都必须具有“先检查null,然后访问属性”类型的代码。

我知道那些检查是正确的,我不希望在这里成为一个更懒惰的程序员。我正在寻找那些比我更有经验的WiX深刻魔法的想法和建议,因为我觉得我没有做到最佳。我们欢迎任何代码审查/使用指南,我提前感谢您。

2 个答案:

答案 0 :(得分: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”,那么值不存在,否则它将为您提供服务名称。

答案 1 :(得分: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位注册表视图,但是不清楚您的值是否会写入此注册表视图。此外,从配置中读取密钥路径和值名称;你确定他们是对的吗?