从注册表中读取值的成功取决于应用程序是在 IDE 中还是从命令行构建的

Success of reading values from registry depends on if the application was built in IDE or from command line

我遇到了一个非常奇怪的问题。

我在 C++ Builder 2010 中构建了一个应用程序。该应用程序在注册表中读取和写入一些内容。因为它是一个 32 位 应用程序,所以这些密钥最终出现在 wow6432Node 中。时不时地,它似乎无法从注册表中读取值。但只有在构建服务器(使用 TeamCity)上构建时才可以,而不能在开发机器上构建。通常新的提交和重建会使问题消失,因此很难诊断。

经过一些测试后,我注意到我能够在开发机器上重现它。但仅当通过手动调用 msbuild 从命令行构建时。如果在 IDE 中构建完全相同的项目,则没有问题。但由于某种原因,从命令行构建时生成的 exe 无法从注册表中读取值。

构建期间没有错误或警告。没有由于无效路径或类似原因而找不到的文件。据我所知,由于 msbuild 在构建时被 IDE 使用,这让我摸不着头脑。我尝试手动使用不同版本的 msbuild 等,但没有任何效果。

所以基本上,在同一台机器上,我生成的 exe 的行为有所不同,具体取决于我是从命令行手动启动构建还是 IDE 启动构建。

这到底是什么?

在花费大量时间尝试强制应用程序使用特定的注册表视图等之后,我被鼓励查看 UAC 清单设置。我发现该应用程序确实有一个清单文件,名称正确且位于正确的位置。它也包含在 .cbproj 文件中并由资源编译器编译。

但是,有些事情让我想到它可能没有被正确使用。经过一些挖掘后,似乎如果 运行时主题 为将创建将使用的 "default" 应用程序清单的项目启用。

禁用运行时主题 将允许编译器实际使用您的自定义应用程序清单文件(没有详细记录,但我发现很多 Embarcaderos 都是这种情况事物)。通过这样做,我能够为应用程序设置所需的执行级别,并且一切正常。

您仍然可以在您创建的 maniftest 文件中手动启用对 运行时主题 的支持。您的表单在 ide 中可能看起来有点奇怪,因为那会认为 运行时主题 被禁用。

要手动添加 运行时主题 支持,请将依赖项添加到自定义应用程序清单中。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

 ...

  <dependency>
    <dependentAssembly>
      <assemblyIdentity
        type="win32"
        name="Microsoft.Windows.Common-Controls"
        version="6.0.0.0"
        publicKeyToken="6595b64144ccf1df"
        language="*"
        processorArchitecture="*"
        />
    </dependentAssembly>
  </dependency>

  ...

</assembly>

将其另存为 Foo.exe.manifest,其中 Foo.exe 是您的应用程序名称。 然后为您的应用程序创建一个 .rc 文件。例如FooManifest.rc

#define MANIFEST_RESOURCE_ID 1
#define RT_MANIFEST 24
MANIFEST_RESOURCE_ID RT_MANIFEST "Foo.exe.manifest"

现在您将能够使用您自己的自定义应用程序清单来构建您的应用程序,并且仍然保持对 运行时主题.

的支持