Search code examples
msbuildregistryc++builder

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


I'm facing a really strange problem.

I have an application built in C++ Builder 2010. This application reads and writes a bit to the registry. Since it's a 32-bit application these keys end up in the wow6432Node. Every now and then it has appeared as though it has trouble reading the values from the registry. But only when build on the build server (using TeamCity) and never on the dev machines. Often a new commit and a rebuild would make the issue go away so it was hard to diagnose.

After some testing I noticed that I was able to reproduce it on the dev machine to. But only when building from the command line by calling msbuild manually. If the exact same project is built within the IDE there are no issues. But the exe produced when building from the command line, for some reason, can't read values from the registry.

There are no errors or warnings during builds. No files it can't find due to invalid paths or anything like that. Since msbuild is, as far as I can tell, used by the IDE when building to this has me scratching my head. I have tried to manually use different versions of msbuild etc, but nothing works.

So basically, on the same machine, my produced exe behaves differently depending on if I manually started the build from the command line or if the IDE started the build.

What on earth could this be?


Solution

  • After spending a lot of time trying to force the application to use specific registry views etc I was encouraged to look into the UAC manifest settings. I found that the application did in fact have a manifest file, named correctly and in the correct spot. It was also included in the .cbproj file and compiled by the resource compiler.

    But, something got me thinking that perhaps it's not being used correctly. After some digging it seems like if runtime themes is enabled for the project that will create a "default" application manifest that will be used.

    Disabling runtime themes will allow the compiler to actually use your custom application maniftest file (not exactly well documented, but I have found that to be the case with a lot of Embarcaderos things). By doing this I was able to set the required execution level for the application and things started to work just fine.

    You can still manually enable the support for runtime themes in the maniftest file you create. You forms might look a bit strange in the ide since that will think that runtime themes are disabled.

    To manually add runtime theme support you add the dependency to your custom application 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>
    

    Save it as Foo.exe.manifest, where Foo.exe is your application name. You then create a .rc file for your application. For instance FooManifest.rc

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

    Now you will be able to build your application using your own custom application manifest and still maintain support for runtime themes.