How to redistribute the Visual C++ Libraries with your application

How to redistribute the Visual C++ Libraries with your application

  • Comments 51

Hello again, this is Ben Anderson, SDET on the Visual C++ libraries team. 

One of the most common questions we get from customers on the forums and elsewhere is “My app needs the Visual C++ Libraries (CRT, ATL, MFC, OpenMP or some combination thereof) – how do I get them on my customers’ machines?”  It’s also something we see in the wild done, if not incorrectly, at least non-optimally fairly frequently.  The help documentation in MSDN is correct, but there is no one stop-shopping explanation of all your options.  This blog post will attempt to explain what to do. (In case you’re looking for the short answer, almost always, the correct thing to do to distribute the Visual C++ libraries is to add the Visual C++ redistributable MSMs, or “Merge Modules”, for the libraries you use to your application’s setup.) I’ve tried to outline below the various methods of redistributing the Visual C++ library DLLs based on what your deployment story may be.

 In most cases, folks deploy their applications using a standard Windows setup.  In these cases, you probably build an .msi file using some toolset (such as a Visual Studio setup project) which is then wrapped in an .exe file by your tool chain.  End users run this .exe file and your application is installed.  If you don’t already have a setup for your application, it’s very easy to create one using Visual Studio’s setup project (found by right clicking your solution, clicking Add -> New Project… -> Other Project Types -> Setup Project).  You can then right click your setup project, click “Add->Project Output…”, then select Primary Output.  You can then add Start Menu items and tweak your setup to meet your needs.

In order to redistribute the Visual C++ libraries, all you need to do is include the appropriate .MSM file and its accompanying policy .MSM to distribute the library you need.  If you are creating a setup project as part of your solution as described above, Visual Studio will attempt to detect which libraries you depend on and will add MSMs as appropriate.  If you are creating your setup project with another tool, or not using the “Add project output” option, you will have to manually add the MSMs for any libraries you need.  These libraries are found in “%ProgramFiles(x86)%\Common Files\Merge Modules”.  For example, on my VS 2005 SP1 system, if I had an x86 MFC App, I would add the following files as Merge Modules to my setup project:

  1. “C:\Program Files (x86)\Common Files\Merge Modules\Microsoft_VC80_CRT_x86.msm”
  2. “C:\Program Files (x86)\Common Files\Merge Modules\Microsoft_VC80_MFC_x86.msm”
  3. “C:\Program Files (x86)\Common Files\Merge Modules\policy_8_0_Microsoft_VC80_CRT_x86.msm”,
    and
     
  4. “C:\Program Files (x86)\Common Files\Merge Modules\policy_8_0_Microsoft_VC80_MFC_x86.msm”

These files are then consumed by your setup tool, and their contents are dropped as part of your MSI on your users’ systems.  They contain components which install to Windows Side by Side the DLLs and the redirection policies [see footnote 1] for the libraries you select.  These components are ref counted so that every time an app using these MSMs installs, the ref count is incremented, and every time one of these apps uninstalls it is decremented.  Once the ref count hits zero, the DLLs and policy are uninstalled. 

 There are a few cases in which MSM installation may not work for you.  In one case, you may have to deploy your app on systems where the user has no administrator privileges and so cannot run a setup.  There may also be some other reason you cannot use an MSI to install your application – for instance, users may run your binaries directly from a network share. 

In these cases, you can do an “app-local” deployment, which is sometimes called deploying the DLLs as “private assemblies”.  All you need to do in this case is provide a copy of the DLLs you need, and their accompanying manifest in the same directory as every .exe, .dll or .ocx file in your application.  To deploy in this way, simply copy the entire contents of the appropriate folder under <Visual Studio install dir>\VC\redist [see footnote 2] into the all folders which contain binaries which use those libraries. 

The advantage of this approach is that you do not need to create an install for your application.  This means you can deploy and run without requiring your users to elevate to administrator privileges.  All your users need to do is copy your application folder onto their systems or run your .exe directly from its current location.  The disadvantage is that you must put a separate copy of the libraries you need in every single directory in which your binaries reside.  For a simple application, this may not be a problem, but for a large app which might have many subdirectories with many tools and DLLs, this is a lot of file duplication. 

 Finally, there is one additional scenario for redistributing the Visual C++ libraries DLLs.  This scenario is if you are using “Click Once” deployment.  In this case, “Click Once” will use a custom built installer package called “VCRedist_<arch>.exe” to install the libraries for you.  DO NOT use the VCRedist_<arch>.exe installer packages for any other purpose. 

The VCRedist packages are simply MSI’s built by consuming all the MSMs from “%ProgramFiles(x86)%\Common Files\Merge Modules” as well as the MSDIA DLL (used for debugging).  However, MSIs are not ref counted like the components in the MSMs, so if you install it, you can never uninstall it because you do not know who else might be using it in addition to your app.  Further, your users cannot uninstall it because they do not know which of their applications may be using it.  Additionally, your users may not realize what it is when they see the entry in Add/Remove program files.  Imagine a user trying to free up space on their machine, seeing the entry for VCRedist which they do not recognize, uninstalling it, then some time later (maybe months), trying your application again.  It will not work!  Your user will probably not connect the action of uninstalling VCRedist at some point in the past, and will either be broken without a fix, or use your support center’s time trying to find out why your app stopped working.  What’s more, it’s very likely that you are not using every single Visual C++ library, and installing the whole of VCRedist is unnecessary.  Alternately, a poorly written installer for another application which used VCRedist to redistribute the Visual C++ libraries may (incorrectly) uninstall VCRedist when that app uninstalls. 

A better option if for some reason you cannot incorporate the MSMs into an MSI which installs your application is to use Visual Studio or another tool to build a tiny MSI installing just the MSMs, and only those that you require.  Since this MSI is unique to your product, and can be named whatever you like, you can uninstall it when your application is removed, and you can name it in such a way that your user recognizes it as part of your application and will not uninstall it inappropriately (name it say “MyApp Prerequisites).  By using your own MSI, you also guarantee that no other application which uses the VCRedist package will interfere with your app by incorrectly uninstalling it during that app’s uninstallation.

Again, just to emphasize – do not use VCRedist*.exe unless you are using Click Once to deploy your application.

 In addition to all the methods described above of distributing the Visual C++ libraries DLLs, there is one last option for building your application which does not require you to distribute the DLLs.  However, this option only works for native-only code (it is not supported with /clr) and leaves your customers seriously vulnerable to any security holes as well as adds a significant burden upon yourself to patch all customer systems should a vulnerability be found in any of the libraries.  This option is to statically link in the libraries as .lib files instead of dynamically loading them as DLLs.  You do this by using the /MT flag on the cl.exe command line (vs /MD), or selecting the appropriate option in your project properties through Visual Studio.  You may wish to use this option when testing early debug builds of your application on test machines before you start working on setup. [See footnote 3] 

However, I can think of no scenarios in which this is actually the right thing to do when shipping your product to customers.  Basically, what this approach does is pulls in the binary code needed from .LIB files at compile time, making it a part of your .exe or .dll files.  It increases the size of your application, and there is no way to update the libraries apart from recompiling your application with new .LIBs and redistributing your application all over again.  What this means is that unless you go touch every single machine which has installed your application every time there is a security vulnerability found in the Visual C++ libraries and completely reinstall your updated binaries, you will be leaving your customers vulnerable to attack.  If instead you use the DLLs, every time there is a security vulnerability found in the Visual C++ libraries, Microsoft will install the update centrally into the WinSxS folder via Windows Update and all requests for the DLLs will be redirected to the updated version.  This removes all servicing burden on your side and also allows the user to install one small update which will touch all their applications instead of replacing every installed exe and DLL on their system.  Please, do not distribute an application built by linking statically against the Visual C++ libraries unless you have a system in place for updating every customer machine and also have a very good reason to do so.  At this time, I can think of no circumstance under which this would be the right thing to do for a shipping application.

 Well, hopefully this article has helped you out in understanding how to redistribute the Visual C++ libraries onto your customer’s machines.  If you have additional questions, you can find the documentation for deploying Visual C++ built applications here:

http://msdn2.microsoft.com/en-us/library/zebw5zk9(VS.80).aspx

 If you still have questions, you can post comments here (I will check back for a few weeks), or you can post your question in the Visual C++ forums here:

http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=29&SiteID=1

 Thanks,
Ben Anderson
Visual C++ Libraries Team


[1] The redirection policy always redirects requests for the Visual C++ dlls to the latest installed versions, even if the application requesting the dlls has used “app local” deployment to drop the dlls as private assemblies – this way, if a security issue comes along, Windows Update can drop fixed dlls into Windows SxS and all affected applications will be fixed.  The Visual C++ team maintains a strong binary compatibility guarantee that applications built against an earlier version of the library will work against all later versions with few exceptions (exploitable usage may be broken to prevent customer machines from being hacked).

[2] Please note that the files in this directory are not updated in QFE patches, and some of the manifest files in this directory were not updated as part of SP1 of Visual Studio 2005.  As a workaround, you can find the appropriate version of the files in the WinSxS directory of your Visual Studio development box by typing “c:\windows\winsxs> dir *VC80*”, identifying the correct directory based on version numbers, then copying the contents of that directory into your application directories instead.

[3] A better option would be to create a simple setup project and include all the Visual C++ MSMs and install this on all your target machines. 

  • I have a similar situation to Tom Robinson. I maintain an ISAPI extension, and upgrading our toolset is going to cause us a significant amount of work one way or another - unless I switch to statically linking.

    With isapi's, you don't typically have a single 'app directory', so the 'app local' solution is pretty distasteful.

    I was experimenting with manifests - hit the issue that (in my build environment at least) it seems to insist on embedding a reference to 8.0.50727.762, even if I already have one for .42. But from this discussion it sounds like it's not worth trying to track this down. Static linking it is...

    I've appreciated the heated but informed discussion on this thread. But it still seems pretty ironic to me that you can now write a stand-alone C# .exe that doesn't need its run-time redisted, but the same is no longer true of C++.

  • In my case I want to minimize download size.  Since the application is made of separate DLLs, static linking is not an option.  I'd love to distribute the Visual C++ MSMs, but there are two problems:

    - The base MSM includes the .net interop DLL that I don't need.  If I install applocal I can opt out of it, and just copy the C and C++ DLLs.

    - Since the MSM installs the DLLs in several places (three, IIRC), it includes the DLL three times.  This is increases the size of the installer unnecesarily.  Can you fix this?

  • Tom,

    Please, correct me if I misunderstood your scenarios...

    The general scenario is:

    What happens for languages that support loading a library dynamically without knowledge about fusion - how do we get them to work?

    One solution is to have those languages/tools support loading dlls through fusion (by creating an activation context, etc).

    Another solution is to wrap the necessary functionality in another dlls that has a manifest and have the language/tool call that dll (which doesn't require fusion).

    I am not sure how much the user would want exposed from a fusionized dll (CRT for example) - so, if needs broad access, the wrapper solution will be pretty clumsy.

    Luckily, most CRT functions are exposed natively in scripting languages - so, I guess the surface to expose shouldn't be large.

    Regarding the ISAPI scenario...

    My previous comments apply to that scenario.

    However, I'm thinking that EYESAPI does not actually have to support loading the CRT - since the CRT is not an ISAPI extention...

    thanks,

    George Mileka

  • Andrew,

    Could you please explain why you're not using central deployment for your ISAPI scenario?

    The embedded reference to 762 is coming from crtassem.h which got installed with SP1.

    Regarding the ability to avoid redistributing the VC dlls - well, it sounds like statically  linking with the VC libs...

    For example, when C# produce a standalone binary, how do they handle patches to their managed libraries?

    thanks,

    George Mileka

    Visual C++ Libraries

  • George,

    My problem is not with the Visual C++ library itself.  I don't have a problem with building the ISAPI extension dll with a manifest.  The problem I have is that I want to use a testing tool that's several years old (that I don't have source for) to test problems I'm having with my ISAPI extension.

    You can reproduce this problem simply.  Search of EYESAPI and download the executable.  Compile the Simple sample ISAPI extension from the Windows Server 2004 R2 PSDK and try to load the Simple ISAPI dll by typing Simple.dll into the EYESAPI UI and pressing the Load button.  Even if you have a Simple dll manifest that says that Simple requires the CRT, the DLL won't load. I might be able to create a manifest for EYESAPI that says that it requires Simple.dll - but that would mean that I have to edit the manifest every time I want to use EYESAPI to test a different ISAPI extension.  Do you see what I mean?

  • Hi Tom,

    Thanks for the details, for some reason I can not repro the problem.

    Here is what I did on a machine with VS installed:

    1. Install IIS (I think this is not required though).

    2. Install the PSDK from http://www.microsoft.com/downloads/details.aspx?FamilyId=A55B6B43-E24F-4EA3-A93E-40C0EC4F68E5&displaylang=en

    3. Open <PSDK dir>\Samples\Web\iis\isapi_6.0\HelloIsapi in VS and accept all the project conversion defaults.

    4. Change the project settings to dynamically link to the CRT.

    5. Build the dll.

    6. Download EYESAPI from http://www.genusa.com/isapi/eyesapi.html, unzip and run the exe.

    7. Make sure EYESAPI successfully loads the HelloIsapi.dll.

    8. Open the HelloIsapi.dll in DevEnv, and change the manifest resource to require a bogus version of the CRT. Save it.

    9. Make sure EYESAPI fails to load HelloIsapi.dll.

    10. Copy the CRT dlls + manifest to the same folder where HelloIsapi.dll is. Change the manifest to indicate that it is the bogus version I set earlier in the dll.

    11. Make sure EYESAPI successfully loads HelloIsapi.dll.

    So, I'm afraid I still don't see why it is not working for you...

    Note that as long as the ISAPI dll has a manifest, that is all you need. Users of the dlls (EYESAPI in this case) never have to have a manifest to indicate the dll dependencies.

    When it fails to load, do you see any relevant entries in the event log?

    If not, could you run the repro under Vista and use sxstrace.exe to get more information?

    For applocal scenario, could you verify that the CRT version requested in the ISAPI dll manifest is the same as that in the CRT manifest in the same folder?

    Let me know how this goes... I'll be glad to help.

    George Mileka

    VC++ Libraries Team

    This posting is provided "AS IS" with no warranties, and confers no rights.

  • George,

    Thanks for your response.  I will follow your instructions and see what I get.  Please note:  the version of the PSDK I am using is March 2006, not the April 2005 referenced in your instructions.

  • The SxS idea is good, but it's making really much trouble.

    My programs are always deployed with XCOPY. In fact, most of the times, it's deployed with a single executable file. I think it's not a nice job to describle what a DLL file is, don't you think so? But with the MSVC*.dll the program's impossible to be deployed with a single EXE. The only thing i can do is static linking...

    In fact, most of the computers we can see here have the system drive "locked" and the system drive's content is restored each time the computer starts... That's why the public assemblies or installers are never considered...

    I wonder if you can allow us to use the MSVCRT.dll in the system when we want to in future VC++ versions? Or you can make a special version of CRT which can install itself into the SxS directory?It will really save us from this big trouble.

    And you can't, it's also not a bad idea to put CRT libraries in Windows Update...That will make things a little easier!

  • Hi Charles, thanks for your comment.  Unfortunately the msvcrt.dll is maintained by Windows and is not available for public usage by current toolsets.  I don't think that will change.  I wonder if you could explain more by your request that we "make a special version of CRT which can install itself into the SxS directory".  That is what we do with the MSMs and VCRedist*.exe.  In your case where youre systems are managed, maybe you could have a custom setup install the libraries you need into WinSxS on your base images?  Then your future deployments would not need to redist the libraries since they would already be present centrally.  

    Anyway, maybe that is not exactly what you're asking, so if not, let us know and maybe we can figure something out for you.

    Thanks,

    Ben

  • You state that a major reason for not statically-linking to the CRTs is so that a newer, security-fixed version of the CRT can be used instead of the one shipped with your application, and you won't need to ship security updates for your application. But how is this newer, security-fixed version getting on to your users' computers?

    If I am the one who had to install the CRT DLLs in the first place, why is it safe for me to assume I don't need to be the one to install a newer version of the CRT DLLs if a security flaw is fixed?

    I suppose you could provide an updated version of the CRT through Windows Update, but you state that even applocal copies of the CRT will benefit from updated versions of the CRT. So WU seems unlikely, unless you're really going to be willing to force an install of the CRT onto all WU clients, regardless of whether there is a previous version in the system assembly. So should VC developers be crossing their fingers and hoping for a major security flaw to come along and remove the need to redistribute the CRT entirely? :)

    Even if a security update is added to WU, that is only going to cover <i>most</i> of your users, not all of them so if you redistribute the CRT along with your program, you're going to need to distribute updated versions of the CRT as security fixes for your program, if you want to be a responsible developer. And I don't see any advantage in sending out an entirely new version of the CRT instead of a patched version of a statically-linked executable.

    That's not to say I don't see any advantages to using a DLL, but claiming that it will prevent you from having to provide security updates seems untrue. A better way to state the security advantage would be: if you are willing to distribute your application through an MSM-supporting setup process, or if you are willing to add 2-3MB and 4-6 files to your installed directory, using a dynamically-linked version of the CRT will still allow your customers to apply security fixes (if they are aware of them) to the CRT parts of a program if you ever go out of business or stop supporting that program/version.

  • Ben, you state that you've worked on at least one security fix to the CRT since RTM. Does this mean that every computer that doesn't have the SP1 version of the VS2005 CRT in the system assembly is an example of a computer where a program using an applocal install would have required the program's author to provide a security update for the CRT?

  • Ben,

    Has anyone successfully used "app-local" deployment for a 64-bit application running on "Windows XP Professional x64 edition"?  Note that my entire app is built using Visual Studio 2005 SP1. I've been trying, but my app just crashes on start-up.

    If I instead run the 2005 SP1 version of vcredist_x64.exe to install the runtime, then my app will start-up and run just fine.  I'd really like to do "app-local" deployment because I don't want to require admin privileges to install my application (which rules out merge modules and vcredist_*).

    Note that I can get "app-local" deployment working for the 32-bit version of app, whether it's installed on Windows XP or Windows XP x64 edition.

  • Hi Ben,

    Why can't we just use the original MSVCRT.dll? In fact, when i rebuild my application with other compilers GCC/MingGW the program will use MSVCRT.dll. Anyway, I prefer MSVC since almost everything is better. But I remember VC6 Applications will link to MSVCRT.dll, right?

    Could you UNOFFICIALLY tell me the way to configure my VC05 to link with MSVCRT.dll? I know i'll need the file msvcrt.lib in VC6. Could you tell me the step-by-step process to configure my linker?

    Yes. I know VCRedist*.exe can install the runtime libraries. But that will be two files, one is the program and the other is a strange thing:) What's worse, it adds the non-localized name "Visual C++ 2005 Redist..." in Add/Remove Programs in the Control Panel. I can't expect user have that in the computer for a long time.

    And I can't even write a unpacker which runs the VCRedist*.exe automatically because the unpacker written with VC8 will need MSVC?80.DLL,too!

    Installer is even worse. Because using this method means that i will need to reinstall it each time i use the program...Because when the user reboot the machine, there's nothing in the WinSXS folder...

    That's what the "special version of CRT" is for. When the "loader" starts up, it can install the CRT library automatically, maybe download it from the web, maybe unzip it from a cabinet file, or things like that, and copy itself into the WinSXS cache(To me, it is a cache folder). We don't a prompt saying "The configure of the application is incorrect."(I've never seen the English version of this prompt, but it's certainly something like that.)

    Base images? Come on, I'm not selling business solutions(like Microsoft does). I'm offering them free tools:)

    Private assemblies should also be improved. The manifest's name is so long that it looks really strange. And creating a folder with the assembly name to contain it will cause the application be unusable under Windows 2K.

    By the way, i'll tell you a story, though it's not related to your job, it's really fun to hear this. It's about user experience, though. I'm still using VS05 SP0 now. Do you know why? Once upon a time i tried to install SP1. The setup process is very very long. So very long did i wait. Guess what? After seven whole hours' waiting, there's a prompt saying i don't have enough free space:-(

    What's worse, i knew exactly that after the installer would soon free up some space after the installation...

    To us, why we use unmanaged VC++ instead of managed code? Compared with managed code under the help of RAD tools, unmanaged code's cost is extremely high. It's just because unmanaged code is smaller in size,faster in execution, able to control the code logic freely and easier to deploy. It's not so pleasing to see that all these are changing...Vista has the .netFX shipped, and i believe after further integration managed code will be running faster. It's hard to imagine what the VC's future will be like.

    I'm speaking these just for VC10. To me, CRT issue is not very serious since i'll continue static linking the CRT for small apps and i'll make installers for bigger applications. I know VC9 is coming. Good to hear that, though my computer is too old to use the new IDE. When there's VC10 i'll be using my new computer:)

    By the way, something about VC++ library. Could make us a Microsoft Specific TCHAR string class in CRT? The STL string handles only char(s) and wstring handles only wchar_t(s). And the convertng APIs are in SDK... Could you wrap them or reinvent them to get us a new CString without ATL or MFC support?(maybe we can call this class tstring)?

    And something more important, i hope one day unmanaged code will have optional XAML support!

    Thank you for taking so much time reading!

    Charles

  • George,

    Thanks for your detailed response above.  I followed your instructions down to step 10.  I can't seem to change the right things about the manifest to indicate that it is my bogus version.  Can you explain exactly what you did here?

    Thanks,

    Tom

    By the way, my customer is migrating to .Net, but the application I support will be in use for at least another year.  I have friends in other large companies that are in similar situations.  The explanation that you gave above provides how-to information not available elsewhere.  Any possibility of a KB article or something similar for those of us supporting pieces of old applications?  Thanks again.

  • Hi,

    I have found very good information from this blog.Thank you very much you all.

    But I have one quetion and also problem which is related to this blog topic redistributing the library.

    I have created Visual Studio’s setup project in which I have added Activex (.ocx) control in it and also I have included appropriate .MSM file and its accompanying policy .MSM to distribute the library.

    My package is created successfully(in VS 2005).

    And I try to install it on the different machine(without VS 2005) but ask for the installing .Net Framework 2.0 but I did not install it and try to install other setup file(which also created with our main setup file) and it perfactly installed.

    And now What I have to do to use that Activex (.ocx) control directly in other application.

    May I directly register it using REGSVR32.exe or any other setting I have to do?

    Please suggest me if you can. It will be very helpful to me.

    Thanks.

Page 3 of 4 (51 items) 1234