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

Msbuild 从注册表读取值的成功与否取决于应用程序是在IDE中构建的还是从命令行构建的,msbuild,registry,c++builder,Msbuild,Registry,C++builder,我正面临一个非常奇怪的问题 我在C++ Builder 2010中构建了一个应用程序。此应用程序向注册表读取和写入一个位。由于它是一个32位应用程序,因此这些键最终位于WOW6432节点中。有时,它似乎在从注册表读取值时遇到了问题。但是只有在构建服务器上构建时(使用TeamCity),而不是在开发人员的机器上。通常,新的提交和重建会使问题消失,因此很难诊断 经过一些测试后,我注意到我能够在dev机器上复制它。但仅当通过手动调用msbuild从命令行生成时。如果在IDE中构建了完全相同的项目,则没

我正面临一个非常奇怪的问题

我在C++ Builder 2010中构建了一个应用程序。此应用程序向注册表读取和写入一个位。由于它是一个32位应用程序,因此这些键最终位于WOW6432节点中。有时,它似乎在从注册表读取值时遇到了问题。但是只有在构建服务器上构建时(使用TeamCity),而不是在开发人员的机器上。通常,新的提交和重建会使问题消失,因此很难诊断

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

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

因此,基本上,在同一台计算机上,我生成的exe的行为不同,这取决于我是从命令行手动启动构建还是IDE启动构建


这到底是什么?

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

但是,有些事情让我觉得它可能没有被正确使用。经过一些挖掘之后,似乎项目启用了运行时主题,将创建一个将要使用的“默认”应用程序清单

禁用运行时主题将允许编译器实际使用您的自定义应用程序maniftest文件(虽然没有很好的文档记录,但我发现在很多情况下都是这样)。通过这样做,我能够为应用程序设置所需的执行级别,并且一切都开始正常工作

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

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

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

现在,您可以使用自己的自定义应用程序清单构建应用程序,并且仍然保持对运行时主题的支持。

在不了解项目设置或环境的情况下,无法诊断此问题。首先想到的可能是两个构建之间的UAC显式冲突。另一种尝试是查看IDE的消息输出窗口,以查看它实际用于调用msbuild的确切命令行参数,然后在命令行生成中使用这些相同的参数,并查看是否存在相同的问题。当读取注册表失败时,让程序记录Winapi错误代码,它可能会给你一个机会clue@MattMcNabb:问题是似乎没有发生错误。(至少没有引发异常)。相反,调用TRegistry->ReadString只返回一个空字符串。@RemyLebeau:我已经检查了所有参数一次,发现它们是相同的。我可以再做一次来确定。关于可能的UAC清单冲突。如何检查/修复?UAC对我来说仅限于点击一个按钮来运行ass admin:)。。。它的深层内部工作原理是我以前从未深入研究过的,可能也与VirtualStore的注册表部分有关。尝试以管理员身份运行IDE和命令行(如果其中一个以管理员身份运行,而另一个不是,这就可以解释了)是的,在CB2010中,项目选项中没有使用自定义清单的设置,您必须禁用默认(仅主题)清单并使用.rc/.res文件来提供自定义清单。使用自定义清单的选项已添加到XE2中的项目选项中。
#define MANIFEST_RESOURCE_ID 1
#define RT_MANIFEST 24
MANIFEST_RESOURCE_ID RT_MANIFEST "Foo.exe.manifest"