WIx - "Registry key not found" 试图查看 SQL SMO 的值是否存在

WIx - "Registry key not found" when trying to see if a value of SQL SMO exists

自从我完成任何 WiX 以来已经有一段时间了,但我发现我很久以前写的一些现有的引导程序 exe 实际上并没有像我想的那样 - 哦!我见过其他人有类似的问题,但我仍然不明白为什么它不起作用。

我基本上是在尝试确定是否安装了特定版本的 SQL SMO,并且正在以下位置查看注册表:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\SharedManagementObjects\CurrentVersion

其中有一个名为 "Version" 的 REG_SZ 键,它被设置为类似于 13.0.1601.5

下面是我的代码模型:

    <?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
     xmlns:bal="http://schemas.microsoft.com/wix/BalExtension"
     xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension"
     xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">

    <Bundle Name="RegReadTesterSetup" Version="1.0.0.0" Manufacturer="BigChris Inc" UpgradeCode="fcaa47db-3b55-474f-995d-2b0a0905fced">
        <BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense" />

    <util:RegistrySearch Id="IsSMOInstalled"
                 Root="HKLM"
                 Key="SOFTWARE\Microsoft\Microsoft SQL Server\SharedManagementObjects\CurrentVersion\Version"
                 Value="13.0.1601.5"
                     Win64="yes"
                 Result="exists"
                     Format="raw"
                 Variable="SMOInstalled"/>

        <Chain>
      <MsiPackage SourceFile="C:\Users\chris.moxon\AppData\Local\Temporary Projects\SimpleTextFileSetup\bin\Debug\SimpleTextFileSetup.msi"
              Id="MYTEXT"
              DisplayName="Big Chris Test File"
              Visible="yes"
              InstallCondition="SMOInstalled = 0"
              SuppressSignatureVerification="yes"/>
        </Chain>
    </Bundle>
</Wix>

注意:缩进设置(Win64 和格式)只是我试图让它工作的一些尝试;但有或没有这些设置; 运行 在 64 位或 32 位机器上,我总是得到(在这个密钥确实存在的机器上!):

Registry key not found. Key = 'SOFTWARE\Microsoft\Microsoft SQL Server\SharedManagementObjects\CurrentVersion\Version'

Setting numeric variable 'SMOInstalled' to value 0

在我的日志文件中;所以最终结果是 SMOInstalled 变量总是设置为 0,因此 SMO(或我的文本文件)总是被安装。

我很感激(或希望)我一定是在做一些愚蠢的事情——但可惜我不知道是什么!!

提前致谢,

大克里斯

这应该有效:

<util:RegistrySearch Id="IsSMOInstalled"
             Root="HKLM"
             Key="SOFTWARE\Microsoft\Microsoft SQL Server\SharedManagementObjects\CurrentVersion"
             Value="Version"
             Win64="yes"
             Result="exists"
             Variable="SMOInstalled"/>

进行 Result="exists" 注册表搜索时,您不需要 Format="raw"

您遇到的问题是您混淆了注册表中键和值的含义。 "Key" 是您在选择注册表位置时在注册表底部看到的路径。该值实际上是注册表项位置的注册表值的名称。在这种情况下,您想要的注册表值是来自键 "HKLM\SOFTWARE\Microsoft\Microsoft SQL Server\SharedManagementObjects\CurrentVersion" 的 "Version" 并且您正在查看该值是否存在(这会将 SMOInstalled 设置为 0(不存在)或 1(存在)) .

如果你想得到实际的版本信息(注册表值上的"data")你需要使用Result="value"然后SMOInstalled会被设置为Registry Value的数据如果不存在则未定义。

要理解Win64="yes",您需要了解 64 位注册表和 32 位注册表之间的区别。在 32 位机器上只有一个注册表,我不确定 Win64='yes' 注册表搜索的行为方式。在 64 位机器上有两个注册表位置。一种用于 32 位进程 (x86),一种用于 64 位进程 (x64)。如果明确指定,您可以从某个位数进程查看其他位数的注册表位置,但您需要确保这是您想要执行的操作。尝试查看注册表的 64 位计算机上的 32 位进程将其注册表项重定向到 SOFTWARE\Wow6432Node\abc\xyz... 即使您只指定了 SOFTWARE\abc\xyz... 。

如果您的程序适用于安装的 32 位或 64 位 SMO,您可能需要检查这两个注册表位置。这意味着对 32 位注册表位置进行两次注册表搜索,对 64 位位置进行一次注册表搜索。你可以这样

<util:RegistrySearch Id="IsSMOInstalledx86"
             Root="HKLM"
             Key="SOFTWARE\Microsoft\Microsoft SQL Server\SharedManagementObjects\CurrentVersion"
             Value="Version"
             Result="exists"                     
             Variable="SMOInstalled"/>

<util:RegistrySearch Id="IsSMOInstalledx64"
             After="IsSMOInstalledx86"
             Condition="SMOInstalled = 0 AND VersionNT64"
             Root="HKLM"
             Key="SOFTWARE\Microsoft\Microsoft SQL Server\SharedManagementObjects\CurrentVersion"
             Value="Version"
             Win64="yes"
             Result="exists"
             Variable="SMOInstalled"/>

(作为一个额外的问题,您不能在注册表条件中使用 "NOT SMOInstalled" 因为仅在条件中使用 PROPERTYNAMENOT PROPERTYNAME 实际上会评估 属性 是否已定义,实际上根本不计算 属性 的值。有关详细信息,请参阅 here,特别是在 "Properties in Expressions" header 下。)