Udostępnij za pośrednictwem


Q&A on adapting VS2005 SP1 to build your applications

 

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, https://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:

https://msdn2.microsoft.com/en-us/library/ms235460(VS.80).aspx

https://www.lenholgate.com/archives/000419.html

https://blogs.msdn.com/oldnewthing/archive/2006/09/15/755966.aspx

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.

Comments

  • Anonymous
    March 10, 2007
    One major problem with this - the SP1 does not update the merge modules with the latest ones so we can't ship applications without rewriting to use vcredist_*.exe Also I have users complaining that they can't install my COM objects because they fail to register - this also happens with regsvr32 applied directly to my DLLs. Which dependency walker throws up the following (after running the vcredist above) < Nikola: listing from log is removed to save space>

  • Anonymous
    March 12, 2007
    Hi, Thank you for the comment! VS2005 SP1 does update VC redistributable MSMs for all versions of VS. Please double check if VS2005 SP1 was able to completely install all files and perhaps re-install it. I had to remove listing of errors because it is just too long and because there are better places to get answers to resolve specific issue. Try re-posting your question about COM object registration on forums (http://forums.microsoft.com/msdn/ShowForum.aspx?ForumID=29) or newsgroups (http://msdn.microsoft.com/newsgroups/default.aspx?dg=microsoft.public.dotnet.languages.vc&lang=en&cr=US). Thanks, Nikola

  • Anonymous
    March 13, 2007
    I have previously posted a few items about deploying the Visual C++ 8.0 runtime redistributable packages

  • Anonymous
    March 29, 2007
    I am linking a library which is using the CRT from pre SP1 to my main code which is using the SP1 CRT. Before I started linking the pre SP1 CRT, I was just doing an applocal (copy CRT files in local folder) and everything was great. However, now I've got a DLL which relies on both SP1 and pre SP1 CRT.  It works fine on my development machine because I've got the right redirection policy.  How do I setup a redirection policy when distributing the dlls in a side-by-side mannor? Thanks, Dave http://dave.thehorners.com/

  • Anonymous
    March 29, 2007
    HI David, You cannot have a policy based redirection for private assemblies (applocal deployment). The recommended solution is to rebuild all code with SP1 libraries. It this is not possible, you may use .config file to redirect EXE to use one version of CRT library. This question come up several times by now. Let me put together a quick sample. I will try to have it on my blog later today. Nikola

  • Anonymous
    April 12, 2007
    Hi Nikola, I enjoyed speaking with you at the MVP Summit.   When you say, "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." I'm sorry, but this is a faulty assumption.  When SP1 is the only supported Visual Studio 2005 configuration on Vista, and contains vital stability fixes for the IDE, we as developers are forced to upgrade to it.  This does not mean we want to inconvenience our customers by forcing them to update to your latest redist. If you are going to force us to use SP1 for the dev env, you should update the dev env separately from the redist. On another note, you imply if both RTM and SP1 DLL's are both loaded, we can get the same types of problems as with static linking, since there are multiple runtimes in the same process, with all the incomatibilties this causes.  So what are you saying with that?  That even though we dynamically link to avoid the problems with static linking, we may still have to deal with these types of problems due to having separate runtimes loaded by the loader? Not to have too much cheese with my whine, but is all this pain really necessary?  The only reason I'm not blasting you harder is because I know you have it 10x as bad eating the dogfood, as it were.  :-) Thanks, David

  • Anonymous
    April 12, 2007
    > I mean otherwise why to build with version N if you are going to run against version N-1? Today I noticed that one more answer fits this question.  One reason is:  Version N-1 is builtin to Vista, but version N is needed in order to build on Vista. I want to solve that by cross-compiling.  I want to put VS2005 RTM + Vista SDK on a Windows XP machine and copy the resulting .exe and .dll files to a Vista machine for testing. But I'm afraid to try installing the Vista SDK on my Windows XP machine.  At present VS 6, 2003, and 2005 all working.  The SDK from year 2003 is installed in order to support VS 6.  If the Vista SDK breaks VS 6 then I probably have to repave the Windows XP machine.

  • Anonymous
    April 14, 2007
    Norman, I haven't tried but wouldn't think installing Vista SDK would interfere with the Feb2003 SDK for VC6.  VC6 would have the include/lib directory from Feb2003, and VS2005 would have it from Vista SDK.  Maybe binaries (tools and utilities) would have duplicates, but mostly I just use Include/Libs.

  • Anonymous
    April 24, 2007
    I previously wrote a blog post about updated versions of the Visual C++ 8.0 runtime files that shipped

  • Anonymous
    November 09, 2008
    The comment has been removed