RunDll32 Problem on Win2k with Visual C++ 2008 Express Compiled DLL - visual-c++

First off, I'm not a C++ programmer (but I am learning). I have finally managed to modify and compile some C++ source code using Visual C++ 2008 Express Edition. I've tried to get the same code compiled in the full version of Visual C++ 2003 without success (I get a wide variety of errors, but no luck).
The problem is that everything is working fine using RunDll32 to call the DLL on Windows Vista, but when I try the same rundll32 call on Windows 2000, I get the following error:
"Error loading mysampledll.dll"
"The specified module could not be found."
Of course, I've tried setting the full path, moving the file around, etc...but no luck. I guarantee that the file exists and has the correct permissions.
I thought perhaps that there is something wrong with the manifest that is getting compiled along with the DLL in Vista. So I removed it using a resource editor, but then I get the same error in Vista and Win2k. Here's the manifest:
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"></requestedExecutionLevel>
</requestedPrivileges>
</security>
</trustInfo>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.VC90.DebugCRT" version="9.0.21022.8" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.21022.8" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
</dependentAssembly>
</dependency>
</assembly>
Now, I assume that the problem is with Win2k not having the Microsoft.VC90.CRT installed, but why does my DLL have this dependency? I've set the "Common Language Runtime Support" to "No Common Language Runtime Support" in the project properties, so why does it still require the CLR? Is there a way to change the manifest to use an older Visual C++ runtime that is available by default in Win2k? Sorry for my ignorance in these matters, and thanks in advance for any help.

Try installing the Visual Studio 2008 Redistributable package.
It contains the C++ runtime DLL that your program needs.
Don't get confused. That is not the CLR. The CLR is for managed code, not native Intel executables. Even native executables need the Microsoft runtime library dll if you dynamically link them to the runtime. This is the default in project properties, C++, Code Generation, Runtime Library = Multi-Threaded DLL. You can avoid this by choosing Multi-threaded, which would statically link in the library code.

I would say that on the Windows 2000 box your DLL won't load because it is missing a dependency.
You find out what is missing by downloading the Depends utility found here: http://www.dependencywalker.com/
If it is a MSCRT DLL that is mising then you will need to reditribute these DLL's with your DLL.

The problem is that you are trying to run a DLL compiled with the debug C-Runtime (CRT) library linked in.
To fix the problem, link in the non debug CRT with your DLL:
Option 1: Build and distribute the release version. (This is what you should be doing anyway when it's time to release.)
To do this:
List item
Build.Configuration Manager... and change your target flavor from Debug to Release; or
Build.Batch Build... and check of both Debug and Release; and
Use the binaries that come out of the Release directory.
Option 2: Build your debug binaries with the non-debug CRT.
To do this:
List item
Project.Properties...
Navigate to C/C++, Code Generation
For Runtime Library, select Multithreaded DLL or Multithreaded.
I tend to go with option 2 for quick and dirty projects, where I want the speed of the retail CLR, but want all the debug info for my code.
(By the way, CLR != CRT, but that's a different discussion.)

Note that you can also redistribute the CRT DLLs with your application, if you'd rather not require your users to run the CRT installer. You'll find them in your VC installation directory under redist\x86 (C:\Program Files\Microsoft Visual Studio 9.0\VC\redist\x86\Microsoft.VC90.CRT is the full path on my machine). Note that you must copy all four files in that directory (three DLLs and a manifest) and place them next to your EXE for this to work properly.
If you're doing anything more complicated, like building a DLL that other applications will load this is insufficient, but this suffices for most cases.

Related

Microsoft vcredist uses later version at runtime than specified in the manifest

How does the Microsoft C++ redistributable package work?
I have a binary which is built in visual studio 2008. It uses the RunTime Library as "Multi-threaded DLL (/MD)". The version in the manifest is Microsoft.VC90.CRT" version="9.0.21022.8". I have chosen the option to embed the manifest to the binary.
When this binary is deployed in the target machine, it gives a runtime error stating that
The procedure entry point could not be located in the dynamic link library MSVCP90.dll
I understand that the version of msvcp90.dll which the machine contains by default, doesn't have a function that my binary is referring to.
Now I install the vc++ redistributable (vcredist_x86_9.0.30729.17) and run the binary again.
This time it works fine and I see that the loaded msvcp90.dll is of version 9.0.30729 instead of 9.0.21022.8.
How does this happen? How does my exe choose the latest version of msvcp90.dll even though the embedded manifest has the version as 9.0.21022.8?
I believe these variances are specific to the VS 2008 RTM vs the SP1.
The manifest will specify the code's intent, necessary privileges, etc. However, the system will detect the dependencies even if a manifest doesn't exist. Your program depends on VC90 ver 9.0.21022.8 or greater. That is the only concern. The app.config however can assist in the specific version that is bound, similar to the following:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<configuration>
<windows>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.VC90.CRT" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"/>
<bindingRedirect oldVersion="9.0.30729.1" newVersion="9.0.21022.8"/>
</dependentAssembly>
</assemblyBinding>
</windows>
</configuration>
In the app.manifest, you can set _BIND_TO_CURRENT_VCLIBS_VERSION to control this.
The .h and .lib files determine the dependency.
--> EDIT:
Regarding your comment about the name mangled entry point _Xbad#tr1#std##YAXW4error_type#regex_constants#12##Z:
(undecorated is void std::tr1::_Xbad(enum std::tr1::regex_constants::error_type))
It is in fact found in the later SP1 MSVCP90.DLL (9.0.30729.17)
Ordinal: 1513 (0x05E9)
However it is not located in the older RTM version (9.0.21022.8)
(Use dependency walker to view the entry points)
You must have compiled your code with the latest .h and .lib for the linker to resolve the function, so it is curious why your dependency version would not be updated since your code requires a function which does not exist in the older version. I would ensure that your dependencies target the newer version. I hope this helps.

Which Windows Libraries are missing from the Visual C++ Redistributable Package?

I am using JNI to interface to a CAN driver I wrote using MSVC++ 2012. Everything compiles and runs fine - but only on my computer. Whenever I try to run on any other computer, I get the JNI "UnsatisfiedLinkError" - can't find dependent libraries. I've implemented JNI before, and typically this issue is resolved by simply installing the Microsoft Visual C++ Redistributable Package before running my program. The Redistributable does not solve my issue, however, installing the entire MSVC++ Express 2012 IDE on the computer in question seems to make everything work just fine. Thus, I assume this means that there is some dependency that gets installed and added to PATH when the IDE is installed but not when the Redistributable is installed. Just for verification, I uninstalled the IDE and my JNI driver failed to load once again. The primary difference between this and my other implementations of JNI is that I use Windows.h since it is required for the CAN API I use in my driver. Any ideas on any libraries installed with the IDE but not the Redistributable and whose prototypes are included with Windows.h? (Note: I am aware that Windows.h includes a number of headers itself but I imagine the other criteria make the issue a bit more specific.)
First guess: You are installing a debug build intead of a release build. Debug builds depend on debug versions of the CRT, which cannnot be redistributed.
Check that you are using the right "Microsoft Visual C++ Redistributable Package". There are 2012, 2012 Update 1 and 2012 Update 2 (as well as many for 2010, 2008, ...).
Assuming your dependencies are load-time DLLs, you can use Depends to find out what's missing. (Note: you'll typically see some delay-load DLLs that are "missing". Ignore thoses; See the FAQ.)
Of course, once you find out the name and path of the missing DLL, you'll have to find out what redist package installs it.

wix custom action missing dll MSVCR100D.dll

I am writing an installer using wix. I have also written custom actions. But while installing the MSI the installation fails because the target system does not have MSVCR100D.dll
I am linking using /MTd option which is what the docs I read suggested for static linking.
Can anyone please let me know how to link msvcr100d.dll statically so that even if msvcr100d.dll is not present on the target system, my MSI installation succeeds?
The "D" in MSVCR100D.dll indicates that your native custom action DLL is a debug DLL. The "D" dependency won't be on the target machine unless they have various SDKs installed. Rebuild your DLL in release and the dependency will change to MSVCR100.dll
Also, since you are using WiX / Votive, there is a Visual Studio WiX C++ CA project type that creates the project for you. My experience has been that all of the default compiler and linker settings are good to go out of the box when you use that project type.
I have noticed the same problem. In my case, I am trying to debug my custom actions running in the context of the installer, so I do want to install debug versions.
The Visual Studio debug CRT DLL's are not redistributable, by Microsoft policy. Apparently, it seems furthermore that a 64-bit DLL compiled with Visual Studio 2010 using /MTd (static linking, debug configuration) produces output with a dependency on MSVCR100D.dll. In the 64-bit release configuration, as expected, compiling with /MT results in no dependency on MSVCR100.dll.
One solution is to install Visual Studio on the target test machine. Microsoft offers further suggestions here.

After building exe using VS 2010 C++ missing MSVCP100.dll

I have designed an application that requires no install and can be used by non-administrators. I would rather not lose this functionality but when I use the .exe on other computers than the one I programmed it on I get an error that a missing MSVCP100.dll is preventing the file from executing.
What am I doing wrong here? How do I include the file in my release build?
Thanks!
Configure your project to statically link to the C/C++ runtime instead of linking to the runtime DLL:
Configuration Properties | C/C++ | Code Generation | Runtime Library
Select Multi-threaded (/MT) (or Multi-threaded Debug (/MTd) for your debug build).
As an alternative, you should be able to get xcopy deployment of the C/C++ runtime DLL using the technique documented on http://msdn.microsoft.com/en-us/library/ms235291.aspx under the heading "Deploying Visual C++ library DLLs as private assemblies". I haven't tried that technique, as it's generally simpler to just statically link if you need xcopy installation of a native C++ program.
http://msdn.microsoft.com/en-us/library/ms235299.aspx
Distributing apps that have been compiled with Visual C++ requires distributing the C++ runtime .dlls that your app uses. In your case, I assume you want to just distribute a folder, so follow the directions (appropriately modified for your app) here:
http://msdn.microsoft.com/en-us/library/dd293565.aspx
Or just copy msvcp100.dll into your application's directory alongside the .exe and you'll be good to go.
32-bit msvcp100.dll is in C:\Windows\SysWOW64\
64-bit msvcp100.dll is in C:\Windows\System32\
What am I doing wrong here
What you had was dll hell. You had unintentionally used a dynamic linkage with the previous compiler where it just happened on most target systems there was an appropriate C runtime. Windows often included VC 6 CRT, and with more recent SP even VC7 & 8 CRT.
When you changed to the latest VC compiler most systems will not have the new VC runtime pre installed for you.
As Michael Burr says, you can have your 'no install' back if you link statically.
Or you could include the CRT and manifest in the same folder, still doesn't require install.
Or include the vcredist.exe from VS2010 and have a 1 off install
You need to install Microsoft Visual C++ 2010 Redistributable Package.

Visual Studio 2005 security updates and CRT DLL versions in manifest

Recent Visual Studio 2005 security updates may be causing problems for us.
We build and internally distribute SDKs written in C++. These SDKs are a collection of header files and static libraries only. After installing the security updates our SDKs now depend on the newer versions of the MSVC CRT DLLs. These SDKs are used downstream in projects which produce EXE files.
If one of these EXE files is built with a mix of SDKs (some from before the security updates, some from after), then the EXE file produced makes reference to two sets of MSVC runtime DLLs. E.g:
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50727.4053" processorArchitecture="amd64" publicKeyToken="1fc8b3b9a1e18e3b">
</assemblyIdentity>
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50727.762" processorArchitecture="amd64" publicKeyToken="1fc8b3b9a1e18e3b">
</assemblyIdentity>
</dependentAssembly>
</dependency>
</assembly>
Does this mean that at runtime this EXE will be using both versions of the DLL? Does this mean we must distribute both versions of the MSVC Runtime DLLs with this EXE?
Is there a simple way to avoid this problem without forcing all SDKs to be built with the Visual Studio 2005 security patches in place? (This would be undesirable for some of the older and quite stable SDKs that we don't want to rebuild unnecessarily)
Is is possible to simply rewrite the manifest file on either the SDKs or the final EXE file so that only one version of the MSVC CRT DLLs are mentioned?
My understanding is that the relevant updates are as follows:
Security update for Microsoft Visual Studio 2005 Service Pack 1: KB971090
http://go.microsoft.com/fwlink/?LinkId=155934
Security update for Microsoft Visual Studio 2008 Service Pack 1: KB971092
http://go.microsoft.com/fwlink/?LinkID=155933
I have discovered two other questions which are similar:
VC++: KB971090 and selecting Visual C Runtime DLL dependencies
Does the latest Visual Studio 2005 Security Update cause C runtime library issues when hot fixing customer sites
1) Yes it means the runtime is using both versions - something you never want to happen. It should only ever reference a single version of the DLL(s)
2) There is a method that I've developed to force the version to be the SP1 version (without the security update). I've outlined it here
3) You could disable manifests entirely and do them by hand, but I don't recommend this, as it's a pain to maintain different manifests for your debug and release, and it's an error-prone way of dealing with the problem. It would be better to use the workaround I mentioned in (2) above.
As Ted says, at runtime your executable will be trying to use both versions of the DLL. This is probably because you haven't fully recompiled the entire project (or you are using external libraries that have been compiled to depend upon the .762 runtime).
The good news is that if both these libraries are installed on your client systems then the side-by-side redirection policy will mean that only the latest is loaded. By far the more detrimental side-effect you will notice is when only one is installed (probably .762) that the application will fail to start with the old "application is not configured correctly, reinstalling may fix this problem" error message.
Does this mean we must distribute both versions of the MSVC Runtime DLLs with this EXE?
The easiest solution for you would probably be to just ship the latest version of the visual c++ runtime redistributable which you can get from the following link.
http://download.microsoft.com/download/6/B/B/6BB661D6-A8AE-4819-B79F-236472F6070C/vcredist_x86.exe
It can be a bit of a pain because it asks the user to click "I agree" on a EULA page and requires admin priveledges but by general consensus it is the best option if you can get the user to install it.

Resources