Welcome to MSDN Blogs Sign in | Join | Help

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

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. 

Published Friday, October 12, 2007 2:33 PM by vcblog
Filed under:

Comments

Sunday, October 14, 2007 12:39 AM by Joe

# re: How to redistribute the Visual C++ Libraries with your application

<i>At this time, I can think of no circumstance under which this would be the right thing to do for a shipping application.</i>

How about:

1) historically, Microsoft has completely screwed up versioning, installing and patching the CRT and MFC DLLs.

2) Microsoft does not include the MFC, CRT and associated DLLs with service packs and, to my knowledge, has never updated them through Windows Update.

3) The DLL install package is huge. Do you really suggest that I should ship a 2 MB package so a 90k executable will run? Are you out of your mind?

Seriously, you comment illustrates absolute ignorance of the reality of distributing commercial executables to customers and in supporting those customers, especially in light of Microsoft's history of awful support for the MFC and CRT DLLs and the bloat of these libraries.

Sunday, October 14, 2007 8:09 PM by Phaeron

# re: How to redistribute the Visual C++ Libraries with your application

Agreed. Another circumstance I'd like to add: you must statically link if your program must run as a stand-alone .exe. There are many circumstances in which this is required, such as if your program has no setup module and users are likely to just run it out of a .zip archive. Would you dynamically link a stub for an installer? That would be stupid.

You say that dynamic linking allows for DLL servicing. Are you aware of the testing load that this incurs? If you were to find a problem that you wanted to fix in the CRT, you would have to test ALL versions of the CRT you were updating against ALL programs using them. The DirectX team went down this path with the D3DX DLL, and they are now up to at least 12 versions of D3DX_*.DLL. Hotfixing and testing an update for a flaw in all of those versions is a huge task, and it turns into a nightmare for vendors if the DLL breaks a program, because it becomes one more moving part in the system. The main effect so far of the D3DX DLL scheme has been a big installation headache, and this is true for the DLL versions of the VC8 CRTs as well.

My rule for avoiding distribution and servicing headaches in third party components is, for the most part, to simply avoid using them. That isn't really an option for the CRT, so I statically link it. I have no plans to change this any time soon.

Monday, October 15, 2007 9:42 AM by Jalf

# re: How to redistribute the Visual C++ Libraries with your application

As hinted above, static linking does *not* increase file size. It makes your .exe slightly bigger, yes (but only adds the bits that you actually use), but it saves you from having to distribute the full CRT/MFC/whatever DLL's, which are much bigger than the slight increase in file size you get with static linking. That's one argument down.

As for the security thing, true, but:

1: How often are security vulnerabilities found/patched in the CRT?

2: How is static linking different from an app-local deployment, where you get (multiple copies of) the same dll's, but in the app's folders where a general windows update won't be able to reach them?

And of course, there's 3:

It just works. (and you know it'll keep working, because you, the developer, controls when/if your code gets updated)

Distributing dll's doesn't, as your post shows. There's too many hoops to jump through, too many gotchas, and too little benefit.

It would be really nice if Microsoft recognized this. I'm not opposed to dynamic linking (seems to work fairly well on Linux), but when it's done as awkwardly as this, static linking is just a better alternative.

Monday, October 15, 2007 1:37 PM by Stephan T. Lavavej [MSFT]

# re: How to redistribute the Visual C++ Libraries with your application

I love static linking, but it seems like I'm the only person at Microsoft who does.

Yes, if a security flaw were patched in the CRT or separately compiled Standard C++ Library, you would have to ship your binaries again if you statically linked them. But no matter what, if a security flaw were patched in the header-only part of the Standard C++ Library, you'd also have to ship your binaries again.  Same thing for any other libraries you use that are statically linked (e.g. zlib, bzip2, Boost.Regex) or header-only (e.g. other parts of Boost).  And if a security flaw is patched in your own code, you definitely have to ship your binaries again.

Result: Any application with security exposure (which is almost all of them) needs to be serviceable. Statically linking the CRT/etc. increases the number of scenarios in which you will have to ship your binaries again from "many" to "many plus one". It does not increase it from zero to nonzero.

As I said, though, I haven't been able to convince anyone else at Microsoft with this argument. Officially, statically linking the CRT is severely frowned upon (as Ben makes clear).

Jalf: Proper app-local deployment of the CRT DLLs *does* permit Windows Update to service them (basically, it checks for patched copies before loading the app-local DLLs).

Stephan "/MT" Lavavej

Visual C++ Libraries Developer

Monday, October 15, 2007 5:01 PM by Ben Anderson (MSFT)

# re: How to redistribute the Visual C++ Libraries with your application

There seem to be a few misunderstandings regarding the details of how this process works.  I'll try to hit all of them, but I might miss some, so be patient.

In no particular order:

Phaeron - in the case you mention, in your first paragraph, having a standalone exe with no installer, the correct thing to do is to package the CRT DLLs app-local - no need to install and in the case of a security event you will be redirected to the patched version by WinSxS.

With regards to maintaining multiple versions of the DLL, the VC servicing policy is different than what you describe for DirectX.  VC has an extremely strong commitment to binary compatibility within a VS version.  What this means is that if you build with our RTM bits, every subsequent version of that VS is guaranteed to be compatible with your app.  So any version of MSVCR80.dll greater than or equal to the version your app was built will work with your app.  If not, this is a bug and we will fix it for you and/or pull the update.  The only scenario I can envision a binary breaking change would be if there is an exploitable use case where not breaking the case would result in customers boxes getting owned.  In that case there might be justification to break that API (have it gracefully fail) to ensure that end user boxes are not compromised.  

In your scenario, I strongly recommend you change your stance towards statically linking the CRT.  I believe your choice was made based on mistaken assumptions.  I cannot envision any scenario that would give you a headache by dynamically linking and I can envision a scenario where you would be significantly inconvenienced by statically linking - a security event along the lines of the GDIPlus vulnerability from a few years back described here: http://www.microsoft.com/technet/security/bulletin/MS04-028.mspx.  Without WinSxS the only way to fix this was to scan the machine for copies of the dll and update each one.  Now with WinSxS, a single central copy with accompanying policy can redirect all DLL requests to a patched version.  However, if you are statically linking, you will have to handle servicing all your customers yourself.

Jalf:

Regarding point 2 - when you deploy app-local, even though you have a local copy of the DLL, when your DLL is loaded, if there exists a policy in WinSxS to redirect requests for the version of the DLL you are trying to load to a centralized version, your app will load the updated version.  This is the main benefit VC derives from using fusionized (WinSxS) DLLs.  We can service every user of the DLLs centrally even if they are deployed app-local.  It also guarantees, rogue DLLs named msvcr80.dll should not get loaded by an app loading the CRT dynamically by building /MD.

In question 1 you ask how often security vulnerabilities are found and patched in the CRT.  I don't have the numbers in front of me, but I can think of one case since VS2005 RTM that I was involved in (thankfully it was never exploited).  It is true that since the Secure CRT functions were added we've had significantly fewer vulnerabilities than in previous product versions, however this is no guarantee.  It only takes one really nasty vulnerability like the GDIPlus one from a few years back to cause a huge headache both for end users and ISVs.  

I would also dispute your assertion that distributing DLLs does not work.  In nearly every mainstream scenario DLLs are both easy and untroublesome.  If there is some scenario you think we need to address to make things easier let us know.  We recognize that guidance on using the new fusionized redist mechanisms was not very good coming out of the gate for VS2005.  We're working hard to improve that story as we hear from you guys what the pain points are.

Joe:

I saved your post for last because I don't believe you have any misconceptions about how things work to clarify.  I think you and I just disagree about the cost/benefit of things.  

Let's start with the size issue you mention.  There are two sides to the size story - size of what you have to ship and size once your app is installed on end user systems.  Let's analyze making that distinction.

In your example I'm assuming all you have to ship is a single 90k executable (which is pretty small by statically linked size standards - by just using printf and cout I get a 122k exe /MT which is 7k /MD - but really, we're talking about a 0.1 meg difference so no biggy).  I'm also assuming you're dependent only on the CRT and possibly also the SCL (the C-runtime and Standard C++ libs).  In this case, assuming you don't want to add anything to the start menu and that sort of thing, it's probably reasonable to ship installer-less as just a zip file including the MSVCR80.dll (CRT) and MSVCP80.dll (SCL).  This adds about 1 MB to what ends up on your user's drive, and assuming you zip your app and 400k to what you have to ship (459KB vs 59KB in my little dummy app).  In this dummy app scenario, the CRT dlls do dominate, but in most serious applications, if you have a gui or anything along those lines and accompanying resources and artwork, this scenario will be reversed.  In my mind 400k to ship and 1MB on my users machines is worth not having to service in the case of a CRT issue.  

Now, let's assume you have an installer and you use the merge modules to redist.  I think in this case you might get a little bigger - say about 2 MB total to ship your app and the consume CRT MSMs into an installer.  So you're now shipping a little more.  However, what ends up on your end user's machine in most circumstances is less.  Since many, many apps use the CRT, it's almost guaranteed to be on your users system already - I believe IE7, Office 2007, Windows Vista all ship the 8.0 CRT.  Since the MSMs will simply bump a ref count and not drop anything additional on your users' systems in this case, your user will actually be saving about 100KB of space vs what they would if you shipped statically.  

So really, the size argument comes down to whether you are sweating having to redist about 1MB in addition to what you otherwise would have to.  I would argue that in most large applications, you'd actually be saving space shipping the MSMs when you have a number of binaries you are shipping to link dynamically.  But even in a small app, where this isn't the case, are you going to want to service your users in the event of a security issue?  Is the saved cost in a 1MB smaller shipping vehicle worth the cost of harming your customers and having to service them yourself?  If size is the only argument, I would have to say that in my mind the answer is a resounding No!

I believe your other argument is that historically, CRT and MFC versioning has been screwed up.  I'm not sure exactly what you're referencing, but it is true that back in the 90s some companies had issues.  One annecdote I was told by a coworker was that back when VC6 shipped, which I think was before we started renaming the dlls with each version, we shipped a new msvcrt.dll which had a vastly improved memory allocation scheme which was much better at reusing freed memory.  At the time a lot of vendors had double-free bugs which most of the time did not repro because on the second free, the memory had not been reused yet, but when 6.0 hit and was shipped, their apps started crashing when they hit their double free bugs after the memory had been reused.  This clearly was a bad situation.  The vendors did have bugs and all that really happened was that their apps were crashing more frequently than they were before, but since the CRT was dropped on them from elsewhere, they didn't have the opportunity to test their apps against the new CRT before they got hit by the new bits.  This was bad.

However, we've learned a lot since the 90s and are constantly trying to make things better for you guys.  Starting with 70, we started renaming our DLLs every version and maintaining strong binary compatibility commitments within a version.  With 80 we've gone with WinSxS which allows us even closer control.  If you have an issue, please tell us, and if there's any way we could behave better please tell us that too.  

We're a company that ships a lot of software from huge projects like Office to tiny utilities.  If you've hit a pain point, we probably have too since we're our own customers.  Across the range we are able to ship linking the VC DLLs dynamically without pain and saving a lot of rebuilding and servicing effort when picking up fixes as well.  We've been successful this way and I think you can be too.

I apologize that as we try to improve the situation the story changes over time and takes a little bit of re-education on the current story from version to version.  I'm also sorry that the shipping documentation was a little hard to understand.  We're doing what we can to rectify the situation, and hopefully in the future things will get easier, clearer and more pain free.

If you have any suggestions about how we can keep a strong servicing story while making things easier for ISVs, we're definitely interested in hearing them.

Thanks,

Ben

Monday, October 15, 2007 7:48 PM by Joe

# re: How to redistribute the Visual C++ Libraries with your application

There is a running joke that Microsoft never found a task it couldn't make more complicated. My variation is that a normal developer writes a Hello World program in one line of code, Microsoft writes in 10,000 lines of code and it involves COM.

Thus is the case here. Side by side native assemblies is a complex solution to a simple problem and arguably doesn't really solve it at all. The common sense solution would have been to name the DLLs according to their version. Thus, I would be linking against MFC804.DLL right now. This is an elegant solution requiring no jumping through hoops and diving in and out of the registry, adding manifests and all that nonsense. Moreover, if there was a genuine, honest to God show stopping bug and full regression testing found that it could be safely fixed in MFC804.DLL, it could be easily patched.

This is all you had to do. It could have been implemented in an hour and would have saved Microsoft hundreds of thousands of dollars in development, testing, deployment and other headaches. It would have saved us developers millions of dollars in trying to deal with a solution that has terrible support from your own tools. To put it even more directly; you created a million dollar solution for a hundred dollar problem.

That aside, for years I have been working with Embedded XP and XP/W2K installed headless. Sometimes I've had broadband access to these boxes, but sometimes I have limited, and very expensive, access. Reducing patches by 50k causes us cheers.

In addition, we like to keep our patches as simple as possible, meaning xcopy (we simply unzip the files into our binary directory during boot up.) Suddenly I have a 2MB executable that has to be downloaded and executed, not just unzipped into our binary directory. Had you done the common sense naming method, we could do exactly that and avoid DLL hell at the same time (and made the install smaller since we only need the CRT and MFC DLLs.)

Do note that even if I were currently dealing with "normal" end users, I don't want to use the side by side assemblies since they require yet another install step with too many points of failure which will (not may) generate increased calls to tech support. Calls to tech support cost real money and reflect badly on the company.

One final point: you express concern for security, but currently that is of little concern of mine in my context. Why? Because our "boxes" are so locked down it doesn't matter. Furthermore, I can't recall a single security issue with the code set we use. (Even the GDI+ issue you discussed was a non-issue for me years back because I completely controlled what files were accessed.)

Monday, October 15, 2007 8:18 PM by Ben Anderson (MSFT)

# re: How to redistribute the Visual C++ Libraries with your application

Hi Joe, thanks for your comments.

In your case, where you have locked down boxes with little or no access to the internet or other input, I think statically linking may be "ok" and even make sense in some cases.  (You may save time overall by dropping the dlls app local once and then all your subsequent updates can be much smaller).  

Beyond that, there are two points I'd like to address.

First, I think you may have a misconception about what is required to redistribute the DLLs.  The 2MB exe you describe is the VCRedist.exe file, which as my original post describes is not intended for anyone to install but people deploying with ClickOnce (not something most people use).  In your case you would be better served by deploying just the DLLs you use app-local with your app.  This can be done in the zip file method you describe.  If instead, in your scenario, it is possible to drop the dlls once into WinSxS, and then ship dynamically linked binaries which will be smaller than the statically linked binaries, I would recommend building your own MSI as described in the article, including the MSMs for only the libraries you intend to use, dropping that, then never worrying about it again.

The second misconception, and it is a common one, is that we are using WinSxS as a side-by-side versioning mechanism.  In VC's case, we are not.  As you say that is handled nicely by renaming the files.  Instead, we are using it as a guarantee that all requests for our DLLs can be directed to a specific version containing a fix.  We are dependent on Windows for this functionality, and the functionality they provide is WinSxS.  If we don't use WinSxS, apps just load whatever .dll is on the path - no guarantee it is even ours.  I believe WinSxS provides strong guarantees that any request will not only load the DLL in WinSxS, but also that it is our DLL and not some other DLL with the same name that has been maliciously dropped there.  This allows us to allow end users to distribute app localy allowing the xcopy/zip file deployment method, but also be redirected to the new version if there's a security fix.  In the sense that we are not really using the majority of the functionality of WinSxS, I agree with you that this is an over-engineered solution.  Unfortunately, we go with what we can get in terms of loading from Windows and WinSxS while giving us headaches, provides us with security guarantees we can't get otherwise.

Some of this depends on perspective.  From a developer perspective it's a little bit more of a pain if you don't take the time to understand how the new WinSxS scheme works.  I think this is the big hurdle as once you understand how it works, it actually ends up being pretty much the same as the old scheme with some benefits.  From a library provider perspective though, since we can't guarantee the patching behavior of all our developer customers, having a mechanism to centrally provide fixes so that end users of applications which use our libraries aren't hosed by a two step process of getting fixes where we can't guarantee the middle man is being responsible is very appealing.

And to address one of your points about our tooling not really being up to date with making this process easy, I definitely agree there.  I don't think too much work has been done in VC9 (Orcas) to make the situation better, but it's definitely one of the pain points we've noticed over the last two years since VC2005 shipped, and for VC10 we'd love to have a better story.

So any suggestions are definitely most welcomed.

Thanks,

Ben

Monday, October 15, 2007 8:55 PM by Ben Anderson (MSFT)

# re: How to redistribute the Visual C++ Libraries with your application

Just a correction to my last post, the first parenthetical should have read "You may save time overall by dropping the dlls centrally once and then all your subsequent updates can be smaller".  What I mean is install the libs you'll be needing to WinSxS using a custom built MSI using the MSMs you need (You can call it "YourProduct Prerequisites"), then all your future installations can just be tiny dynamically linked executables. This of course only makes sense if your going to be dropping a lot of things.

Tuesday, October 16, 2007 4:10 AM by Phaeron

# re: How to redistribute the Visual C++ Libraries with your application

Ben:

First, let me say that I am in no way opposed to providing ways of creating more secure apps -- certainly I am no fan of strncpy(). However, I think you are overreaching in considering Microsoft's experiences in application deployment and maintenance as mostly representative.

I do not use an installer, nor do I want to. I use .zip files for deployment because they are simple and universal. The largest program I have ever written, with a full GUI is 950K; I have distributed many smaller modules down to 50K. The CRT DLLs would add very significantly to the download footprint of each. In addition, none of the side-by-side scenarios you have noted work for me -- users tend to run applications directly from .zip files without supporting files, and there is no directory layout that works directly for both Windows 2000 and XP, since 2K does not support WinSxS. When manifest-based DLL lookup fails, the errors are often cryptic even to programmers, much less users. As others have said, the only CRT linking scenario that is guaranteed to work is static linking, and everything else is a support hassle. For applications which make light use of the CRT, the size overhead is minimal compared to the DLL.

More importantly, I do not desire Microsoft to update the CRT used by my program without my express permission. You have already given the reason why -- the best intended changes, even fully tested and correct in themselves, can break applications. Like Joe said, applications can use DLLs are used such that no external data ever reaches them, mitigating many security issues in those modules. The necessary API break case you speak of would be very inconvenient, especially since users would not associate the breakage with you -- they would associate it with us, the application vendors. As for pulling the update, frankly, I don't believe you. Did Microsoft pull the recent .NET Framework security update that changed the behavior of the character encoding classes and broke existing applications in ways not security related? No, users were left wondering why their apps were broken and vendors had to scramble to fix them.

I am not going to say that Microsoft should roll back its security practices. However, you must realize that your security policies, for better or for worse, are not the same as everyone else's. Furthermore, it is obnoxious and not very good design for the lowest level library in a program to be dictating application distribution policy. Static linking gives us the option of both greater flexibility and responsibility. This kind of choice is part of the reason we use C++ and native code.

Tuesday, October 16, 2007 5:20 AM by Niki

# re: How to redistribute the Visual C++ Libraries with your application

Ben Anderson wrote: "having a standalone exe with no installer, the correct thing to do is to package the CRT DLLs app-local - no need to install and in the case of a security event you will be redirected to the patched version by WinSxS."

This might be correct for other Dlls, but installing the CRT-Dlls app-local is a BAD idea, at least for .NET applications. I've spent two days tracking down strange bugs that happened only on a particular production machine, until I looked in detail at the loaded modules: There were two different versions of each of the msvc...dlls, the app-local one and the one from WinSxS. This led to very strange, non-reproducible bugs. I don't know if the older WinSxS-DLLs were buggy, or if they were incompatible with the newer app-local ones. My guess is that the CLR loader loaded the WinSxS-versions.

As soon as I installed vcredist_[arch].exe everything worked fine.

Bottom line: If you want xcopy-deployment, use vcredist_[arch].exe. I wish there was a way to put all the components for my application in one folder, but I couldn't find one.

Tuesday, October 16, 2007 7:12 AM by pingpong

# re: How to redistribute the Visual C++ Libraries with your application

Count me as another one who'd love to link statically to avoid dependencies on dynamic CRT. Unfortunately, our app has multiple DLL modules which pass vectors and strings around, so we need the common allocator.

We didn't migrate to VC8 yet, mostly due to distribution issues. If we will, it's going to be app-local. Or maybe VC10 will show up earlier.

Anyway, this blog post was very interesting - thanks.

Tuesday, October 16, 2007 11:39 AM by Bryan

# re: How to redistribute the Visual C++ Libraries with your application

I think the approach here is kinda unfriendly toward installers.  For example, Windows Installer has various limitations on SxS assemblies.  If I have any file that self-registers or relies on a file that needs to load the VC Runtime DLLs, that file will fail to load because the SxS assemblies have not been loaded.  This means that I cannot load my DLL in System Context, say if I need to write to ProgramFilesFolder or something of that nature.  The obvious and simple solution is to simply package the EXE and launch it as a prerequisite, as nearly all of the mainstream commercial installer products allow.

The approach on VCRedist is pretty scary as the download page does not, in any way, explain the severity of installing it that way.

Please excuse my ignorance of some of the approaches for VC9; however, I think the SxS merge module only approach severely limits deployment capability and locks you in to a situation where you're likely to experience issues.

Further, I was wondering:  Is there a solid upgrade approach provided through the merge modules?  Will including the VC8 MM and then changing to the VC8Sp1 MM break Windows Installer minor upgrade component rules?

Is there a thought to making the EXE Redist approach realistic in the future without the huge side-affects?

Just some thoughts :)

Tuesday, October 16, 2007 12:49 PM by Dusty

# re: How to redistribute the Visual C++ Libraries with your application

Is it possible to use the merge modules if you do not create a Windows Installer?  Can you somehow install the merge modules by launching them on your own? (not sure this makes sense)

Currently in our installers we use the VCRedist*.exe because we create our installers with Inno Setup, but it sounds like we should switch to copying the DLLs or using the merge modules.

Tuesday, October 16, 2007 4:34 PM by QbProg

# Issues and Issues

The idea behind SxS is good. The implementation is bad.

I use private assemblies for CRT and ATL and bypassed almost every problem. I'm forced to put all my binaries in one folder, but that is not a big issue.

Anyway I got problems with some computers where Vs2005 was previously installed (maybe another version). The program failed to load, no way. I tryed with VC redist, with private assemblies, etc.. No way. The same dist in another (clean) computer worked well. Why?

Plus

- SxS is the worst documented feature of MSDN. No way to read a document containing the way it works in a clear manner. I mean , how it REALLY works.

"How to deploy VC++ apps" doc is good, but it doesn't cover every possible scenario... Approximative, I would say.

- It is not clear how SxS and manifests work with COM dlls, with dependent DLLs, etc... (i.e. sometimes I get themes enabled anyway, sometimes not... why?)

- It is really not clear how manifest, redirection, COM isolation , isolation aware compilation, etc... work in complex scenarios.

I'd like to use these features from visual C++ projects, but I was never able to do that, and I'm using VC from years now...

- Mixed RTM & SP1 deployment never worked, using manifests, shared assemblies, etc...

I don't see the point in using assemblies for CRT:

- If I use redirection from RTM to SP1, I could break things out for non-recompiled software.

- If I use Side by side, I get two copies of the CRT in memory , the same as using a static lib.

So why don't simply overwrite the CRT DLL and let programmers be happy ? :)

- Using non MSI tools or merge modules, needed to install in different location in Win2000 or Win > 2000. Not really good.

And there's not instruction for deployment in such cases.

- PLEASE do not force the user to use assemblies, and do not force the user to include manifests, at least for "x-copy" deployment.

(Sorry for my bad english)

To VC team: I won't never deploy a CRT or MFC dll patch "alone", I don't think anyone will do that. I will always send it with a new version of the software, and I'd like that Windows Update doesn't interfere with my application, breaking things out, specially if I deploy private assemblies.

---

Conclusion : I'm not able to use static libs because I have multiple DLL's in the same project, but if I could, I would!

Tuesday, October 16, 2007 7:46 PM by Ben Anderson (MSFT)

# re: How to redistribute the Visual C++ Libraries with your application

Wow, thanks everyone for your posts!  I'll try to respond to most questions / posts, forgive me if I miss something.

In reverse order:

QbProg:

Your issue where you couldn't get your app to load sounds strange.  You didn't have a mismatch between what you had compiled for and what you were redisting did you?  Or maybe you had a prerelease version installed?

I totally agree with you that SxS isn't super well documented.  A lot of it is black magic to me.  As for your questions about COM, I'm not entirely sure which complex scenarios you're referring to, but a lot of what happens falls out of how the Windows loader works and what WinSxS does.  I believe you may be seeing the themed look sometimes and not others based on the order in which you load binaries and whether any of them has loaded the common controls DLL with themes since those things get reused by the loader if possible.  I've found the Windows Internals books helpful in understanding what might be going on in situations like this.  I'm not sure if they're up to date now or not so I'm not sure if they include WinSxS info, but check them out - they're a helpful tool in general.

As for your comment about redirection from RTM to SP1 - actually you will should not break anything, and if you do you should file a bug and request a QFE from support if you need it.  We put a lot of work into making SP's and QFEs binary compatible with previous versions meaning if you compile against RTM and onward, all future QFE and SP VC++ libs DLLs should work with your bits.  Note that Windows Vista and Office 2007 both work this way - they built with and shipped against one version and as users install other software with updated DLLs, they are redirected to use the newer DLLs.  No issues so far :).  Please note that msvcrt.dll along with the various MFCs shipped with the OS are also patched from time to time to fix security holes and that sort of thing and in recent years I don't believe that has caused issues.  

Bryan:

I believe the common practice to workaround the limitations you describe is to chain multiple MSIs into your installer so that you install the SxS stuff first, then your app.  I'm not really a setup guy though, so I'm not sure about some of your other questions.  I'll see if I can get a setup guy to take a look at some of these posts, but if not, check out Heath Stewart's blog here: http://blogs.msdn.com/heaths/default.aspx and maybe he can help you if you post a question in the comments of an appropriate post.

pingpong:

Thanks for your post :).  I'm curious - is the reason you would use app-local deployment instead of the MSMs because you want to avoid an installer?  If not, why so?  When you mention you haven't migrated to VC8 yet because of distributions issues just that you would have to redist the libs or was there something further holding you back?  It'd be great to know any specific issues you're worried about.

Niki:

The issue you saw deploying app-local sounds kind of bad.  If you could help us out by filing a bug and repro on the Connect site, that would be super helpful.  Even if it's not a bug, at least we could understand the issue you are hitting.  https://connect.microsoft.com/feedback/default.aspx?SiteID=210&wa=wsignin1.0

Phaeron:

I understand your concerns and why you chose to do what you do.  That is why static linking is still available and supported.  I do think that the likelihood of your hitting an issue due to a CRT update is very slim, but I understand also that other people breaking you is no fun ;).  I do think that with MS supplied base components like the CRT though, that the target value is very high for malicious exploitation.  As such, I think it's important that we are able to update well if vulnerabilities are found.  The concern though is probably not for folks like you who understand the issues and update their customers responsibly.  The concern is for less informed folks, less responsible folks, or just unforseen circumstances (companies going out of business, developers no longer working on projects, that sort of thing).  

I'm pretty excited about the posts we're getting on this thread.  I think already I've identified a couple things we could do better in the future like a) more informative error messages on loading errors, b) better accommodate the Win2k app local scenario and c) explore ways of removing the redist burden from the developer.  I think redisting via Windows Update is something worth exploring.  I'm not sure whether it would be possible, and whether it would be possible to ship it as an automatic update since some users are sensitive about what gets shipped as a critical update (usually the vote is that only security updates gets shipped as critical).  If you have more ideas let us know.  Just to note, we are probably not going to move to a model where users can refuse a redirection.  I think we're comfortable with our binary compatibility (I can't think of a single issue I've heard in relation to this) and we want to maintain central updatability given the target a component like the CRT makes.  

Keep it coming

Ben Anderson

Visual C++ Libraries QA Team

Tuesday, October 16, 2007 9:05 PM by Ben Anderson (MSFT)

# re: How to redistribute the Visual C++ Libraries with your application

In response to Dusty:

While you can't install the MSMs directly, what you can do is build your own setup project which is empty except for consuming the MSMs.  You can call the install "MyApp Prereqs".  This will associate the entry in Add/Remove Programs with your app, and will allow you to uninstall it since you know no one else will depend on it.  Then you can just call that instead of VCRedist in your install process.

Tuesday, October 16, 2007 9:18 PM by Ianier Munoz

# What about OpenMP?

For some of the reasons already mentioned by other readers many times I go for static linking of the CRT, too; however, OpenMP doesn't support static linking. Are there any plans to change this? If not, would the "app-local" scenario work for OpenMP deployment? (i.e. vcomp.dll)

Tuesday, October 16, 2007 9:43 PM by Ben Anderson (MSFT)

# re: How to redistribute the Visual C++ Libraries with your application

App local does indeed work for vcomp.dll.  It also works for the other DLLs if you should choose to link the CRT that way as well.

Wednesday, October 17, 2007 2:31 AM by QbProg

# Re:

Thank you for your reply :)

I'll check the internal books to really understand what happens!

I do see advantages using an "assembly" approach, so you can easily upload fixes via Windows Update.

But the system has some incongruencies:

- If I have an app-local deployment, and NOT the shared assemblies installed, this method doesn't works . It could happen, specially with new compiler versions. For many time I didn't got any VC2005 app installed.

- If I have updated shared assemblies , app-local is useless.

Ok, these are by design. But I wonder if something simpler could be done?

(or at least provide a fallback to prevent loading errors)

I will try to reproduce the loading error, and put a feedback on connect.

Good Bye!

Wednesday, October 17, 2007 5:07 AM by Niki

# re: How to redistribute the Visual C++ Libraries with your application

Ben Anderson wrote:

"a) more informative error messages on loading errors, b) better accommodate the Win2k app local scenario and c) explore ways of removing the redist burden from the developer."

Yes, that would be most helpful!!!

Just two additions that come to my mind:

d) Better documentation (this should really by a)...)

e) A tool like "depends.exe" that can tell me - for managed, unmanaged and mixed code - what libraries a given executable would load and from what location (and if possible: why from that location). Today you can get some of that information by using a combination of ProcessExplorer, Depends.exe, ildasm/reflector (and sometimes WinDbg), but it's kind of a puzzle...

(I will try to reproduce the deployment issue I described and file a bug report as soon as I have time.)

Wednesday, October 17, 2007 9:07 AM by Bryan

# re: How to redistribute the Visual C++ Libraries with your application

"I think redisting via Windows Update is something worth exploring."

I think this is a much more sane deployment practice.  In this way, you also accomplish your desire to remove the static linking approach to redisting as well.

It's the best security, deployment, and usability model that could be implemented.

Otherwise, if that doesn't fly, I think the merge module approach is something that Microsoft's other departments have learned are a Bad Idea (tm) and only cause hardship for both sides of the deal.  Maintenance on those DLLs is miserable as if you need to update the merge modules for any reason, you have to deploy the entire MSI or pray that modules are authored per small/minor upgrade rules so you can deploy them as a patch.  And if they aren't?  You, as the installation developer, have no recourse :-(

I think taking a look at the evolution from the original MSDE 2000 Merge Module style installation to how SQL Server 2005 has evolved from that.  Sure, people complained at first.  But then once you understand how you can leverage and take advantage of the functionality provided through the seperate redist, you realize how good it is to be able to install it outside of your installation without hardship.

I really like the direction that the CRTs are moving as far as functionality goes and resolving those pesky security issues.  There's just a little area that I think got kinda overlooked to some extent.  :-)

I read Heath Stewart's blog every day :)  It's a good one, but I think sometimes it's best to not talk to a setup guy.  Also, he hasn't really touched on the subject much :(

Wednesday, October 17, 2007 2:34 PM by pingpong

# re: How to redistribute the Visual C++ Libraries with your application

We provide two packages: one is simple zip containing the executables and some data files, another is setup created by InnoSetup which copies t

Wednesday, October 17, 2007 2:42 PM by pingpong

# re: How to redistribute the Visual C++ Libraries with your application

Oops, Enter key seems to overreact. I'm starting again :)

We provide two packages: one is just a zip containing the executables and some data files, another is simple setup program created by InnoSetup. Using MSMs seems like an overkill in such basic scenario.

Overall, the CRT distribution model is/was the biggest obstacle blocking us from migrating to VC8. Other things, like relative sluggishness of the IDE can be overcome with faster workstations :)

Thursday, October 18, 2007 1:24 PM by Thomas Witt

# re: How to redistribute the Visual C++ Libraries with your application

For the record you may have a strong commitment with respect to maintaining binary compatibility but you don't have a strong track record.

Over the last twelve month our app was broken twice by binary incompatible CRT upgrades one was a SP1 beta CRTs shipped to customers by some unconnected product group (in a non beta product as far as I can tell) and one was SP1 itself!

Let's face it, it's a losing battle. Give people a way to control the CRT version they link to. If you don't do it for DLLs they will link statically. It's the reasonable thing to do.

Thomas

Thursday, October 18, 2007 2:35 PM by Ben Anderson (MSFT)

# re: How to redistribute the Visual C++ Libraries with your application

Hi Thomas - if you were broken, it's probably a bug.  We'd love to see it if you want to file a repro on Connect, or if you need a fix, you can request a QFE so we can see if we can fix the issue for you.  (I assume you're talking about VS2005 DLLs correct?)

Alternately, if you don't want to go through those processes, you could post the repro or details here and I can take a look and forward it along if necessary.  You probably won't get any action in terms of a fix that way though.

Friday, October 19, 2007 3:05 AM by QbProg

# re: How to redistribute the Visual C++ Libraries with your application

Hi Thomas,

from what I have understood of the whole thing, you can set an Application Config manifest that forces your app to link to a specific version of CRT (should override publisher settings).

Right ?

:)

Saturday, October 20, 2007 3:24 PM by Jon Wiswall (MSFT)

# re: How to redistribute the Visual C++ Libraries with your application

The hands-on-the-baseball-bat go {private policy, publisher policy, admin policy}.  Private policy is what’s in your app .exe.manifest saying “I want at least version M.”  Publisher policy is from the component publisher and says “When someone asks for version A through Q, given them version R” and is the usual thing you distribute with a QFE/GDR.  Administrator policy says “My line-of-business app is broken with version R, substitute version P.”  It’s called administrator policy because it’s something the local administrator can author into “foo.exe.config”.  Because of the possibility of opting out of security updates, it must appear in the same directory as the foo.exe itself.  The implication being that if the admin was too lazy to not properly security foo.exe and its parent directory against writes, it’s irrelevant what “bad” policy can be added, local users can already replace foo.exe itself with something more interesting.

The key here is that application config is for administrators to create, not for application publishers (even though the name is confusing.)

Don't ship .exe.config with your app.  Now, your app is free to auto-update itself and pull down .exe.config after install in response to being broken.  This should be done with the consent of the administrator or via a 'knowledge base' article on your site.

Sunday, October 21, 2007 8:23 PM by Norman Diamond

# re: How to redistribute the Visual C++ Libraries with your application

One of my recent experiments, with a product which might or might not get released this way, has essentially Xcopy deployment and I managed to get some manifests working.  But I don't really need to depend on exactly this version of the CRT and ATL, I just need this version or newer.

As far as I can tell, if some end user's machine has newer DLLs as a result of their administrator installing some other application that does a full SxS installation, my manifests are going to prevent using the newer ones.  If the newer ones have security fixes then this almost surely isn't what I want.  But I still need my manifests because my app can be Xcopied by a non-admin for personal use without doing an install.

Sunday, October 21, 2007 9:02 PM by Ben Anderson (MSFT)

# re: How to redistribute the Visual C++ Libraries with your application

Norman - as long as you only use manifests, not .configs which as Jon describes is bad, if newer DLLs get installed to WinSxS, your app will still query the system saying "I want version X".  The policy in WinSxS intalled with the new DLLs will redirect your app's request to the newer versions.  So the behavior you describe as optimal will still occur and you should be safe.  Feel free to include manifests in your xcopy deployment method - a policy in the central WinSxS can redirect you when a newer DLL is available.  

Thursday, October 25, 2007 4:35 AM by Tom Robinson

# re: How to redistribute the Visual C++ Libraries with your application

Ben - your explanation of the assemblies and manifests concepts and implementation helps a lot but once again, it seems that Microsoft has neglected support for dynamic situations.  Currently, I am rebuilding an ISAPI extension provided by a vendor using VC++ Express.  I have had some problems with the code, since it was written a long time ago for a non-Microsoft compiler.  I'm trying to use the EYESAPI tool to test my extension changes (www.genusa.com/isapi/eyesapi.html) and to figure out what problems I have.  EYESAPI lets you debug ISAPI extensions without having to use IIS - a much simple debugging strategy.  This tool gets the name of a DLL by having the user type the name into the window.  My examination of the assemblies and manifests implementation suggests that tools like this can't be built or supported with MSVC anymore.  Am I wrong?  How would you solve this problem....(bearing in mind that I have no source for this tool and that it does not already dynamically generate a manifest resource inside itself?)  Similar questions arise for linking using DLLs from dynamic languages like Perl, Python, Ruby and Smalltalk.  Are these languages going to have to dynamically generate manifests to support loading DLLs in dynamic language code?  That isn't my problem right now, but it looks like it could be down the road.

Thanks for all of the time you've put into responses to our questions.

Thursday, October 25, 2007 3:39 PM by Andrew Godfrey (MSFT)

# re: How to redistribute the Visual C++ Libraries with your application

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++.

Sunday, October 28, 2007 10:47 AM by Bruno Martínez

# re: How to redistribute the Visual C++ Libraries with your application

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?

Tuesday, October 30, 2007 6:18 PM by grmileka

# re: How to redistribute the Visual C++ Libraries with your application

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

Tuesday, October 30, 2007 6:27 PM by grmileka

# re: How to redistribute the Visual C++ Libraries with your application

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

Friday, November 02, 2007 7:19 PM by Tom Robinson

# re: ISAPI testing with EYESAPI and creating DLLs that can be loaded by LoadLibrary without an application manifest

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?

Saturday, November 03, 2007 3:28 PM by grmileka

# re: How to redistribute the Visual C++ Libraries with your application

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.

Monday, November 05, 2007 1:22 PM by Tom Robinson

# re: How to redistribute the Visual C++ Libraries with your application

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.

Tuesday, November 06, 2007 10:03 AM by Charles L.F.

# re: How to redistribute the Visual C++ Libraries with your application

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!

Tuesday, November 06, 2007 12:58 PM by Ben Anderson (MSFT)

# re: How to redistribute the Visual C++ Libraries with your application

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

Tuesday, November 06, 2007 1:36 PM by Nick

# re: How to redistribute the Visual C++ Libraries with your application

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.

Tuesday, November 06, 2007 1:45 PM by Nick

# re: How to redistribute the Visual C++ Libraries with your application

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?

Tuesday, November 06, 2007 4:43 PM by kstreith

# re: How to redistribute the Visual C++ Libraries with your application

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.

Wednesday, November 07, 2007 9:10 AM by Charles L.F.

# re: How to redistribute the Visual C++ Libraries with your application

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

Tuesday, November 13, 2007 11:10 PM by Tom Robinson

# re: How to redistribute the Visual C++ Libraries with your application

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.

Friday, November 16, 2007 11:45 PM by Ashish Bhatt

# re: How to redistribute the Visual C++ Libraries with your application

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.

Monday, November 19, 2007 7:16 PM by Ben Anderson (MSFT)

# re: How to redistribute the Visual C++ Libraries with your application

Sorry it's been a while, but as I said responses here will get thin now that it's been more than a few weeks.  I recommend checking out the MSDN forums for quicker answers.

Anyway, I'll hit what I can.  If I miss something, bug me again (maybe post short comments with hints about what I missed;):

Nick:  We will indeed drop the updated CRT on every machine via Windows Update in the case of a security event.  The security fix I worked on a while back was actually not an exploited issue, but an internally reported issue where a specific use case of a rarely used function could lead to a garbage function pointer.  Basically it was an issue that noone would probably ever hit ever, and also that probably no one even has written exploitable code for so it did not trigger a security event.  Maybe it should have, I'm not sure what the exact polices are.  You're right in your comment though that if you want to see the VC8 DLLs on pretty much every machine, one thing you could do would be to report a security issue and get MSRC to issue a patch ;).  We jokingly suggested we code one in to do this and then have someone's mother report it, but of course we would never actually do that.  

kstreith - it sounds like you might be trying to drop the wrong bits in the x64 case.  I would double check you've got all the manifests correct and you're dropping the right bits for app local.  It should work on every Windows OS XP and above (including 64-bit).  

Charles - the reason you can't link to msvcrt.dll using 2005 is that msvcrt.dll defines objects and structs differently than 2005 does.  It also uses an older version of the C++ standard.  So, while in theory you could take the 2005 compiler on your path and put the VC6 headers and libs on your include and libs paths, the 2005 compiler would likely choke on the VC6 headers.  It might work, I have no idea, but you'd definitely be way out in unsupported land and it would probably be way more trouble than it's worth.  Also, then you're basically using VC6 WRT the libraries.

I can't discuss planning for VC10, but one of the things we'd like to work on and address is an improved redist story.  It's all early stages now and we haven't prioritized and selected which features will get in to VC10 as a whole, but hopefully not too long down the road you'll see a new blog post talking about all the issues that are addressed :).  Some of the things we're thinking about would solve some of the scenarios people here are reporting (in fact, these comments are one of our sources of info for what sorts of things are the most pain).  

Also, I wholeheartedly agree that 2005 SP1 was a huge beast of a patch and that it was extremely painful to install.  As someone who has to build test machines probably more frequently than anyone pretty much anywhere else, I feel your pain ;).  It will be interesting to see if the situation improves for 2008 SP1.  I guess part of the issue was that the 2005 SP1 patch was huge, but I'm sure there is more work that could have been done to make it more painless.

Monday, November 19, 2007 7:17 PM by Ben Anderson (MSFT)

# re: How to redistribute the Visual C++ Libraries with your application

One more:

Ashish -

It sounds like you're trying to use .net somewhere in your component.  I think the installer can self register your ocx, but if not, regsvr32'ing it with /q should do the trick.

-Ben

Wednesday, November 21, 2007 8:09 AM by Michael Ellison

# re: How to redistribute the Visual C++ Libraries with your application

First of all, thanks for the explanation of redistribution! Additional documentation on this is more than welcomed.

As another developer who has switched to statically linking whenever possible, just wanted to point out an annoying thing to watch if you statically link moderately complex applications with MSVCRT:

Everyone knows not to alloc/dealloc memory and objects across DLL boundaries, especially when using multiple copies of a runtime (e.g. statically linked) or different runtimes.

However, one thing that I've seen very little discussion on is that you should also avoid much of the runtime entirely during callbacks originating from a thread external to your runtime (e.g. DirectShow thread callbacks, third party DLLs, or even your own threaded plugins).  

One example is the sprintf() family. If called from an externally created thread, it will allocate locale information for the thread.  Unfortunately, since the thread will be exited from the external module, this will never be cleaned up by MSVCRT - resulting in a small memory leak per thread that can add up over time.  Same problem with the FILE* io functions, except you get the added bonus of a leaked critical section as well.  

These can be avoided by posting messages across the thread-boundaries or similar to ensure they are used on module-local threads. It would be *beautiful* if there were a function to clean this up manually (the code allocating is deep down in the CRT though - near _getptd()).

As far as why I've switched to statically linking... I spend a very large percentage of my time tracking down, fixing, or working around bugs in third-party software - including but certainly not limited to Microsoft's.  My recent applications have required as close to 24/7/365 operation as the host OS's will allow, so even extremely minor leaks and rare race conditions are a big problem.  The apps are more industrial than consumer, although I've been less able than an earlier poster to exert much control on locking them down tightly.  

Bugs I've found and/or reported (e.g. one leak in an ATL hosting container, another in the  IWebBrowser2's use of registry keys for Zones, another in the WMP's COM object, crash-prone race conditions between multiple IWebBrowser2 windows on navigation, etc.) don't seem to hit high priority to be fixed when I face them.

They have also often been replaced with other problems when subsequent major versions came out.  Granted, these examples aren't in the MSVCRT, but they've made me nervous.

Once I've fully tested a system of software and fixed or worked around all the issues I could find in the environments it is expected to run in, I like keeping it that way as much as possible.  It'd be particularly brutal to have an app break at multiple customer sites when a patch is pushed out. I'd rather trust the code I've run through thorough tests with myself.  I  wish there was a good (non-license-violating) way to make all other components I