Problem

I have recently migrated a C# 2.0 project registered for COM interop to .NET 4.5 and when I imported the type library in a C++ project with no_registry, suddenly I got some errors because the type library could not be imported. Here are the steps to reproduce:

  • create a .NET Class Library project and set platform target to .NET framework 4.5
  • check Register for COM interop
  • build the project
  • import the type library in a C++ project:

The result is the following error:

Solution

Searching for the solution I found that this was a known issue when you have both CLR 2.0 and 4.0 installed on the same machine. See this KB article: VC++ 2010 #import with no_registry fails with error C1083 or C3510. Unfortunately I was unable to fix the problem with the solution indicated there.

There are two tools that can generate a type library from an assembly:

  • tlbexp.exe: generates a type library from a specified .NET assembly
  • regasm.exe: registers metadata from an assembly to the Windows Registry, but in addition can create a type library from for the input assembly when /tlb switch is used.

When a project specifies to register for COM interop what Visual Studio does is similar to calling regasm.exe with /codebase switch specified. Since I had before problems with interop assemblies automatically generated by Visual Studio (with tlbimp.exe) I though it would be the same (only the other way around). Therefore I unchecked “register for COM interop” and added as a custom build step registration with regasm.exe, like this:

Not very surprisingly, the generated file was different and the #import command executed without problems.

Problem solved!

Cause

The question that arises is why are the two files, generated with Visual Studio and with regasm.exe, different? You can see they are different if you open them in an hex editor. But if you just use oleview.exe, the disassembled type library looks identical.

The obvious answer that occurred to me, but eventually proved wrong, was that Visual Studio is not actually using regasm.exe to register the assembly and generate the type library. It actually uses a MSBuild task for that.

When the RegisterForComInterop property is set in a .csproj an MSBuild task is executed.

The task can be found in Microsoft.Common.targets (in c:\Windows\Microsoft.NET\Framework\v4.0.30319\)

To check if I can reproduce, I have created MSBuild file (explicitreg.xml) with some hard-coded values that only runs that registration task.

But surprise: this produced the exact same output as the regasm.exe command. Comparing the diagnose logs from MSBuild (for the build of the .csproj and my custom file) I couldn’t spot any difference in the execution of the task. Also using the Process Monitor (procmon.exe from Sysinternals) to check access to the TLB file, I could clearly see the difference for the file writing, because different lengths were produced from Visual Studio build and explicit MSBuild run, though again I could not see any difference in the call stacks.

So, the actual cause for this behavior is still unknown to me and I would appreciate if anyone that knows the answer clarifies it.

, , , , , , , Hits for this post: 50666 .

Text templates (aka T4) is a great feature in Visual Studio, that proves helpful in many scenarios. I use it for instance in developing Alchemy. However, it has a significant drawback: it does not generate code automatically when you build your solution. To build the files and generate their output you have to manually run either Run Custom Tool command for each .tt file, or Transform All Templates for the entire solution.

Run Custom Tool

Transform All Templates

The good news is that Visual Studio 2010 has added capabilities for building the text templates files automatically at the build time. Basically, what you have to do is two things: first install the Visual Studio Visualization and Modeling SDK. Second, manually add the following to the project file:

And that should do the trick. When you build the project, the .tt files will also be built.

To read more about this topic see:

, , , , Hits for this post: 50089 .

The new version of Visual Studio, called Visual Studio 2010 comes with a series of changes for Visual C++. This includes a new build system, new project system, multi-targeting, new IntelliSense, support in MFC for new controls, new additions to the C++ compiler (which were already approved for C++0x), new deployment model, and others. In this post I will talk about the new build system and multi-targeting.

In order to show the changes I will create two simple projects, one in Visual Studio 2008, called Wordpad 2008, and one in Visual Studio 2010, called Wordpad 2010. These would be simple MFC single document applications. The image bellow shows the two solutions opened in Solution Explorer.

As you can see both versions contain the same solutions file (only the suffix in the name differs). The next image shows the files on disk, in comparison for the two solutions.

MS-Build System

The first thing to notice (though it might not be the obvious) is that the project file extension was modified. In Visual Studio 2008 it is called .vcproj, but in Visual Studio 2010 is called .vcxproj. Not only the extension changed, but also the content of the file. This is because in Visual Studio 2010, Visual C++ build system was changed from VCBuild to MSBuild. This build engine was already used for the languages targeting the .NET framework.

MSBuild uses XML project files, and the most important elements of a project are:

  • Items: units of input into the build system, grouped into item collections, which can be used as parameters to the tasks, using the syntax @(ItemCollectionName). Examples of items from the Wordpad2010 project:
  • Properties: pairs of key/value used to configure the builds. The value of a property can be changed after it was defined. They can be referred in the project file using the syntax $(PropertyName). Examples of properties from the Wordpad2010 project.
  • Tasks: reusable units of executable code used to perform builds. Example of tasks can be compiling input files, linking, running external tools. Tasks can be reused in different projects.
  • Targets: represent groupings of tasks in a particular order and expose parts of the project file as entry points into the build system.

You can get a deeper overview on the MSBuild engine here.

Another thing to notice is the presence of a file called Wordpad2010.vcxproj.filters. This file defines the solution explorer tree with the files contained in the project. This used to be a part of the file project, but in Visual Studio 2010 it was moved into a separate file. The reason is to keep the project file only for the build, not for the organization of the project.

The user specific settings used to be stored in a file called ProjectName.vcproj.fullyqualifiedusername.user. Now there is a new file called ProjectName.vcxproj.user.

You can read more about these changes in MSDN.

Multi-targeting

Visual Studio 2008 came to support for multi-targeting of the .NET framework, not only for C# and VB.NET, but also for C++/CLI. In addition to that, Visual Studio 2010 comes with support for native multi-targeting.

The managed multi-targeting allows to target different versions of the .NET framework for mixed-mode applications. By default the target version is the latest, 4.0. This can only be changed manually in the project file. The support for changing this from the IDE was not included in this version. Actually it was dropped, because in Visual Studio 2008 this was possible.

The native multi-targeting allows to use different versions of the tools and libraries to build (native) C++ projects. Of course, you must have the targeted toolset installed on your machine, in order to do that. You can define different configurations that target different versions of the toolsets. The targeted toolset can be changed from project’s properties page, General, Platform Toolset. The following image shows the available options on a machine with Visual Studio 2008 SP1 and Visual Studio 2010 installed side by side.

It is possible to target the previous version, 2008, 2005, 2003 and 2002. In theory it’s possible to target even VC6, but there is no support from Microsoft for that.

I suggest to read more about native multi-targeting here, and about managed multi-targeting, for mixed-mode applications, here.

In a next post I will talk about the changes to IntelliSense and browsing experience.

, , Hits for this post: 58184 .

Visual Studio 2010, currently in beta 1, replaces VCBuild with MSBuild as the build system, aligning C++ with the other languages that already used MSBuild. The VC++ team has already posted several articles on it’s blog about the new build system. Channel 9 has published recently a video with Bogdan Mihalcea, a developer in the VC++ build and system project team, talking about MSBuild. You can watch the video here.

, , , Hits for this post: 33071 .