gpt4 book ai didi

installation - 升级时保留注册表设置

转载 作者:行者123 更新时间:2023-12-04 00:10:45 24 4
gpt4 key购买 nike

我正在使用 WiX 3.0。我在升级时试图保留我的所有注册表设置。

我找到了以下链接
http://www.mail-archive.com/wix-users@lists.sourceforge.net/msg28844.html

我更喜欢使用 Property 和 RegistrySearch 方法而不是自定义操作方法,因为我认为它看起来更简单。

不幸的是,这种方法对我来说效果不佳。我的项目有一些 DWORD 和 SZ 类型的注册表值。对于所有 DWORD 类型的注册表值,它会在前面附加一个 #。我检查了 WiX 引用手册。这就是 RegistrySearch 的工作原理。

所以,升级后,结果是我所有的DWORD类型的注册表都改成了SZ。该值看起来相同,只是在前面附加了一个 #。例如,我在注册表值“LogLevel”中获得了 DWORD 类型的值 2。升级后,我在注册表值“LogLevel”中获得了值“#2”,类型为 SZ 位于同一位置。

这是代码片段

<Property Id='LOG_LEVEL' Value='Information'>
<RegistrySearch Id='LogLevelRegistry' Type='raw' Root='HKLM' Key='Software\Company\Product' Name='LogLevel' Win64='$(var.Win64)'/>
</Property>

<Component Id="RegistryKey">
<RegistryKey Root='HKLM' Key='Software\Company\Product' Action='createAndRemoveOnUninstall'>
<RegistryValue Type='int' Name='LogLevel' Value='[LOG_LEVEL]'/>
</RegistryKey>
</Component>

我想知道是否有任何字符串函数可以帮助我在我放回去之前从 LOG_LEVEL 属性中删除“#”。或者在升级时有没有更聪明的方法来保留注册表项?我应该采用自定义操作方法吗?

最佳答案

我终于让 RegistrySearch 方法起作用了。我希望这可以在 future 帮助其他一些人。

我检查了 MSI 文档。注册表实际上不包含名为 type 的列。相反,它以一种奇怪的方式存储值,以便 MSI 知道它应该创建什么类型的注册表值。就我而言,我想创建一个 DWORD 类型的注册表值。如果我想将数值 1 放入注册表值,则该值应存储为注册表中的 #1。这是指向 Registry table 的链接

那么,为什么 Wix RegistryValue 有一个强制属性 Type?我想这是因为 Wix 想对你好。如果将类型标记为 int,则只需在 value 属性中输入“1”即可。你不需要记住你必须输入“#1”而不是“1”。当您编译 Wix 源代码时,编译器会为您做一些脏活,并将“1”翻译成“#1”。

同样,RegistrySearch 是到 MSI 数据库表 RegLocator 的直接映射。它向我返回 #1,因为我的注册表值类型是 DWORD。可惜这次Wix没有帮我翻译。以下代码将表中的原始数据返回给我。因此,我的属性 LOG_LEVEL 正在存储 #1 而不是 1。

<Property Id='LOG_LEVEL' Value='3'>
<RegistrySearch Id='LogLevelRegistry' Type='raw' Root='HKLM' Key='Software\Company\Product' Name='LogLevel' Win64='$(var.Win64)'/>
</Property>

这是 RegistrySearch 的链接

我的代码将注册表值存储到一个属性中。然后,我试图使用以下代码将其放回原处。
<Component Id="RegistryKey">
<RegistryKey Root='HKLM' Key='Software\Company\Product' Action='createAndRemoveOnUninstall'>
<RegistryValue Type='int' Name='LogLevel' Value='[LOG_LEVEL]'/>
</RegistryKey>
</Component>

正如我所说,Wix 会在看到“int”类型时为我附加一个 #。因此,注册表中的值现在是##1。如果您查看 MSDN 文档,##1 将被解释为字符串值“#1”。因此,我的注册表值使用新类型 SZ 和新值“#1”重新创建

为了解决这个问题,我把我的代码改成了这样
<Property Id='LOG_LEVEL' Value='#3'>
<RegistrySearch Id='LogLevelRegistry' Type='raw' Root='HKLM' Key='Software\Company\Product' Name='LogLevel' Win64='$(var.Win64)'/>
</Property>

<Component Id="RegistryKey">
<RegistryKey Root='HKLM' Key='Software\Company\Product' Action='createAndRemoveOnUninstall'>
<RegistryValue Type='string' Name='LogLevel' Value='[LOG_LEVEL]'/>
</RegistryKey>
</Component>

请注意,虽然我在这里指定了“字符串”类型,但我仍然有一个为我创建的 DWORD 类型的注册表值。这是因为这是 MSI 解释注册表中值的方式。如果注册表值 LogLevel 不存在(全新安装),我将为其设置默认值 #3。如果注册表值 LogLevel 存在,它将保留现有的 LogLevel。

另请注意,此方法有效,因为 Wix 3.0 不对属性值进行任何处理。它将存储在属性中的值直接放入注册表中。
出于好奇,我也尝试了以下方法。
<RegistryValue Type='string' Name='LogLevel' Value='#1'/>

这一次,Wix 正确转义了# 字符并将##1 放入注册表中。如果以后 Wix 也选择转义属性值中的 # 字符,我的解决方案将不起作用。

关于installation - 升级时保留注册表设置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4406403/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com