When VS2005 SP1 has been released, because of manifests it become more visible what version of VC++ DLLs are used at runtime by applications built with SP1. Devs have noticed that once they have built their application with VS2005 SP1, it wants to load SP1 version of VC++ libraries and refuses to load RTM version of VC++ libraries.
I have been saving questions and answers related to this issue for past two months. And today I have decided to share the most common asked questions with my answers. Below I am listing questions followed by answers in no particular order. Several questions may be different ways of asking about the same issue and there is one answer for them.
But first, I would like to say thank you to all customers who helped me generating this list by providing their feedback and asking good questions in their emails and on phone conversations. And same time, I say thank you to anyone who may add questions and answers to this list in future edits.
Q: It looks like with VS2005 SP1 if a new version of VC++ libraries is installed, all apps start using it. Is this new policy for VS2005 SP1?
This is not a new policy to VS2005 SP1. In all previous versions of Visual Studio, both hotfix and SP releases of VC++ DLLs used to replace older versions of VC++ DLLs in place on developer’s computer. With new manifest based deployment model, the new version of libraries does not replace (remove) older version. Rather it is installed side-by-side as another version of the assembly. Same time a new version of assembly policy file is installed. It redirects applications from using old version of the library to the new version. In other words, approach is different because VC++ Dlls use new deployment model, but the goal is the same and it is to move all applications to use most up-to-date version of VC++ libraries.
Q: When my application is rebuilt with VS2005 SP1 it runs only when SP1 versions of VC++ are installed. Why does not it run when RTM versions of libraries are installed? Is this new policy for VS2005 SP1?
Running applications built with SP versions against RTM (SP-1) version of libraries is not supported scenario in other releases of Visual Studio. However it is more visible with the new manifest based deployment model because Windows loader checks SxS assembly version before loading DLLs and it refuses to load DLLs of different version. To go back to questions, this is not new policy to VS2005 SP1. It happened to work before because Windows Loader was not able to enforce it before and because two versions were binary compatible. The right approach is to always deploy versions of VC++ libraries your application is built with. I mean otherwise why to build with version N if you are going to run against version N-1? Just build with version N-1 and run using DLLs of that version.
Q. This behavior of VC++ libraries in VS2005 SP1 is it only specific to SP or is it going to be same in future releases of SP and hotfixes?
This is not a new policy to VS2005 SP1. In all previous versions of Visual Studio, VC team maintained binary backward compatibility in hotfix and SP releases of VC++ libraries. Applications that are built with RTM version of libraries may have some behavioral changes because of updates made in SP in response to issues reported by customers. However applications are expected to be able to load libraries at runtime and have not issues resolving calls to methods in VC++ libraries no matter if RTM or SP1 version of libraries are installed. The SP1 version of VC++ libraries should be treated as a complete replacement of the version of the libraries shipped in RTM and they should be used in both application development and runtime execution in an end-user environment. This is not changing for future hotfixes and service packs.
Q: Wasn’t the whole point of manifests to allow applications to specify the versions of VC++ libraries they want to load?
Actually the very first reason why VC is using manifest based deployment is that we can reliably use policy to redirect to the newest version of VC libraries. Martyn Lovell once had put together a nice post to his blog that explains reasons behind implementing WinSxS deployment model for VC libraries and what are the alternative solutions. You may find it here, http://blogs.msdn.com/martynl/archive/2005/10/13/480880.aspx.
We recommend updating all computers used in application development with SP1 and use SP1 in development and testing. Of course, this implies that you need to redistribute the VS2005 SP1 version of the Visual C++ redistributables that the application uses. You should be using same way of deployment VC++ libraries as if it was RTM version of libraries. If you were using MSMs, you should be using MSMs. If VCRedist.EXE, then use SP1 version of VCRedist.EXE.
Q: My application is using a DLL that is built with VS RTM. The application links against import library of that DLL and call exports of that DLL at runtime. Is this going to work with VS2005 SP1 and other SPs?
Q: My final product is a set of DLLs. If I release a version of my DLLs built with VS2005 SP1, can my users who use VS2005 RTM to use these libraries?
Because in SP releases VC avoids breaking binary compatibility from RTM version of libraries, loading DLLs built with VS2005 RTM into EXEs built with VS2005 SP1 works. Assuming that DLL is dynamically linked to CRT, they both are going to load SP1 version of CRT if such is installed in WinSxS folder. They may load different versions of both versions are redistributed as private assemblies (see xcopy deployment example), but it still works.
One additional note. It is not specific to VS2005 SP1 and important to understand. Designers of DLLs have to make sure that APIs exported from DLLs designed such that they obey rules of data type exchange and resource management across DLL boundary. There are several basic rules here that help avoid build errors or runtime AVs. The core issue here is that the loader and the loadee are going to load to different versions of CRT, MFC or any other VC libraries they depend on which may or may not be binary-compatible versions. Most frequently developers break two rules:
A) Data allocated in DLL has to be cleaned in DLL. Same for data allocated in EXE.
For example, when a code in DLL calls new or malloc the memory can only be freed by the code in DLL calling delete or free. If EXE calls delete or free, then the call is routed by CRT of version different from call to new or malloc. This usually results in memory corruption and AV.
B) Parameters and return value can only be Win32 and basic built-in types.
For example, an export like int MyExport(int nValue); is fine. However exports like FILE* MyExport2() or MyExport3(CWnd* myWnd) are not fine. The reason for this is that FILE and CWnd are CRT and MFC types and they depend on version of CRT or MFC. If two different versions of CRT are loaded, FILE in one version is not the same type as FILE in another version.
There are more details of issues around DLL boundaries discussed online. Here are some links I keep in my favorites on this topic:
One may search web and find more topics that discuss this. This is not new to VS2005 SP1, it has been like this in all previous versions of VC++.
Q: My application is linking to static library party is built with VS RTM. Is this going to work with VS2005 SP1 and other SPs?
Answer depends on how static library is built. In general this is not going to work. Static libraries make all consumers of these libraries to use same version of CRT as they use. Distributing your libraries as static libraries is usually a bad idea. It is possible to build static libraries such that they do not bring dependency on specific version of VC++ libraries using various #defines, however I just advise against using static libraries. This is not new to VS2005 and even before static libraries created build errors because their consumers use version of CRT different than they are.
Q: I am deploying CRT (same MFC or ATL) as private assemblies in application local folder. After I have rebuilt my code I have two reference in application manifest to RTM and SP1 versions of CRT (same for MFC or ATL). How can I deploy both versions in application local folder.
It is not possible to have two version of the same private assembly in appliction local folder. Your application has to use one version of CRT, MFC or ATL library. Most likely you want to use SP1 version of it. Two references in application manifest is a sign of a build error, meaning that not all parts of application are built with SP1 compiler, linker and libraries. There is one true solution to the problem. It is to rebuild all parts of your code with SP1 toolset. There are also short term workarounds that I am discussing in another post.
Q: I see VS2005 SP1 has installed SP1 version of VCRedist*.EXE. Should I send it to my customers and ask them to install it?
No, this is not required. If you have not rebuilt your application with SP1, you do not need to force your customers to install SP1 version of VCRedist*.EXE. Once you have built another update to your application using SP1 version of VC++ libraries, you may ask your customer to install SP1 version of VCRedist.EXE before installing new update of your application on their computer.
Q: I am using MSMs to redistribute RTM versions of VC++ libraries. Should I sent SP1 version of VCRedist.EXE to my customers and ask them to install it?
No, you should not. Once you have built another update to your application using SP1 version of VC++ libraries, use SP1 version of VC++ MSMs to build and update MSI to your application and ask your customer to install it. You only should be using SP1 version of VCRedist.EXE if you have used RTM version of VCRedist to redistribute VC++ libraries on end-user’s computer. If you have been using MSMs, continue using MSMs when building an update to your application based on VS2005 SP1.
These are answers to most common questions asked so far. If I come across another question, I am going to add it to this list with an answer.