在WiX中,我如何测试Oracle ODP.Net是否存在注册表项(而不是值)

Dan*_*Dan 21 oracle wix odp.net wix3

更具体地说,我想测试是否在机器上安装了Oracle ODP.Net.我想通过测试HKLM\SOFTWARE\ORACLE\ODP.NET注册表项来完成此操作.

ODP.Net使用的实际值存储在HKLM\SOFTWARE\ORACLE\ODP.NET\2.111.6.20中,但是我假设这个较低级别的密钥名称将随着Oracle发布更新而更改.

我尝试了下面的失败,可能是因为(默认)值不存在或可能因为它是null(我不确定它在注册表中的确切表示).

<Property Id="ORACLE_ODPNET">
  <RegistrySearch Id="ODPNET_RegKey" Type="raw" Root="HKLM" Key="SOFTWARE\ORACLE\ODP.NET" Name="(Default)"/>
</Property>
<Condition Message="This setup requires ODP.Net to be installed.">
  Installed OR ORACLE_ODPNET
</Condition>
Run Code Online (Sandbox Code Playgroud)

所以以下任何一个对我都有帮助:

  • 一种搜索没有值的注册表项的方法.
  • 一种使用包含通配符的路径搜索注册表值的方法
  • 测试正在安装的ODP.Net的更好方法

Dan*_*Dan 18

好的,所以多亏了Sascha的信息,似乎答案是"你不能"使用内置的WiX注册表功能.

现在我也希望这个测试与其他启动条件测试一起发生,这使得它更难.让它工作已经花了我很长一段时间,虽然现在我知道如何相当简单,所以希望这会拯救别人同样的痛苦.

首先在WiX产品中创建一个属性:

<Property Id="ODPNETINSTALLED">0</Property>
Run Code Online (Sandbox Code Playgroud)

接下来创建自定义操作以检查密钥,并将ODPNETINSTALLED设置为"1"(如果存在).我不打算在此处编译并将自定义操作添加到安装程序,但如果在Visual Studio中使用Votive则相当简单.我的自定义操作的代码是:

using Microsoft.Deployment.WindowsInstaller;
using Microsoft.Win32;

namespace WiXCustomAction
{
  public class CustomActions
  {
    [CustomAction]
    public static ActionResult CheckOdpNetInstalled(Session xiSession)
    {
      xiSession.Log("Begin CheckOdpNetInstalled");

      RegistryKey lKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\ORACLE\ODP.Net");

      xiSession["ODPNETINSTALLED"] = lKey == null ? "0" : "1";

      return ActionResult.Success;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

现在您需要注册并安排操作,因为我希望警告与我的其他启动条件一起出现,我必须将其添加到Install UI Sequence元素:

<Binary Id="WiXCustomAction.dll" SourceFile="$(var.WiXCustomAction.TargetDir)$(var.WiXCustomAction.TargetName).CA.dll" />
<CustomAction Id="CheckOdpNet" BinaryKey="WiXCustomAction.dll" DllEntry="CheckOdpNetInstalled" Execute="immediate" />
<InstallUISequence>
  <Custom Action="CheckOdpNet" Before="LaunchConditions">NOT Installed</Custom>
</InstallUISequence>
Run Code Online (Sandbox Code Playgroud)

最后添加一个启动条件来检查属性:

<Condition Message="!(loc.OracleOdpCondition)">
  Installed OR ODPNETINSTALLED="1"
</Condition>
Run Code Online (Sandbox Code Playgroud)

请注意,我认为在InstallUISequence中进行调度意味着在非UI安装期间不会触发自定义操作.但是,我的安装程序必须安装UI,因此对我来说不是问题.


sas*_*ont 6

只需省略RegistrySearch/@ Name即可获得"(默认)"值.不幸的是,我无法进行递归搜索,你需要选择一个"已知"的注册表项,它将在发行版之间保持稳定并从中进行搜索.

<Property Id="ORACLE_ODPNET">
  <RegistrySearch Id="ODPNET_RegKey" Type="raw" Root="HKLM" Key="SOFTWARE\ORACLE\ODP.NET" />
</Property>
<Condition Message="This setup requires ODP.Net to be installed.">
  Installed OR ORACLE_ODPNET
</Condition>
Run Code Online (Sandbox Code Playgroud)

  • 好吧,所以看起来不可能只搜索一个键,你必须搜索一个值,并且(默认)值不够好,除非有人明确设置它(从未见过有人这样做过).看来我需要找到一种不同的ODP.Net测试方式,谢谢. (5认同)
  • 是的,是的.没有使用RegistrySearch进行递归搜索. (2认同)