WiX RegistrySearch 对 MultiString 失败

WiX RegistrySearch is failing for MultiString

我面临 RegistrySearch 多字符串问题,其中字符串搜索工作正常。 签入安装日志

Action start 13:40:07: AppSearch. MSI (s) (40:E0) [13:40:07:381]: PROPERTY CHANGE: Adding MYKEY property. Its value is ''. MSI (s) (40:E0) [13:40:07:381]: PROPERTY CHANGE: Adding MYSERVICE property. Its value is 'myvalue2'.

I have trimmed some logs here

Action ended 13:40:51: ScheduleReboot. Return value 1. Action ended 13:40:51: INSTALL. Return value 1. You must restart your system for the configuration changes made to XXXXX to take effect. Click Yes to restart now or No if you plan to manually restart later. Property(S): UpgradeCode = {XXXXXX-XXXX-XXX-XXXX-XXXXXXXX} Property(S): MYKEY = [~]myvalue1[~] Property(S): MYSERVICE = myvalue2

在安装结束时,它似乎已正确评估 MYKEY,但在 AppSearch 期间未正确评估,导致我的条件评估失败

<Feature Id="MyFeature" Level="" Display="" Title="" Description="" AllowAdvertise="no" ConfigurableDirectory="INSTALLDIR">
   <MergeRef Id="MyFeature" Primary="yes"/>
   <Condition Level="0">((MsiNTProductType=1) OR 
   (MYKEY="[~]MyValue[~]") OR 
   (MYSERVICE="MyService" AND MYKEY=""))</Condition>
   </Condition>
</Feature>
<Property Id="MYKEY" Secure="yes">
        <RegistrySearch Id="MyKey"
                             Root="HKLM"
                             Key="SYSTEM\CurrentControlSet\Services\MyService"
                             Name="mykey"
                             Type="raw" />
</Property>
<Property Id="MYSERVICE" Secure="yes">
        <RegistrySearch Id="MYSERVICE"
                        Root="HKLM"
                             Key="SYSTEM\CurrentControlSet\Services\MyService"
                             Name="DisplayName"
                             Type="raw" />
</Property>

UPDATE:我可能没有注意到你已经说过了,但是在检查 属性 是否由 AppSearch 设置时使用简单的 PROPERTYNAME 作为条件搜索有任何分配的值,条件显示为真 - 意味着 "something" 存在于相关的 属性 中,只是不显示文本。

是否只测试一个值的存在就足够了,还是需要检查MYKEY的具体值?如果仅仅存在一个值就足够了,那么您可以使用这个条件:

((MsiNTProductType=1) OR (MYKEY) OR (MYSERVICE="MyService" AND MYKEY=""))


I guess this answer from Rob Mensching from the WiX-users mailing list answers the question with certaintyMulti-string 根本不支持 AppSearch

没有必要怀疑这个的准确性,因为 Rob 在最初的 MSI 团队中。你需要放弃这种方法。不好意思说。除非我刚刚添加的上述解决方法可行(不检查值,但是否有从注册表中检索到的值)。

其他一些可能的解决方法:

  1. 您可以从自定义操作中读取 multi-string。我刚刚验证它可以与测试 VBScript 一起使用 - 禁止的 MSI 工具:-)。
  2. 你能在磁盘上搜索一个文件或目录,它表示你用这个多字符串从注册表中检索到的相同的东西吗?

我的座右铭是:让我们着迷于此(而不是:“小心,我们不想从中吸取教训" - 这是我的另一个座右铭 - 这往往是更好的选择)。

真奇怪,我可以复制你所说的日志文件。我看到 CommandLine 条目 正确显示 multi-sting,尽管有几个额外的空字符(稍微缩短的日志条目):

CommandLine: NORMALSTRING="sample regular string" MULTISTRING="[~~~]String 1[~~~]String 2[~~~]String 3[~~~]" INSTALLFOLDER="C:\Program Files (x86)\WiX3_GenericTestProject\" TARGETDIR="C:\" ACTION="INSTALL" EXECUTEACTION="INSTALL" ROOTDRIVE="C:\" INSTALLLEVEL="1" SECONDSEQUENCE="1"  ADDLOCAL=Empty,Modules,ProductFeature

并且稍后在日志文件中,在 InstallFinalize 之后:

Property(S): MULTISTRING = [~]String 1[~]String 2[~]String 3[~]

我真的不明白这是怎么回事。 AppSearch 一定确实设置了有问题的 属性,即使它看起来不像它那样 - 属性 只是无法正确检索(或格式正确),因此在(功能)条件下也不起作用?

可能 Windows 安装程序中的基础数据模型已将检索到的注册表多字符串值存储为 BSTR(允许嵌入空值的 COM 字符串格式的可憎行为并且可以编译和 linked without being properly allocated / constructed via SysAllocateString - “烧焦 child,闻起来有烧焦的味道 - 所有这些......”)。

无论如何,我想 AppSearch 需要一个常规的 null-terminated 字符串缓冲区并解释 BSTR as such? Hence stumbling on the first null value which is the first character of the data string section of the BSTR (not the length prefix section - the BSTR pointer points 4 bytes into the allocated BSTR memory) 并报告一个空字符串?日志文件中显示的 属性 值一定是通过其他方式直接从底层数据模型中读取的?我会假设 MSI Win32 C++ 函数?但 AppSearch 不也是如此吗? 在条件.

中显示和使用此 属性 字符串(嵌入空值)的方式有问题

所以总而言之:也许多字符串的检索确实有效,但是通过 Session.Property("PROP") 暴露的值错误地读取了潜在的,本机 BSTR 作为 null-terminated 字符串缓冲区并将前导空值解释为字符串缓冲区的结尾?考虑到 Session.Property 是一个 COM 调用并且绝对应该理解 BSTR 有点没有意义?像这样的理论从来都不是正确的,但也许它们至少可以帮助创造一些新想法。似乎缺少 Windows 安装程序功能,我认为有点像错误。或者就像在现实世界中一样:一个技术问题,不容易解决,因此被视为缺失的功能并被接受。


让我link把你在这个问题上的问题放在一起供参考(以及其他几个答案):

  • .
  • .
  • Passing multiString values to installer through command-line.