I'm loading types from files found in two directories and creating an instance of each type using System.Activator. I've done this a number of times without any issue, which makes me think I'm about to learn something.
The files in the first directory are loaded without issue. At the first file in the next directory, it gets to the point of calling Activator.CreateInstance(type) and continues on without exception, but the returned instance can't be evaluated ("Could not evaluate expression"). Trying to execute the same statement in the QuickWatch window produces the above error as a value with type "object", not an exception.
What I've tried:
Reference the assembly that contains the type in question and specifically create an instance using new and the empty constructor, even from the same point that this error is about to occur. (success)
Using Activator on this type at other points in the call stack. (failure)
The type in question implements an interface, but does not subclass any other classes.
The assembly is in the AppDomain (obviously, after referencing it specifically).
Moving the implementing assembly to a different location. (failure)
I'm at the point that I don't even know what to check, I've never seen this before.
This is Visual Studio 2013, .NET 4.5. I can't find any references to this error in the context of Activator.CreateInstance. The only single instance I can find of this error had no resolution. I don't expect the information I've provided to lead to a resolution, but if I can at least find out possible causes, I can research my own solutions.
Try turning on Fusion Logging and check out what fusion is doing and make sure it is able to find + load the assembly.
Scott Hanselman - Back to Basics: Using Fusion Log Viewer to Debug Obscure Loader Errors
At the time you load it there could be a plethora of issues.
Some I have come across:
Another version (possibly previous) of the given assembly has been loaded with this type missing.
This assembly fails to load due to another incompatible version of its dependencies being loaded.
Related
I’m working with a .NET 4 application written mostly in C#. The application has a user interface, but it also has an automation interface that allows the features of the application to be exploited directly from a .NET client. It also supports automation via COM, and for this there are “COM adapter” DLLs that present the classes/methods in the “real” DLLs in a COM-friendly way.
For example, let’s say the API for the bulk of the functionality is in a DLL called “Alpha.DLL”: a .NET client can simply reference that DLL directly, but a separate DLL called “Alpha.Com.DLL” is provided for use by COM clients (e.g. VBA).
There are 3 such COM adapter DLLs, and while two work fine, I simply cannot get the last one to work correctly.
The problem DLL only has two classes defined within it, and while I can instantiate one of them from a COM client such as VBScript, I get an error when I try to instantiate the other. The error I get is:
-2146234304 (0x80131040) Automation Error
I can instantiate the same class from .NET code, just not from a COM client.
I’ve tried using FUSLOGVW.EXE to look for assembly-loading errors, but there don’t seem to be any (and in any case, the fact that I can instantiate the other class from the same DLL suggests that it’s not the DLL itself that can’t be found/loaded?).
I’ve tried attaching a debugger and putting a breakpoint inside the constructor for the offending class, but it doesn’t get hit when I try to instantiate the class from VBScript. (A breakpoint in the constructor of the class that works does get hit).
I’ve checked the registry entries for the class I’m trying to instantiate, and I can’t see any problem. The GUIDs and version numbers all seem to match up.
I’m all out of ideas, and at the end of my tether, and I’d be extremely grateful for some help…
-2146234304 (0x80131040) Automation Error
The common problem with using .NET code from a COM client like VBA is that .NET exceptions get rather difficult to diagnose. You have to make do with an often cryptic HRESULT error code, you don't get the Holy Stack trace to see how code blew up. This exception is a doozy like that, it is FUSION_E_REF_DEF_MISMATCH, you can find these HRESULT codes in the CorError.h SDK include file.
You'd normally get the easier to interpret exception message "The located assembly's manifest definition does not match the assembly reference". And the stack trace to tell you what type caused this exception so you'll know what assembly is the problem. Nothing like that when this failed when called from VBA.
It is otherwise an every-day .NET mishap, the CLR found your assembly but its [AssemblyVersion] does not match the reference assembly's version that your code was compiled with. COM certainly increases the odds that this can go wrong, the version is recorded in the registry when you register the assembly with Regasm.exe. Forgetting to re-register if you do it by hand instead of letting the build system take care of it is a very easy oversight. Also very easy to copy dependent DLLs in the client EXE's directory, so the CLR can find them, and forgetting to update them.
Fuslogvw.exe does show this kind of mishap, hard to guess why you don't see anything. The backup plan is to use SysInternals' Process Monitor. It also shows you how the client is reading the registry, another thing that often goes wrong in COM. And you'll see it locating the DLL from the registry key so you'll have a shot at guessing why it found an old one.
Stay out of trouble by using the GAC, often necessary anyway to help the CLR to find dependent assemblies and to solve COM's rather severe DLL Hell problem. And strongly consider using the .NET 4 AppDomain.FirstChanceException event. Good to log exceptions before they turn undiagnosable in the COM client.
please check first
your com dll is placed into GAC
you dont't forget about regasm
http://www.jagjot.com/2014/01/register-c-vb-net-dll-regasm-gacutil/
check cpu architecture
does your com dll depends on anything outside GAC?
Aaargh. I found the problem. I said in my question:
I’ve checked the registry entries for the class I’m trying to instantiate, and I can’t see any problem. The GUIDs and version numbers all seem to match up.
...which was true. However, what I had not noticed was that in the registry definition of one of my classes, the public key token was wrong.
This explains why one class could be instantiated while the other could not, and possibly why there was nothing in the FUSLOGVW log (because the assembly was loaded OK when an instance of the "good" class was created).
Thanks for your help, Hans and Dimzon.
I came across the following in a code review:
Type type = Type.GetType(typeName);
if (type == typeof(SomeKnownType))
DoSomething(...); // does not use type or typeName
typeName originates from an AJAX request and is not validated. Does this pose any potential security issues? For example, is it possible for unexpected code to be executed, or for the entire
application to crash (denial of service), as the result of loading arbitrary types from arbitrary assemblies?
(I suppose some joker could attempt to exhaust available memory by loading every type from every assembly in the GAC. Anything worse?)
Notes:
This is an ASP.NET application running under Full Trust.
The resulting type is only used as shown above. No attempt is made to instantiate the type.
No, this is not safe at all. Type.GetType will load an assembly if it has not been loaded before:
GetType causes loading of the assembly specified in typeName.
So what's wrong with loading an assembly? Aside from it using additional memory as Daniel points out, .NET assemblies can execute code when they load, even though this functionality is not exposed to normal compilers like C# and VB.NET. These are called module initializers.
The module’s initializer method is executed at, or sometime before, first access to any types, methods, or data defined in the module
Just the fact that you are loading an assembly and examining its types is enough to get the module initializer to run.
Someone with a cleverly written assembly (say by using ilasm and writing raw MSIL) can execute code just by getting the assembly loaded and you examining the types. That's why we have Assembly.ReflectionOnlyLoad, so we can safely load the assembly in a non-executable environment.
I did a little more thinking about this and thought of a few more cases.
Consider that your Application Pool is set to run 64-bit. Now imagine that your attacker uses the AJAX service to attempt to load an assembly that is strictly for x86 architecture only. For example, there is one in my GAC called Microsoft.SqlServer.Replication that is x86 only, there is no AMD64 counter-part. If I ask your service to load that assembly, you'd get a BadImageFormatException. Depending on what guard clauses you have in place around loading the assembly, unhandled exceptions could completely bring down your AppPool.
It could eat up memory potentially if the libraries aren't in memory.
I would have a Dictionary<string, Type> as an allowed list.
var whitelist = new Dictionary<string, Type>;
whitelist.Add("MyType", typeof(MyType));
There is no inherit danger in referring to the type itself. Trust in .NET is at the assembly level. If there's no available assembly that contains the specified type, your call will just return a null. Accordingly, somebody has to make the assembly available for the code -- assemblies don't just appear out of thin air.
I have the following situation.
Assembly D contains class Data.
Assembly F1 contains class, which creates, fills and returns Data.
Assembly F2 contains class, which accepts Data as input.
The trick is, that all of these assemblies are plugins and are loaded dynamically. Of course both F1 and F2 references D, but in the runtime all three are loaded by host application.
Now what happens if someone replaces D binary file with newer version, which has a different interface?
I wrote a test application, which did something like that, with the following results:
Adding new field in class Data causes no exception;
Replacing the existing field with another one results in TargetInvocationException with information, that requested field does not exist
If .NET keeps track of the interface calls, I'm fine. That's because accessing the unchanged part of library will simply work and if that part changes, I'll get an exception simply telling me that. So it will either work (on the interface level) or not - no undefined behavior.
My questions:
How are the types resolved in the runtime - especially in case of non-matching assembly versions? Does .NET keep track of field/property/parameter/return value types and names?
Is there a way to force the referenced assembly to be required in some specific version?
Your second question: In Visual Studio there is a easy way to force your application to use a specific version of a referenced assembly. Simply click on the assembly under references and look at the properties. There is a property called "Specific version". If you set it to true and load another at run time, you will get an exception.
Your first question: I don't know exactly how .Net determines, when it is able to use an assembly, that it was not compiled with. So if the signature of a class/interface changes, .Net will throw an exception. I think .Net simply tries to use the new assembly and throws an exception if the methods/properties in the class/interface in the new assembly has a modified signature.
I have a program which needs to use a large number of plugins.
Each plugin must support a very basic interface, this interface is defined in a DLL (IBaseComponent for simplicity of question sake).
Each plugin will be in a specific directory (AppDirectory\plugin\plugin-type).
Each plugin can have any name for the plugin's dll (AppDirectory\plugin\plugin-type\plugin-name.dll).
So I need to check through each plugin subdirectory, find each plugin that has a class which supports the IBaseComponent interface, instantiate the class and call some functions on the plug in.
ok, all fine and dandy, none of this is particularly hard. The problem though is that I seem to be running into some weird issues.
Every plugin needs to have the Base.dll file in the individual plugin folders (instead of just in the program that will be loading the plugin) and also it seems that I get many errors and warnings around dynamically loading a dll which have dll's that also need to be loaded.
I'm using:
pluginModule = System.Reflection.Assembly.ReflectionOnlyLoadFrom(PathToAssembly);
in order to grab the plugin dll and using:
types = moduleAssembly.GetTypes();
in order to grab the types contained within the dll.
I am iterating over the types and checking if the individual type is of the IBaseComponent interface (signifying this is a valid to load class) with:
if (type.GetInterface("FrameworkNameSpace.IBaseComponent") != null)
//it's of the IBaseComponent interface
Later, in order to actually create an instance of the class from the dll I use:
pluginModule = System.Reflection.Assembly.LoadFrom(PathToAssembly);
and then use:
types = component.GetTypes();
In order to get the types within the module then select and load the class which supports the interface same as above.
The problem seems to be on when I use:
types = component.GetTypes();
When actually trying to load the class, Instead of simply looking at it. (Hence my different usage of LoadFrom and ReflectionOnlyLoad)
The Exception I receive on the GetTypes call (on a second plug in, but never the first!) is:
{"Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information."}
With the LoaderExceptions property as:
{"The specified module could not be found. (Exception from HRESULT: 0x8007007E)":null}
I'm unsure why this occurs. The DLL is in the plugin folder, and the DLL containing the IBaseComponent interface is also in every one of the plugin directories. Am I going about this the wrong way?
Also is it required for me to keep a copy of the DLL containing IBaseComponent within each plugin subdirectory as well as the one used by the program itself, or am I doing something incorrectly that would allow me to remove this requirement?
I am aware of MEF which is what I wanted to use but unfortunately because I am required to support this on .net 2.0 I am unable to use MEF.
This is a LoadLibrary() failure. Sounds to me that you plugins have a dependency on some unmanaged DLLs. Yes, Windows is going to have a hard time finding these DLLs, it has no reason to look in the plugin directories. Maybe it works the first time because your app's default directory happens to be set to the correct directory. Which would then also be the workaround, use Environment.CurrentDirectory.
Finding out exactly which dependencies can not be found is key. Unmanaged ones are not going to show up in fuslogvw.exe, you can dig it out of a trace from SysInternals' ProcMon utility.
Occasionally, I see that typeof(Foo) returns null. Why would this happen?
This is in C#, .NET 3.5.
I thought it might have something to do with the assembly containing the type not yet being loaded, but a test app shows that the assembly is loaded at the start of the method where typeof is used.
Any ideas?
Update 1
I can't provide a reproducible sample as this happens on a huge application
When I say 'occasionally' I mean in the same method in my application but during various instances. Also, when it fails once when running, it'll fail every time for that instance of the application.
Update 2
The application in question uses a huuuuuge amount of memory and runs on 32bit XP. I'm thinking maybe it's a TypeLoadException or OutOfMemoryException that's somehow being swallowed (but I can't see how, as I've tried this with first-chance exceptions turned on in the debugger).
Update 3
Ran into the same issue just now. Here's the stack trace:
The code up to this point is literally just:
Type tradeType = typeof(MyTradeType)
TradeFactory.CreateTrade(tradeType)
(before, it was ..CreateTrade(typeof(MyTradeType)) so I couldn't actually tell if the typeof returned null)
So, it looks like typeof() isn't returning null but it's getting set to null by the time it ends up in the CreateTrade method.
The exception (NullReferenceException) has a HResult property of 0x80004003 (Invalid pointer). A call to System.Runtime.InteropServices.Marshal.GetLastWin32Error( ) (in the Immediate Window) returns 127 (The specified procedure could not be found).
I've looked in the Modules window and the module that contains this type and method has been loaded and there doesn't look to be any loader errors.
Has loading the dll failed for some reason? Have you checked the fusion logs.
I'd assume this would cause more problems than just this, but if you're doing this check before using anything from the assembly, it may be hiding any further problems.
Since typeof(T) is a compile time operator the loading-time of the assembly won't be involved.
It would be interesting to see some code that demonstrates this.
Even more interesting to see it happen sometimes and sometimes not.
A first answer might be : use GetType() on an instance.
typeof determines the type during the compile time. So even if it returns null then it should return null always. Because the behavior does not change during the runtime. Give some code snippet some other stuff is broken.
I was having this problem in my VSPackage project when using typeof(MyClass) in the package's constructor. I moved my code to the overridden Initialize() method and then it worked fine, so it looks like the assembly not being loaded yet may be a factor in this error some times. I'll note too that my VSPackage is loaded at run-time into Visual Studio via MEF, so this likely isn't your typically scenario, but still thought I'd mention it.
This is quite possible and very easy to reproduce.
typeof(T) will return null if the type has been created in memory.
Through System.Reflection.Emit for example.