怎么介绍?
分类:
2008-11-24 14:53:19
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 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:
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.
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
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.
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.
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.
Ben Anderson
Visual C++ Libraries Team