Fault tolerant DLL usage in Visual C++ - c++

Background:
I have an existing code that uses functionality provided by Microsoft, to post XML data over HTTP. Specifically, IServerXMLHTTPRequest (included in MSXML3 and up) from msxml4.dll (COM).
The Problem:
In the possible eventuality, were MSXML4.DLL is missing on the client workstation, the described POST operation will simply fail. More information about MSXML versions.
The current code:
#import "msxml4.dll"
using namespace MSXML2;
…
IServerXMLHTTPRequestPtr spIXMLHTTPRequest = NULL;
hr = spIXMLHTTPRequest.CreateInstance(__uuidof(ServerXMLHTTP40));
Alternatives:
Hard code to MSXML6 (instead of MSXML4). Not a good solution as we do not know what MSXML version is installed on the workstation. Also, the code will break again if Microsoft will release the next DLL version.
Dynamically load the latest from the registry:
Find MSXML version from registry and
Dynamically load a function from a DLL
Use the type library instead?
I would be happy to hear additional alternatives
The question:
What is the simplest and most robust way to change my code to be MSXML version agnostic? That is, use IServerXMLHTTPRequest regardless of the MSXML version actually installed on the client machine. If no version of MSXML is installed, prompt the user and exit gracefully.
Need additional information? Just let me know
Thank you!

From MSDN:
MSXML version 3.0 was the last version of MSXML to support version-independent GUIDs and ProgIDs. Starting with version 4.0, MSXML is installed on your computer in side-by-side mode. This means that, for example, installing MSXML 5.0 for Microsoft Office Applications does not replace any previously installed version of the MSXML parser on your computer. This is done to protect the quality of applications that are currently using earlier versions of MSXML. Side-by-side mode also allows you to decide which version of the parser to use in your code.
This means that there is no COM class installed which you can instantiate expecting that most recent installed version will be picked up, or otherwise someone else will decide for you whether to load MSXML 4 or 6 depending on availability or another criteria.
You are expected to use specific version and depend on respective runtime to be available or installed. Or you can switch between MSXML versions in your code as you already discovered.

Related

How to set version of a Qt application (made by QtIF)?

Just noticed a File version (4.2.0.0) from a Qt application, when mouse goes over the file. However that seems to be the QtIF version, not my application version.
How to set that (mouser over) version of a Qt application (made by QtIF)?
This may be considered the expected behavior (f.ex. when used as an online installer), as the installer is able to install multiple versions of your program and/or upgrade your installation once a new version of your software becomes available. So, the installer is not directly related to a specific version of your software. See for example the Qt installer itself.
If you really want to control the version number, you should compile the installer from source and change the version string of the installer itself by slightly modifying the source code. In case you use the installer as a pure offline installer, this may indeed be appropriate.

How to get installed version of Microsoft Visual C++ Redistributable(x64) in mfc application

I working on mfc application in which I need to check currently installed version Microsoft Visual C++ Redistributable.
Is there any way?
Each VS Version has its own redistributable files and they are named with a version number in the name.
So there is no "current" version. There may be several installations for different VS-Versions.
Usually the files are installed in the Windows\System32 directory for 64bit. So lookup the file you need and search for (i.e. MFC140u.dll) and you can determine it's version.
Also some programs may have a local copy of the runtime DLLs in their application directory...
I’ve written an application that inspects the customer installation. It works somewhat like the Microsoft Troubleshooters in that it identifies certain information about the user installation so that our tech support people can identify a potential problem with the customer installation. One of the things it reports on is the VC redistributables that are installed.
I accomplish this by interrogating the following LOCAL MACHINE registry key:
SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall
The code iterates through the sub-keys looking for a match on the “DisplayName” attribute of each sub-key. I look for “Microsoft”, “Visual”, “C++”, and “Redistributable”. If all strings are found, I collect the “DisplayVersion” attribute and report it to a dialog.
While this scheme will not indicate the "current" version, it should provide access to all versions that are installed.

How to include .NET framework library in executable

I've recently made a Windows Forms Application in VS 2010 Express. When running on my machine it works fine but on other machines it needs to install the .NET framework first. Is there anyway around this? By including the library in my executable? By not using the .NET framework?
I would really appreciate some help.
Typically this kind of problem would be handled by your Windows Forms Application's installation package.
Opinions vary but I'd suggest the safest/most polite thing to do is to treat .NET as a prerequisite. If .NET is not present, display a message that it is required before the install will succeed and perhaps point to a Microsoft download page like this one or this one. The risk is that you point them to an obsolete download page or that the page moves and invalidates your link.
That said, I would have expected most machines to have some version of the .NET Framework installed (by Windows Update for example) so it's a bit surprising that you're being told it needs to be installed.
I suggest you follow the instructions in How to: Determine Which .NET Framework Versions Are Installed to check one of your failing machines to confirm that .NET is not installed (very unlikely) or to determine which version (or versions) of .NET is (are) installed.
Update 6/21/2015 From the comment below, we have evidence of two systems without .NET installed so my "very unlikely" comment above is a bit off base!
Update 7/4/2015 I have a bad habit of forgetting that not everyone configures their Windows systems exactly the same way I configure mine. From this blog post it seems that the .NET Framework is 'only' a Recommended Update.

Are there any registry entries that indicate whether a specific C Run-Time is already installed?

I've been looking online and at my registry and I think not, but it would be nice if we could get a definitive answer on here.
Just the run time, as in for re-use on the client side.
I see it is possible for VC10, http://blogs.msdn.com/b/astebner/archive/2010/05/05/10008146.aspx, but prior to that we need to call the MsiQueryProductState API. Perhaps just give all the clients MSVCR100.DLL already?
The most common practice is to install the CRT your application was built with, regardless.
I think this practice comes from the v90 and lower CRTs, because there were multiple versions of each redistributable that could be installed, and though MSVCR90.DLL exists on the system, it may not be the version your application uses.
I believe this was changed with the v100 CRT, and now Microsoft guarantees that newer versions of the CRT will be usable in place of an older version, but I would still attempt to install the CRT your application was linked with.
It is still possible to do a private install of the Dll's into the application's folder. I recently installed 3 different version of the VC9 runtime when I was setting up my Visual Studio Express environments. All show up in Control Panel and appear to be readily removable.
For that reason I believe the current best practise to be to perform a private install (I think that is the terminolgy MS uses) of the required DLL's (for managed code you need the managed DLL and the native version) in tha app's folder.

SidBySide: 3rd Party Dll refers to two versions of MSVCR80.DLL

We include a 3rd Party lib+DLL that recently causes a lot of trouble on installations. Using dependencywalker, we found that the dll itself refers to two different Versions of
MSVCR80.DLL:
Version 8.0.50727.4053 and
Version 8.0.50727.42
alt text http://img101.imageshack.us/img101/1734/dependencywalk2.jpg
In MOST cases installation makes no problems, even if we distribute none of both versions. But in a number of cases our installation just does not start. We then find messages in the windows system event log from the SideBySide manger: "Version of DLL does not match". In most cases again this problem can be resolved, by installing the .NET framework (although we do not use this). But now we have a case where this does not help.
I know that a solution would be, to install both versions as a shared assembly, but that seems not to be easy, and besides that i would prefer a much simpler solution. Does anybody know a workaround?
Can i somehow use only one version of the Dll?
EDIT:
I now tried cristians advice:
D:\Develop\LEADTOOLS15\patch_maifest>mt.exe -inputresource:ltkrn15u.dll;#1 -out:old.manifest
Microsoft (R) Manifest Tool version 5.2.3790.2075
Copyright (c) Microsoft Corporation 2005.
All rights reserved.
mt.exe : general error c101008c: Failed to read the manifest from the resource of file "ltkrn15u.dll". Ressource not found.
If i view the dlls dependencies with full paths, i see the following:
alt text http://img340.imageshack.us/img340/4122/dependencywalk3.jpg
The lower MSVCR80.DLL is the one withe Version ...42. I dont understand this. Why does MSVCP80.DLL refer to a different Version of MSVCR80.DLL than the one besides it. Is that maybe a problem of the dependencywalker ?
Your best option is to ship the needed DLLs within your applications installer package. Use at least the version that your 3rd party DLL depends on.
Microsoft offers standalone installers for its runtime DLLs (vcredits_*). The latest version for VisualStudio 2005 can be downloaded here. That is also the version that your DLL is linked against. You can silently launch the redistributable package from your installer.
As a manual workaround for already installed systems, simply apply the redist installer on the target machine.
If you choose this method, you don't need to be afraid of version conflicts, as applications depending on an older versions will be redirected to always use the most recent one.
For a better understanding you have look at this MSDN articles.
You have to change / update the manifest resource from the dlls.
mt.exe -inputresource:dll_with_manifest.dll;#1 -out:old.manifest
mt.exe -manifest new.manifest -outputresource:dll_with_manfiest.dll;#1
Sometimes the RT_MANIFEST (type 24) resource type doesn't have the #1 index in resource table, you should use a Resource Viewer (ResourceHacker, or ResEdit) and find out the index number. I have seen cases when the manifest has the #2 index number.