升级时保留注册表设置

发布于 2024-10-07 03:12:10 字数 1248 浏览 0 评论 0原文

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

我找到了以下链接 http://www.mail-archive.com/< span class="__cf_email__" data-cfemail="dcabb5a4f1a9afb9aeaf9cb0b5afa8aff2afb3a9aebfb9bab3aebbb9f2b2b9a8">[email protected]/msg28844.html

我更喜欢使用属性和注册表搜索方法而不是自定义操作方法,因为我认为它看起来更简单。

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

所以,升级之后,结果是我的DWORD类型注册表全部变成了SZ。该值看起来相同,只是前面附加了一个#。例如,我在 DWORD 类型的注册表值“LogLevel”中得到值 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 属性中删除“#”。或者有什么更聪明的方法来在升级时保留注册表项?我应该采用自定义操作方法吗?

I am using WiX 3.0. I am trying to preseve all my registry settings when doing upgrade.

I found the following link
http://www.mail-archive.com/[email protected]/msg28844.html

I prefer to use Property and RegistrySearch approach rather than custom action approach because I thought it looks simpler.

Unfortunately, this approach doesn't work very well for me. My projects got some DWORD and SZ type registry value. For all DWORD type registry values, it appends a # in the front. I checked the WiX refernce manual. This is how RegistrySearch works.

So, after the upgrade, the result is all my DWORD type registry is changed to SZ. The value looks the same except it has a # appended in the front. For example, I got value 2 in the registry value "LogLevel" with type DWORD. After upgrade, I get value "#2" in the registry value "LogLevel" with type SZ in the same location.

Here is the code fragment

<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>

I wonder if there is any string function that can help me trim off the "#" from LOG_LEVEL property before I put it back. Or is there any smarter way to preserve the registry keys when doing upgrade? Should I go for Custom Action approach?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

好倦 2024-10-14 03:12:10

我终于让RegistrySearch 方法发挥作用了。我希望这可以帮助其他人在未来。

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

这 ,为什么WixRegistryValue有一个强制属性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>

正如我所说,当看到类型“int”时,Wix 会为我附加一个#。因此,注册表中的值现在是##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>

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

另请注意,此方法之所以有效,是因为 Wix 3.0 不对属性值进行任何处理。它将存储在属性内的值直接放入注册表中。
出于好奇,我也尝试了以下方法。

<RegistryValue Type='string' Name='LogLevel' Value='#1'/>

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

I finally got the RegistrySearch approach working. I hope this may help some other people in the future.

I checked the MSI documentation. Registry table actually doesn't contain a column called type. Instead, it stores the Value in a weird way so that MSI knows what type of registry value it should create. In my case, I want to create a DWORD type registry value. The value should be stored as #1 in the Registry table if I want to put numeric value 1 to the registry value. Here is a link to Registry table

So, why does Wix RegistryValue has a mandatory attribute Type? I think it's because Wix is trying to be nice to you. If you mark the type as int, you can simply put in "1" in the value attribute. You don't need to remember you have to type in "#1" instead of "1". When you compile the Wix source code, the compiler will do the dirty work for you and translate "1" into "#1" for you.

Similarly, RegistrySearch is a direct mapping to the MSI database table RegLocator. It returns #1 to me because my registry value type is DWORD. It's too bad that Wix didn't do the translation for me this time. The following code returns the raw data from the table to me. So, my property LOG_LEVEL is storing #1 instead of 1.

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

Here is the link for RegistrySearch

My code stored the registry value into a property. Then, I was trying to put it back using the following code.

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

As I said, Wix would append a # for me when seeing the type "int". So, the value in the Registry table now is ##1. If you check the MSDN document, ##1 would be interpreted as a string value "#1". Therefore, my registry value is recreated with a new type SZ and new value "#1"

To fix this problem, I changed my code to this

<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>

Note that althought I specify type "string" here, I still have a registry value with type DWORD created for me. It's because this is how the MSI interprets the value inside the Registry table. If registry value LogLevel didn't exist (brand new installation), I will set a default value #3 to it. If registry value LogLevel exists, it will preserve the existing LogLevel.

Also note that this method works because Wix 3.0 doesn't do any processing on the property value. It puts the value stored inside the property directly into the Registry table.
Just out of curiosity, I also tried the following.

<RegistryValue Type='string' Name='LogLevel' Value='#1'/>

This time, Wix correctly escape the # character and put ##1 into the Registry table. If later Wix chooses to escape the # character inside the property value too, my solution here won't work.

哎呦我呸! 2024-10-14 03:12:10

无论如何,您都需要立即执行自定义操作。 这组自定义操作和扩展据称具有此类操作。您可能需要考虑使用它,因为它也声称在企业中经过了良好的测试和使用。

希望这有帮助。

In any case, you need an immediate custom action for this. This set of custom actions and extensions is claimed to have this sort of actions. You might want to consider using it as it is also claimed to be well tested and used in enterprise.

Hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文