At work I've been porting a bunch of 32-bit C applications to 64-bit. To do this I'm running Windows XP x64 edition and having fun finding the little differences between 32-bit and 64-bit Windows. On these projects we are strict about our Visual C++ project settings. We have probably half a page of settings that must be tuned just right before our changes will be accepted into the source repository. Like any good programmer I hate checklists. Checklists are mundane things that eat up a lot of my time for very little in the way of results. I also think that machines are much better at checklists than I am. So I did what any self respecting programmer would do, I wrote a program to ensure the project settings were always correct.
Microsoft is nice enough to provide a barely documented set of COM classes inside the VCProjectEngine namespace. Yes, the vcproj files are XML. And, yes, I could have written an XML reader, but then I would have had to figure out the different enumerations and default values when an element wasn't present. The COM classes seemed like the way to go. I fired up Visual Studio 2005 and created a new C# GUI application. The first problem I ran into was that I needed to target the x86 platform when building. This is pretty obvious, I can't have a 64-bit application loading a 32-bit DLL, Microsoft.VisualStudio.VCProjectEngine.dll. Once I fixed that and got my code checking all of my settings I realized that I didn't need a whole GUI. I figured it would be easier to just run it from the command line and possibly integrate it into the build system.
So I started up a new C# Console application and copied all my code over. Then I ran into a much stranger problem. I'm porting these projects to target the x64 platform so those are, of course, the settings that I'm interested in checking. However, every time I listed out the platforms from VCProject.Platforms it would only show me x86. This meant that I couldn't access the build configurations that were targeted to x64. This didn't make any sense because the code worked just fine in the C# GUI application. I banged my head against my desk for awhile and rummaged around Google for a bit and came up empty handed. I started comparing each file in the projects for differences and something finally caught my eye. The C# GUI application had [STAThread] above the main function. So I
figured I'd give that a try. Sure enough, once I added that to my console app it was able to see the x64 platform just fine. I have no idea why the Single Threaded Apartment attribute has any affect on the platform detection in VCProjectEngine but it apparently does. I never bothered to learn much about COM Apartments so the little I do know doesn't offer me any clues. If anyone knows why this is I'd love to know. Or maybe this is just a bug in VCProjectEngine?