Click here to Skip to main content
Click here to Skip to main content

Lessons learned migrating to Visual Studio 2012 and .NET 4.5

, 15 Mar 2013
Rate this:
Please Sign up or sign in to vote.
A collection of problems and solutions for migrating projects to Visual Studio 2012 and .NET 4.5.
Prize winner in Competition "Best C++ article of March 2013"

This article is a collection of tips and tricks for migrating projects from Visual Studio 2008 to Visual Studio 2012. Migrating a large application (around 120 projects, 4MLO) written with C++, C#, C++/CLI and involving different technologies and frameworks I have stumbled on different problems that I want to share, hopefully to make the transition easier for others. This article is not about new features in Visual Studio 2012 and .NET 4.5, it is about problems you might encounter when you migrate. Of course, these are not all the problems, but some that I can share from experience.

Some of the issues mentioned in this article are not specific to Visual Studio 2012 or .NET 4.5, but were actually introduced in Visual Studio 2010 and .NET 4.0. Therefore, if you are already familiar with this version, you probably know at least some of theme.

Native

Project Files

The first most important issue for VC++ projects is that the format of the project files has changed. In Visual Studio 2010, VC++ moved away from VCBuild and started using MSBuild. With this switched the project files also changed to an MSBuild format. The new files have the extension .vcxproj, but there is an automatic conversion from the old .vcproj files to the new format. This can however lead to some warnings or even errors in the build.

One of the issues that I encountered was caused by the fact that I used to explicitly specify the Output File in the Linker settings. I used to do settings like $(OutDir)\MyAppD.exe in a Debug configuration and $(OutDir)\MyApp.exe in a Release configuration. That triggers some warnings:

1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\Microsoft.CppBuild.targets(1137,5): warning MSB8012: TargetPath(D:\Marius\VC++\MFCApplication1\Debug\MFCApplication1.exe) does not match the Linker's OutputFile property value (D:\Marius\VC++\MFCApplication1\Debug\MyAppD.exe). This may cause your project to build incorrectly. To correct this, please make sure that $(OutDir), $(TargetName) and $(TargetExt) property values match the value specified in %(Link.OutputFile). 1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\Microsoft.CppBuild.targets(1139,5): warning MSB8012: TargetName(MFCApplication1) does not match the Linker's OutputFile property value (MyAppD). This may cause your project to build incorrectly. To correct this, please make sure that $(OutDir), $(TargetName) and $(TargetExt) property values match the value specified in %(Link.OutputFile).

To fix this the most appropriate solution is to use $(OutDir)$(TargetName)$(TargetExt) as the Output file and make the appropriate settings of these properties under the General page.

Windows XP Support

The RTM release of Visual Studio 2012 has dropped support for targeting Windows XP and Windows Server 2003 for VC++ projects, requiring minimum Windows Vista and Windows Server 2008. After great demand Microsoft have brought back the support for those operating systems in Update 1. By default, the toolset for VC++ projects is set to Visual Studio 2012 (v110), but after installing Update 1 a new toolset called Visual Studio 2012 - Windows XP (v110_xp) is available (installed side-by-side). Change to this toolset if you want to still target Windows XP/Windows Server 2003.

However, you should notice that if your application is mixed and also using .NET, the 4.5 version also no longer supports these older operating systems. In this case you either drop support for them, or do not migrate your managed projects to .NET 4.5. .NET 4.0 is the last framework version that supports those operating systems.

MFC ODBC Bugs

To my surprise, some important routines that were using CDatabase for SQL server access no longer worked and even crashed the application. Investigating the problems I have discovered a couple of bugs in MFC:

Until fixes will be available it is possible to work-around these problems by deriving your own class from CDatabase and:

  • Provide another method for returning the connection string that is first decrypting an encrypted version of the connection string (CDatabase keeps one internally, but it's available for derived classes); I have proposed an implementation here.
  • Override OpenEx() and make sure to null pointers to released memory. I have proposed an implementation here.

Mixed-mode

For C++/CLI projects it is not possible to specify the version of the .NET framework you want to target from the IDE. The only available option is to manually set the desired value in the .vcxproj file. What you have to do is adding a <TargetFrameworkVersion> element under <PropertyGroup Label="Globals">.

  <PropertyGroup Label="Globals">
    <ProjectGuid>...</ProjectGuid>
    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
  </PropertyGroup>

Regardless you use .NET 4.0 or .NET 4.5 (which share the same 4.0 CLR), you may run into a runtime error like this:

Mixed mode assembly is built against version 'v2.0.50727' of the runtime and cannot be loaded in the 4.0 runtime without additional configuration information.

That occurs when your application targeting CRL 4.0 tries to load a mixed-mode assembly (directly, or indirectly through one of the loaded modules) that is built with a previous version of the .NET framework that targets CLR 2.0 (or even 1.x). The problem occurs because .NET 4.0 has changed the way it binds to older mixed-mode assemblies. There are two possible fixes:

  • Make sure all the modules you load are targeting CLR 4.0; however, this might not be always possible, in which case
  • Add a fallback option in the application configuration file; the key here is the useLegacyV2RuntimeActivationPolicy attribute that must be set to true.
    <startup useLegacyV2RuntimeActivationPolicy="true">
      <supportedRuntime version="v4.0"/>
    </startup>
    

You can read more about this problem here.

Managed

Interop assemblies

You may have projects that have references to COM servers, and therefore using interop assemblies, and code that may look like this:

using SomeLib;

namespace ClientApp
{
   class Program
   {
      static void Main(string[] args)
      {
         var o = new SomeLib.DummyClass();
      }
   }
}

When you migrate this to .NET 4.0/4.5 you get the following error:

1>[…]: error CS1752: Interop type 'SomeLib.TestClass' cannot be embedded. Use the applicable interface instead.
1>[…]: error CS0143: The type 'SomeLib.TestClass' has no constructors defined

.NET 4.0 (and of course 4.5) allow embedding type information for COM types directly into managed assemblies instead of using an interop assembly (basically statically linking everything that is needed, instead of requiring an additional interop assembly) (see MSDN for details). However, this has some limitations, and one of them is that classes cannot be embedded. Detailed information about the problem can be found here.

There are basically two solutions:

  • Disable the embedding of interop assemblies; you can go to the properties page of a reference and set the Embed Interop Types to false;
  • Simply remove the Class suffix from the instantiated COM coclass.
    var o = new SomeLib.Dummy();

I would prefer the later, since it still leverages the benefit of embedding the interop types and making unnecessary the interop assemblies. (Notice that if you build COM components, primary interop assemblies for COM components are still necessary if you want your COM component to be consumed from applications using a previous version of the .NET framework).

WPF

Applications using WPF need to add a new reference (in addition to PresentationCore, PresentationFramework and WindowsBase): System.Xaml.dll.

Setup

Visual Studio Setup Project is no longer available in Visual Studio 2012. If you have such projects then you have several alternatives:

  • Continue to develop and build these projects with a previous version of Visual Studio;
  • Use InstallShield; a free, limited edition is available from Visual Studio and you can convert (with some tools) existing .vdproj files;
  • Use WIX (Windows Installer XML) toolset, but you need at least version 3.7, because this is the first one that supports Visual Studio 2012;
  • Use any other (free or commercial) tools for developing setup projects.

Which one should be the best option probably depends on various factors. I would personally prefer switching to WIX. The only feature that WIX is missing is handling pre-requisites, but you can use dotNetInstaller for that. A comparison of various deployment tools is available here.

Text templates

Template assembly directives used to be resolved using project references. So if you had to reference an assembly called something.dll in a .tt file you first had to add a reference to it and then use it in the assembly directive:

<#@ assembly name="something.dll" #>

In Visual Studio 2010 the way assembly directives are resolved has changed (the complete list of changes for T4 in Visual Studio 2010 can be found here). The T4 engine is now sandboxed to keep the T4 assemblies separate from the project assemblies. Therefore migrating T4 projects to VS2010/VS2012 may result in compiler errors. The possible solutions for this problem are:

  • Put the assembly in GAC and use namespace reference or fully qualified type name
  • Put the assembly in Visual Studio Public Assembly Folder and use namespace reference or fully qualified type name
  • Use fully qualified paths
  • Use a Windows Environment Variable to build fully qualified paths
  • Use Visual Studio macros to build fully qualified paths

You can learn more about the problem and the solutions here and here.

Debugging

A first important aspect is even though you can still target Windows XP for native projects, remote debugging only works for Windows 7/Server 2008 R2 and newer operating systems. For all the previous versions (Windows XP, Windows Vista, Windows Server 2003 and Windows Server 2008) this feature is no longer available. You can check the platform compatibility and system requirements. If this is still important to you then you must use the debugger from a previous version of Visual Studio (together with the remote tools).

Another feature that affects the debugging experience is that Visual Studio 2012 by default will try to load symbols for all modules from Microsoft symbol servers. The result is when the debugger attaches to a process it takes a long time to load everything. That can vary from several seconds, to several minutes, depending how many symbol files it must download (the bigger the application and more modules it loads, the longer it takes).

I recommend changing the default "All modules, unless excluded" to "Only specified modules". You can leave the list of specified modules empty, or you can specify the modules you want.

Conclusion

As mentioned in the beginning, this article is a collection of lessons learned migrating various projects from Visual Studio 2008 and .NET 3.5 to Visual Studio 2012 and .NET 4.5. You will probably encounter other problems too, but I hope this article can guide you in solving some of them.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Marius Bancila
Software Developer (Senior) Visma Software
Romania Romania
Marius Bancila is a Microsoft MVP for VC++. He works as a software developer for Visma, a Norwegian-based company. He is mainly focused on building desktop applications with VC++ and VC#. He keeps a blog at http://www.mariusbancila.ro/blog, focused on Windows programming. He is the co-founder of codexpert.ro, a community for Romanian C++ programmers.
Follow on   Twitter

Comments and Discussions

 
QuestionThanks.. more questions PinmemberAmar S. Kumbhar14-May-14 20:42 
Thanks..a lot. Great you share and that helps others.
 
I just started converting vs2008 project into vs2013 and found these lessons very helpful.
- I was able to resolve error MSB8012: $(TargetPath) does not match based on these article.
 
Have additional questions, I continue researching on this. Please respond in case these are known issues.
 
- As there is xml change, is it okay to ignore warnings like Attribute 'ProjectType' of 'ReleaseLib64' is not supported in this version and has been removed during conversion. I assume its okay
 
- Additional error with macros : All user macros reported below for configuration 'Debug|Win32' are used before their definition, which can cause undesirable build results; this is not supported in this release. You can resolve this by changing the inclusion order of the consuming property sheets and making sure they come after the property sheets defining the user macros.
MSB4211: C:\Program Files (x86)\MSBuild\12.0\bin\Microsoft.Common.CurrentVersion.targets (86,5); The property "TargetPlatformIdentifier" is being set to a value for the first time, but it was already consumed at "C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.Cpp.Common.props (103,5)".
AnswerRe: Thanks.. more questions PinmemberAmar S. Kumbhar14-May-14 21:34 
SuggestionAddition PinmemberChona11711-Apr-14 1:20 
Questiongeneral settings for .lib targets PinmemberColumbia280522-Jul-13 13:54 
AnswerRe: general settings for .lib targets PinmemberMarius Bancila22-Jul-13 19:33 
GeneralMy vote of 5 PinmemberDevMarcus4-Jul-13 3:03 
QuestionNice experience PinprofessionalAbhishek Sur24-May-13 12:03 
GeneralMy vote of 5 Pinmemberrm82223-May-13 8:01 
GeneralMy vote of 5 PinmemberMihai MOGA12-Apr-13 19:00 
QuestionUpgrading to VS 2012 Pinmvpgeoyar29-Mar-13 9:57 
AnswerRe: Upgrading to VS 2012 PinmemberMarius Bancila31-Mar-13 9:14 
GeneralRe: Upgrading to VS 2012 Pinmemberkabdolla20-Jun-13 5:21 
SuggestionDon't skip versions when updating projects Pinmemberjeffb4215-Mar-13 6:46 
GeneralRe: Don't skip versions when updating projects Pinmemberkodabd15-Mar-13 10:02 
GeneralRe: Don't skip versions when updating projects PinmemberMarius Bancila15-Mar-13 11:14 
GeneralRe: Don't skip versions when updating projects Pinmemberjeffb4215-Mar-13 14:14 
GeneralRe: Don't skip versions when updating projects PinmemberMarius Bancila17-Mar-13 8:42 
GeneralRe: Don't skip versions when updating projects Pinmember.:floyd:.23-Apr-14 20:33 
QuestionMy vote of 5 PinmemberMember 902399215-Mar-13 6:18 
GeneralRe: My vote of 5 Pinmemberandreas12372-Jul-13 7:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140721.1 | Last Updated 15 Mar 2013
Article Copyright 2013 by Marius Bancila
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid