Why does loading System.Data 4.0.99.99 succeed? - c#

To our surprise, the following statement does not throw an exception!
Assembly.Load("System.Data, Version=4.0.99.99, Culture=neutral, PublicKeyToken=b77a5c561934e089");
The GAC contains only the version 4.0.0.0 - there is no 4.0.99.99. Note that trying to load 4.1.0.0 fails. We observed this behavior for .NET framework assemblies only.
Why is that so? Are there any default assembly binding redirects for .NET framework assemblies in place? Is there some other magic going on?
To my knowledge, strongly-named assemblies should only be loaded if the exact same version is found.

As Hans Passant mentioned in the comments, the CLR contains a retargeting mechanism for framework assemblies that redirects references to old framework libraries to newer ones. You can see that mechanism at work by looking at the Fusion Log (using fuslogvw.exe and configuring it to log all binds to disk), which contains the information "Version redirect found in framework config":
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\Users\fabian.schmied\Desktop\Temp\ConsoleApplication3\ConsoleApplication3\bin\Debug\ConsoleApplication3.exe.Config
LOG: Using host configuration file:
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Version redirect found in framework config: 2.0.0.0 redirected to 4.0.0.0.
LOG: Post-policy reference: System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
LOG: Found assembly by looking in the GAC.
In your sample, the Fusion log contains an equivalent line:
LOG: Version redirect found in framework config: 4.0.99.99 redirected to 4.0.0.0.
From that, I conclude that the same mechanism comes into play here. It seems that all references to System.Data up to 4.0.65534.65534 are redirected to 4.0.0.0.
(For versions starting from 4.1.0.0, the retargeting no longer kicks in.)

Related

Could not load file or assembly 'Microsoft.Data.SqlClient' in .NET standard Library

I've created a .NET standard library 2.0 which uses Microsoft.Data.SqlClient Version=1.12.20106.1. I'm referring to this library in the console application (.NET Framework 4.7.2). While making call, I'm getting the error shown below, even though I've added an assembly reference. Can anyone help please?
Could not load file or assembly 'Microsoft.Data.SqlClient, Version=1.12.20106.1, Culture=neutral, PublicKeyToken=23ec7fc2d6eaa4a5' or one of its dependencies. The system cannot find the file specified.":"Microsoft.Data.SqlClient, Version=1.12.20106.1, Culture=neutral, PublicKeyToken=23ec7fc2d6eaa4a5"}
Chances are that in the full error you will see something like
The located assembly's manifest definition does not match the
assembly reference. (Exception from HRESULT: 0x80131040)
When I experience a similar problem and run a unit test in the debugger then I see this sort of thing in the unit test output Pre-bind state information
Pre-bind state information
LOG: DisplayName = Microsoft.Data.SqlClient, Version=2.0.20168.4, Culture=neutral, PublicKeyToken=23ec7fc2d6eaa4a5
(Fully-specified)
LOG: Appbase = file:///C:/Dev2/MyApp/UnitTests/bin/Debug
LOG: Initial PrivatePath = NULL
Calling assembly : MyApp, Version=1.0.0.2, Culture=neutral, PublicKeyToken=c.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\Dev2\myapp\UnitTests.dll.config
LOG: Using host configuration file:
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config.
LOG: Redirect found in application configuration file: 2.0.20168.4 redirected to 1.12.20106.1.
LOG: Post-policy reference: Microsoft.Data.SqlClient, Version=1.12.20106.1, Culture=neutral, PublicKeyToken=23ec7fc2d6eaa4a5
LOG: Attempting download of new URL file:///C:/Dev2/MyApp/UnitTests/bin/Debug/Microsoft.Data.SqlClient.DLL.
WRN: Comparing the assembly name resulted in the mismatch: Major Version
ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.
The issue is an assembly binding issue the answer here may help. Don't worry that it mentions VB6 the actual issue is independent of that.
This answer is only useful if your netstandard2.0 library has referenced Microsoft.Data.SqlClient as a NuGet package and the referred assembly is not copied over on build.
You may have to use dotnet publish to have the Microsoft.Data.SqlClient assembly copied. It's something that I stumbled upon lately and that I had to fix using a custom resolver. You shouldn't use that resolver but you should check if publishing your application and library helps the issue.

Failure to load System.runtime dll on Visual studio WebApi project

When i run the portal it gives the following error:
Could not load file or assembly 'System.Runtime, Version=4.0.0.0,
Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its
dependencies. The located assembly's manifest definition does not
match the assembly reference. (Exception from HRESULT: 0x80131040)
=== Pre-bind state information ===
LOG: DisplayName = System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
(Fully-specified)
LOG: Appbase = file:///D:/.....
LOG: Initial PrivatePath = ....\bin
Calling assembly : System.Runtime.CompilerServices.Unsafe, Version=4.0.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: ....\web.config
LOG: Using host configuration file: ....\aspnet.config
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Redirect found in application configuration file: 4.0.0.0 redirected to 4.1.1.0.
LOG: Post-policy reference: System.Runtime, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
LOG: The same bind was seen before, and was failed with hr = 0x80131040.
System.Runtime is a Microsoft package that is part of the webapi project.
Observing the Pre-bind state information it shows that the system.runtime dll is being called from System.Runtime.CompilerServices.Unsafe dll. Also the following redirect is made:
LOG: Redirect found in application configuration file: 4.0.0.0
redirected to 4.1.1.0.
The System.Runtime Package version is 4.3.0 and generates dll version 4.1.1.0.
This is my first doubt. I thing dll version should be 4.3.0.0 but inspecting with ILSpy it shows that the Assembly version attribute is 4.1.1.0
Web config redirect is correct, it redirects the call to version 4.0.0.0 to
version 4.1.1.0 as show in the Pre-bind log
The odd thing is that System.Runtime doesn't show in the references of the project. If i add it manually it gets an yellow icon (fail).
What is wrong here? What more can i check?
Found out that the problem was caused by a version conflict and not by an incompatible version as i expected.
The follow build warning exposed the conflict. Just need to double click on the warning message to fix the binding session on the web conflict.
Warning Found conflicts between different versions of the same
dependent assembly. In Visual Studio, double-click this warning (or
select it and press Enter) to fix the conflicts; otherwise, add the
following binding redirects to the "runtime" node in the application
configuration file: ...
I am not sure if Visual studio will be able to detect all build conflicts,so the absence of this warning may still be caused by the same error.

System.Io.FileNotFoundException for System.Core while using Ninject in .Net 3.5

I'm using Ninject (v3.2.2.0) with a tool built on a .net 3.5 framework. This had been fine - up until a couple of weeks ago when I put aside development.
I've picked it up again to prepare for the release, and it is no longer fine - it still compiles without issue, but I now get a FileNotFoundException whenever I try to run the it:
System.IO.FileNotFoundException occurred
Message=Could not load file or assembly 'System.Core, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' or one of its dependencies. The system cannot find the file specified.
Source=Ninject
FileName=System.Core, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
FusionLog=Assembly manager loaded from: C:\Windows\Microsoft.NET\Framework64\v2.0.50727\mscorwks.dll
Running under executable E:\work\wire\M\Tools\Import\bin\Debug\Import.vshost.exe
--- A detailed error log follows.
=== Pre-bind state information ===
LOG: User = ZOO\TAL
LOG: DisplayName = System.Core, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e (Fully-specified)
LOG: Appbase = file:///E:/work/wire/M/Tools/Import/bin/Debug/
LOG: Initial
PrivatePath = NULL
Calling assembly : Ninject, Version=3.2.0.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7.
LOG: This bind starts in default load context.
LOG: Using application configuration file: E:\work\wire\MR\Tools\Import\bin\Debug\Import.vshost.exe.Config
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v2.0.50727\config\machine.config.
LOG: Post-policy reference: System.Core, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
LOG: Attempting download of new URL file:///E:/work/wire/M/Tools/Import/bin/Debug/System.Core.DLL.
LOG: Attempting download of new URL file:///E:/work/wire/M/Tools/Import/bin/Debug/System.Core/System.Core.DLL.
LOG: Attempting download of new URL file:///E:/work/wire/M/Tools/Import/bin/Debug/System.Core.EXE.
LOG: Attempting download of new URL file:///E:/work/wire/M/Tools/Import/bin/Debug/System.Core/System.Core.EXE.
StackTrace:
at Ninject.Planning.Bindings.BindingConfiguration..ctor()
at Ninject.Planning.Bindings.Binding..ctor(Type service)
at Ninject.Syntax.BindingRoot.BindT
at Ninject.KernelBase..ctor(IComponentContainer components, INinjectSettings settings, INinjectModule[] modules)
at Ninject.StandardKernel..ctor(INinjectModule[] modules)
at Import.ImportBootstrapper.Import(String[] xiArgs) in
e:\work\wire\M\Tools\Import\ImportBootstrapper.cs:line
16 InnerException:
I've taken this to its extreme - I'm currently trying to run only the following code:
using Ninject;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
new StandardKernel();
}
}
}
Which again, compiles just fine, but as soon as I get to new StandardKernal(); line it breaks with the same error as above.
It's also all in source control, so I've loaded this up on a colleague's system, references, libraries, configs and all, and yep, it runs fine on their machine.
To try and fix this, I have:
Made sure that the referenced System.Core file exists (it does).
Made sure that it has the correct permissions.
Ensured that System.Core definitely existed in GAC - it did, and the results are below:
C:\> gacutil -l | find /i "system.core"
System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL
System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL
In "Turn Windows features on or off", removed .NET Framework 3.5, rebooted, reinstalled .NET 3.5, rebooted again, tried to run the program.
Installed all available windows updates (initally the .NET ones, but eventually all of them).
Tried to find issues with sfc /scannow, to no effect.
Tinkered with various supportedRuntime versions in the App.config file:
<configuration>
<startup>
<supportedRuntime version="v2.0.50727"/>
<supportedRuntime version="v3.5.30729"/>
</startup>
</configuration>
(Having either, both, or neither makes no discernible difference)
Made sure that the Reference files definitely included System.Core (<Reference Include="System.core" />).
Made sure that the project properties are definitely set to .Net 3.5.
I've also looked into the machine.config and web.config files. Nothing looked at fault, but I'm not sure I'd be able to identify if something was obviously wrong, so I can't say that this avenue of research is closed off.
I'm now completely at a loss. I mean, short of getting a new PC and starting from there.
What am I doing wrong?
Add Website with new Application Pool.
We faced the same issue and fixed by creating a new website and application pool in IIS.

Interop error with earlier versions of Framework

I have a COM object that is referenced in my project. When I build the project with target framework 4.5 everything works. However if I change the target framework to 3.5 (or 2.0), the code throws an exception when trying to instantiate the class using DLLName.exe (I presume it is an ActiveX EXE)
The following is the error (I translated it from a foreign language so it may not be exact):
System.BadImageFormatException: Could not load file or assembly 'Interop.DLLname, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies.. This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded.
File name: 'Interop.DLLname, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'
....
Assembly loaded from: C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll
Running under file execution C:\Users\Admin\Documents\Visual Studio 2012\Projects\....t\bin\Debug\EXEname.vshost.exe
#NAME?
=== Pre-bind state information ===
LOG: User =
LOG: DisplayName = Interop.DLLname, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
(Fully-specified)
LOG: Appbase = file:///C:/Users/Admin/Documents/Visual Studio 2012/Projects/............/bin/Debug/
LOG: Initial PrivatePath = NULL
Assembly calls : EXEname, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
....
LOG: Using computer file configuration from C:\Windows\Microsoft.NET\Framework\v2.0.50727\config\machine.config.
....
ERR: Failed to complete assembly definition (hr = 0x8013101b).
I have tried to remove interop.DLLname.dll from the bin/obj folders, I have checked that all the projects in the build are targeting Framework 2.0
Am I missing something else?
You are getting this error because the com wrapper dll (interop.DLLname.dll) was generated for .net 4.5, obviously it can not be used in earlier versions of .net due to the different CLR version. You need to get the wrapper for .net 2.0 and reference it. Here is link on how to generate a com wrapper http://msdn.microsoft.com/en-us/library/ms404285%28v=vs.80%29.aspx
The only solution that worked in this case was to install Visual Studio 2008 and create the interop there.

Why do I get System.IO.FileLoadException: Could not load file or assembly, about once a week on my ASP.Net Website?

I have a rather simple internal ASP.Net Website that has issues loading the Microsoft.Practices.EnterpriseLibrary.Data dll about once a week. Here is the Exception message:
System.IO.FileLoadException: Could not load file or assembly 'Microsoft.Practices.EnterpriseLibrary.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. Access is denied.
File name: 'Microsoft.Practices.EnterpriseLibrary.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null'
at foobar.Intranet.Logic.Data.UserDB.SelectByUserName(String userName)
at foobar.Intranet.Logic.Info.User.ValidateUser(String userName) in F:\Development\foobar\foobar\foobar.Intranet.Logic\Info\User.cs:line 130
at Login.ValidateUser(String username, String password) in e:\foobar\foobar.Intranet\Login.aspx.cs:line 32
=== Pre-bind state information ===
LOG: User = Unknown
LOG: DisplayName = Microsoft.Practices.EnterpriseLibrary.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null
(Fully-specified)
LOG: Appbase = file:///E:/foobar/foobar.Intranet/
LOG: Initial PrivatePath = E:\foobar\foobar.Intranet\bin Calling assembly : foobar.Intranet.Logic, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: E:\foobar\foobar.Intranet\web.config
LOG: Using host configuration file: \\?\C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet.config
LOG: Using machine configuration file from C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL file:///C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/Temporary ASP.NET Files/foobar.intranet/668896d8/82d7e51c/Microsoft.Practices.EnterpriseLibrary.Data.DLL.
LOG: Attempting download of new URL file:///C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/Temporary ASP.NET Files/foobar.intranet/668896d8/82d7e51c/Microsoft.Practices.EnterpriseLibrary.Data/Microsoft.Practices.EnterpriseLibrary.Data.DLL.
LOG: Attempting download of new URL file:///E:/foobar/foobar.Intranet/bin/Microsoft.Practices.EnterpriseLibrary.Data.DLL.
ERR: Failed to complete setup of assembly (hr = 0x80070005). Probing terminated.
Things of note:
A simple IIS Reset fixes the issue.
We had the same code running on a single webserver with no problems. We then moved the site to two new, load balanced (using sticky sessions) webservers (all three Windows Server 2003 R2 Standard Edition SP1). Now each of the load balanced webservers throw this exception about once a week just out of the blue.The only major difference I can think of, is I've installed the 4.0 .NET framework on the load balanced servers. The website is still running under ASP.NET 2.0 so I don't see how this would be an issue
I've configured the indexing service to not search the "Temporary ASP.NET Files" folder, but it didn't help.
We use the Microsoft.Practices.EnterpriseLibrary.Data dll everywhere on our site. Almost every single page uses our logic dll which in turn utilizes the EnterpriseLibrary dlls.
While the errors where happening once, I even looked to see what processes were locking the dll in the "Temporary ASP.NET Files" folder, and it wasn't any different than the locks on the server that was working fine.
Once the error starts, it errors every single time until an iisreset is performed
Any insight anyone could offer would be much appreciated. Let me know if I missed something.
Thanks!
Take a look at the Assembly Binding Log Viewer. It might point you in the right direction.
I had a quick look at other SO answers and one person suggested that the application may have been developed against a signed version of the DLL but the production runtime only has access to an unsigned version. It looks like your production is loading an unsigned assembly (PublicKeyToken=null).
Install the below nuget packages:
Install-Package log4net -Version 2.0.0
Install-Package linqtoexcel
Install-Package System.Data.Sqlite.x86 -Version 1.0.88.0
Install-Package ServiceStack -Version 3.9.71
Install-Package ServiceStack.OrmLite.Sqlite32 -Version 3.9.71

Categories