VS 2012 migration – neither a trek nor a joyride

 

Lately, my team and I worked on migrating our entire codebase to Visual Studio 2012. I would like to share with you some of my thoughts on the process, and some tips you may find very helpful if you are thinking of upgrading your application, even if you are already under way.

 

Our code is comprised of 1400+ projects divided between C# and Windows C++ code, in fairly equal amounts. We also had  various framework & redistributable versions ranging from vc6 up to vc2010 and both c# 3.5 and 4.0 (which means both CLR 2.0 and 4.0). To complicate matters even further, we had a variety of 3rd party and open source software with a similar range of compilation environments, which included the.net 1.1 & 2.0 Frameworks as well.

 

VS2012 – You learn to love it

At first glance visual studio 2012’s new look wasn’t to my liking at all. The contrast looks wrong, everything is too bright and it’s hard to see where one panel ends and another begins. Thankfully I then installed VS2012 Update 3, and switched to the blue theme, which restored me into a nice familiar UI that I can work with.

After that initial roughness, I discovered vs2012 is one of the best IDEs I have worked with, far better than 2010, which, in my opinion, was sluggish compared to its Winform-Implemented predecessors.
VS2012 brings better performance, thus soothing several sore spots I have been complaining about for years:

  • Parallel C# compilation sped up most of my compilation processes by ~40%
  • Solution opening has become much faster, I can now open a solution without any sarcastic comments. (that is fast)
  • The compilation progress bar now shows the progress of the compilation (Hurray!). In previous versions, the progress bar was reset for each project in the solution, so no indication was given for the overall progress of the process.
  • A “reload all” button was added when multiple external changes occur in the solution (SVN update). Furthermore, the studio doesn’t crash when reloading (a big improvement compared to 2010).

C# Migration

As expected, the C# migration was not hard, but there were some glitches

  • Code conversion was conducted in a top to bottom order on the dependency tree, from the upper level UI down to the Infrastructure, since we can’t expect .Net 4.0 assemblies to depend on .Net 4.5 ones.
  • All CLR 2.0 & 1.1 assemblies were forced to run on CLR 4.0 by using the “supportedRuntime” flag in the executable configuration. This saved us from using multiple CLRs in one process, and from adding the .Net 3.5 Framework installation into our installation package. Until now, we have found no problems related to this usage, even though this came with a warning that in some special cases this may cause trouble.
  • We had an issue with static code analysis – apparently some of Microsoft’s analysis rules were changed and after installing vs2012, the compilation would have static code analysis problems, even when using vs2010. This was solved when installing Update 3, which goes to show the importance of using the latest version
  • Some problems were caused by parallel compilation, since our projects use DLL references to each other (to allow for flexibility when constructing solutions). However, the build order depends on defining project dependencies manually, and is sometimes lacking a ref here and there. To fix this I wrote a small program which exposes these issues by parsing the solution & csproj files (stay tune for my next blog entry)

C++ migration

C++ migration was much more difficult, but that is very understandable seeing that we had much older versions to convert. In addition, native code has more API changes since in managed code, such changes can be mitigated by some IL level magic. Here are several points about the conversion process:

  • Many 2010 projects converted seamlessly to 2012.
  • The 2005 vcproj files also had a smooth conversion to vcxproj files despite the difference in format.
  • The build environment had some small issues:
    • The Windows SDK location changed.
    • Some environment variables changed, and custom build steps + msbuild scripts had to be changed accordingly (i.e. redirected to use VS110COMNTOOLS and new windows SDK + tools paths)
  • C++ code conversion was a different matter, and the older the code the more changes it required in order to compile:
    • 2010 code compiled without conversion (but this is not a good sample as we had few projects in 2010).
    • 2005/2008 code needed some tweaking.
    • Most VC6 code needed a thorough reworking.
  • Several crashes surfaced while running the newly upgraded program - it seems that some BSTR optimization has changed in VC++ 11 and caused some bad code to act up. These issues were made more manageable by setting the environment variable OANOCACHE = 1, which disables BSTR caching so crashes occur near the source of the problem.

 

Here is a list of issues we encountered when converting the C++ code:

 

Migrated projects issues:

 

  1. incompatible pdb format:
    • fix: clean bin folder, delete PDB file
  2. fatal error C1189: #error :  MFC requires _WIN32_WINNT to be #defined to 0x0403 or greater. Recommended 0x0501. 
    • fix: set _WIN32_WINNT to 0x0502 in stdafx.h as it requested
  3. IntelliSense: cannot open source file "atlimpl.cpp" or "statreg.cpp" in StdAfx.cpp
    • fix: Remove "#include <atlimpl.cpp>" or "#include <statreg.cpp>" from StdAfx.cpp
  4. error C1083: Cannot open include file: 'winable.h'
    • fix: Change to include winuser.h
  5. std::make_pair error#* 
    • fix: Remove explicit type declaration in <>
  6. C2061: syntax error : identifier 'PSCROLLBARINFO'
    • fix: #define WINVER 0x0502 in stdafx.h
  7. C2039: 'NotifyWinEvent' : is not a member of '`global namespace''
    C2660: 'CWnd::NotifyWinEvent' : function does not take 4 arguments when set the _WIN32_WINNT to 0x05000#*
    • fix: #define WINVER 0x0500 in stdafx.h
  8.  The element 'PropertyGroup' in namespace 'http://schemas.microsoft.com/developer/msbuild/2003' has invalid child element 'ComputeLibInputsTargets'
    • fix: close all files in editor
  9. error RC2102: string literal too long\
    • fix: split the string... welcome better solutions
  10. error c1010001: Values of attribute "level" not equal in different manifest snippets\
    • fix: Check "UAC Execution Level" in Linker -> Manifest File, against that in *.manifest file, make sure they are equal; or remove .manifest
  11. warning C4627: '#include "RegObject.h"': skipped when looking for precompiled header
    • fix: include "StdAfx.h" in the first line of cpp
  12. mt.exe exited with code 31
    • fix: That's a bug in the manifest tool. use "mt.exe /manifest" instead of "mt.exe -manifest"
  13. error C1189: #error :  _SECURE_SCL_THROWS has been removed
    • fix: remove it from C/C++>Preprocessor>Preprocessor Definition
  14. warning LNK4075 ignoring 'EDITANDCONTINUE' due to '/SAFESEH'#* 
    • fix: Invcxproj Debug config, add <UseDebugLibraries>true</UseDebugLibraries>, then /SAFESEH disappears.
  15. When upgrading to VS2012, the settings of the MIDL Tool upgrade to Custom Build Tool with a midl command.
  16. Cannot open <winable.h>. 
    • fix: Replace with <winuser.h>
  17. C2061: syntax error : identifier CCM_SETWINDOWTHEME not declared## 
    • fix: change #define _WIN32_IE 0x0400 to #define _WIN32_IE 0x0500
  18. error MIDL2311: statements outside library block are illegal in mktyplib compatability mode : [ ]#* 
    • fix: Move #include statements inside library in IDL
  19. error C2065: 'TVIF_STATEEX' : undeclared identifier#* 
    • fix: #define _WIN32_IE 0x0600
  20. error MSB8008:Specified platform toolset (v110) is not installed or invalid:‎ 
    • fix: Call "set VisualStudioVersion=11.0" first
  21. g_pfnGetThreadACP not found in library:#*
    • Caused by a 2012 project, linking with a lib compiled with old VS like VS 05 08 etc.
    • fix: upgrade library to 2012
  22. error MSB8011: Failed to register output. Please try enabling Per-user Redirection or register the component from a command prompt with elevated permissions
    • fix: changed the Link->General->OutputFile "../../bin/DetailedVbsParserInterface.dll" to "..\..\bin\DetailedVbsParserInterface.dll"   (So strange)
  23. error MSB4184: The expression "[System.IO.Path]::Combine('', ../../Ifs/ExportTestWithResourcesUI.h)" cannot be evaluated. Illegal characters in path. C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\Microsoft.CppBuild.targets 409
    • fix : Select *.idl property. MIDL->Output->OutputDir = ../../Ifs/  and remove the ../../Ifs in other file path.
  24. Could not open <statreg.cpp> <altimpl.cpp>
    • In the VS2012, there is no statreg.cpp and atlimpl.cpp in \Microsoft Visual Studio 11.0\VC\atlmfc\include, But it exist in previous version of vs.  
    • fix: Remove #include <statreg.cpp> and #include <atlimpl.cpp>
  25. MIDL Error  unsatisfied forward interface declaration.
    • fix: Move the interface definition after the forward declaration.
  26. Interface in IDL not appear in generated TLB & assembly
    • fix: verify that the interface is dispinterface, if so remove interface prefix.
  27. In 2012 project, linker output of a project must be the target output, otherwise we get MSB8012
      • Reason: In the Build Event, $(TargetDir) $(TargetName) cannot be located to the right output file.
      • fix: Copy the file name of  the Link->General->OutputFile to the General->TargetName.
  28. error LNK1281: Unable to generate SAFESEH image. 
    • fix: Project Property -> Link -> Advanced -> Image Has Safe Exception Handlers  Select No(/SAFESEH:NO)
  29. In 2012 project, error LNK1181: cannot open input file 'rpcndr.lib' 
    • rpcndr.lib has been removed since VS2008.
    • remove the rpcndr.lib and link the rpcrt4.lib instead.
  30. In 2012 project, Error MSB8011: Failed to register output. Please try enabling Per-user Redirection or register the component from a command prompt with elevated permissions
    • Related warning MSB3073: The command "regsvr32 /s "../../bin/DetailedVbsParserInterface.dll"" exited with code 3. The return code means cannot find the module.
    • fix: changed the Link->General->OutputFile "../../bin/DetailedVbsParserInterface.dll" to "..\..\bin\DetailedVbsParserInterface.dll"

 

Old project issues (for project that needed to be kept in older VS vers)

    1. unresolved-external-symbol-report range check failure:
        • Issues with old version projects, which link against libs compiled with 2012
        • fix1: upgrade to 2012
        • fix2: in library project turn off GS Buffer Security Check. In VS 2012, Configuration->C/C++->Code Generation -> Security Check.
    2. 2010 projects:  “Source” parameter of the “MIDL” task. Multiple items cannot be passed into a parameter of type “Microsoft.Build.Framework.ITaskItem”
        • fix: Upgrade To VS2012.

 

A Special thanks goes to my teammates for creating this gorgeous issue & solution list that I think will help many of our readers, and also, for migrating the code:

Yun-Sheng Liu (Easton)

Shu Hui Fu (Kimi)

Qiu-Xia Zhang (Iris)

 

Summing Up the ride:

VS2012 is a solid IDE, and a huge improvement in performance and stability over 2010, I will never go back if I can help it…

C++ 11 and c# 4.5 have their own benefits, including WPF & TPL performance, new C++ optimizations and new language features which we will now be able to employ towards improving our software design and performance. When getting the first feel of the application after migration, I do get the notion that it is faster, though I reserve judgment on that until I have some concrete numbers to back me up.

About the migration – it was less harsh than what I imagined and most of the converted code works after conversion. As we saw here, the time it takes to migrate to a new platform depends on how up to date your code already is, so I recommend updating frequently.

 

Leave a Comment

We encourage you to share your comments on this post. Comments are moderated and will be reviewed
and posted as promptly as possible during regular business hours

To ensure your comment is published, be sure to follow the Community Guidelines.

Be sure to enter a unique name. You can't reuse a name that's already in use.
Be sure to enter a unique email address. You can't reuse an email address that's already in use.
Type the characters you see in the picture above.Type the words you hear.
Search
Showing results for 
Search instead for 
Do you mean 
About the Author
I've been all over the coding world since earning my degrees have worked several years in c++ and then several in java, finally setteling i...
Featured


Follow Us
The opinions expressed above are the personal opinions of the authors, not of HP. By using this site, you accept the Terms of Use and Rules of Participation.