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.
Related
Could not load file or assembly 'Microsoft.Bcl.AsyncInterfaces' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.IO.FileLoadException: Could not load file or assembly 'Microsoft.Bcl.AsyncInterfaces' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
I have to keep a backup copy of the dll and replace it again for the site to come up. How to fix the issue
I noticed the web.config for build 21.106.0024 (under Acumatica ERP 2021 R1 21.106.0024\Acumatica ERP\Files) shows the following:
<dependentAssembly>
<assemblyIdentity name="Microsoft.Bcl.AsyncInterfaces" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly>
But the installed instance of Acumatica for the same build version shows:
<dependentAssembly>
<assemblyIdentity name="Microsoft.Bcl.AsyncInterfaces" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.0.0.0" newVersion="1.0.0.0" />
</dependentAssembly>
So I commented out the 1.0 version and put in the 5.0 version and it worked:
<dependentAssembly>
<assemblyIdentity name="Microsoft.Bcl.AsyncInterfaces" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<!--<bindingRedirect oldVersion="0.0.0.0-1.0.0.0" newVersion="1.0.0.0" />-->
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly>
That workaround works for local development without issues but there is a bug with the installer I believe. Strange that the web.config looks correct from the installed files but not when a new instance is created.
EDIT:
The root cause of the error is likely that you have a reference to Microsoft DLL in your Acumatica DLL extension project.
And you also likely have a Website in the same solution which adds the extension projection reference. To check this, right click Website go to Property Pages and check in References, with Add Reference button in Project reference section.
This setup copies references automatically when you compile. You can remove copying of some references with CopyLocal=False property. However this doesn't appear to apply for Microsoft.Bcl.AsynInterfaces. Maybe you used Bind feature in Acumatica Customization page to set-up that automatic copying or created the extension C# project from the Acumatica Customization page.
In case the website is broken by a DLL file in Acumatica Bin directory. To restore original DLL files use Acumatica ERP Wizard (same version as corrupted website) and select 'Perform Application Maintenance'
Then select the corrupted site and run 'Update Only Website':
Check the date of the DLL which was previously corrupted:
Then identify the process which replaces the original DLL file shipped with Acumatica by a incompatible version and remove it. I suspect you are compiling a C# project in Visual Studio. And this project is configured to deploy files directly into Acumatica Bin directory. After compilation the date of the corrupted DLL file would change in Acumatica Bin folder.
Try removing the website from your solution if it's there and has a reference to your C# Acumatica extension project:
If there's a Post Build script (project properties-> build) that replace Acumatica DLL remove it.
Then compile to any directory that isn't Acumatica Bin folder. This is configured in C# project properties build section.
After compilation copy only the required compiled files which does not include 'Microsoft.Bcl.AsyncInterfaces.dll' to Acumatica Bin folder.
This copy operation can be done manually, with a batch file, with a post build script etc... The important thing is that it shouldn't copy DLL files which are already shipped with Acumatica.
One other possible solution is to select the same .Net Framework version that the Acumatica site uses in your own extension DLL. That way when compiling you would be replacing Microsoft DLL with the same version.
I got past this by referencing the Microsoft.Bcl.AsyncInterfaces DLL in my DLL project. The DLL project that I've made is set to put the DLL directly into the bin directory of the Acumatica web site. This works when I have the Acumatica website included in the Visual Studio project. .Net 4.8, Acumatica 2021 R2, Visual Studio 2019
The Microsoft.Bcl.AsyncInterfaces.dll that will appease Acumatica is in the C:\Program Files\Acumatica ERP\Files\Bin folder.
So I updated the Azure SDK to the 2.0 version yesterday and upgraded my projects. Everything worked fine in local, so I published to Azure. Surprise: the worker role didn't start because of the following exception
Could not load file or assembly 'Microsoft.WindowsAzure.ServiceRuntime, Version=1.0.0.0
Something similar happened when I updated to 1.8 but I don't remember the exact solution. I've tried to remove and readd the assembly, referencing to the DLL in my system, updating the NuGet packages... everything yields the same result.
Anyone has any solution to this?
Thanks!
I've not done the migration to 2.0 yet but it is on the cards.
When I last upgraded 1.7 => 1.8 I had to add the following entry to my web.config because of other external projects still referencing the old runtime
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.WindowsAzure.ServiceRuntime" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.7.0.0-1.8.0.0" newVersion="1.8.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
If you have checked your own projects and they don't refer to the old version it could be that some nuget package still contains references to the old versions.
In my case the problem was the Azure Storage Client library, which was referring to the older version of configuration package which was then referring to these version 1.8 DLLs.
Don't know what would be the best way to debug these, but the Nuget package dependency visualizer might help: Tools -> Library Package Manager -> Package Visualize
(looks like you can only create the visualizations in Visual Studio ultimate)
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.
We have webparts that use dll's which are in the GAC.
In the *.webpart file the dll is refered to in the type name tag. Here it is spesified with the version number.
Is it possible to get the web part to use a different version of the dll, without having to redeploy the webpart?
We have many pages that use the webpart. If we were to redeploy the webpart would we need to update all pages that used the webpart?
This question is very similar
SO - SharePoint features: How can I use wildcard assembly versioning?
Whilst you can use a Publisher Policy file to redirect assembly versions this is a bit of a pain to administer.
Perhaps a better way is to reserve this for major version (e.g. SharePoint v11 to v12 or .net core libraries) and for minor versions (e.g. service packs etc) use the same AssemblyVersion but a different file Version. This is exactly what Microsoft themselves use and recommend.
KB556041 - How to use Assembly Version and Assembly File Version
Suppose you are building a framework assembly for your project which is used by lot of developers while building the application assemblies. If you release new version of assembly very frequently ... and if assemblies are strong named, Developers will have to change the reference every time you release new assembly ... A better option in such closed group and volatile scenarios would be to fix the 'Assembly Version' and change only the 'Assembly File Version'.
You can tryout assembly binding in the web.config file
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.SharePoint" publicKeyToken="71e9bce111e9429c" culture="neutral" />
<bindingRedirect oldVersion="11.0.0.0" newVersion="12.0.0.0" />
</dependentAssembly>
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.