I'm trying to get the first executing assembly using the following code:
AssemblyName entryAssembly = Assembly.GetEntryAssembly().GetName();
I'm getting a null exception though. The GetExecutingAssembly() and GetCallingAssembly() functions do return values though. In the documentation, it mentions that it can return null when called from unmanaged code. I don't think my code falls into this category.
I'm running a ASP.NET MVC 2 application in Visual Studio using the Visual Studio Development Server.
Any ideas why I'm getting a null?
This is by design. Quote from Gendarme (note: I'm quoting myself):
This rule warns when an assembly without an entry point (i.e. a dll or
library) calls Assembly.GetEntryAssembly (). This call is problematic
since it will always return null when called from outside the root
(main) application domain. This may become a problem inside libraries
that can be used, for example, inside ASP.NET applications.
from https://github.com/spouliot/gendarme/wiki/Gendarme.Rules.BadPractice.GetEntryAssemblyMayReturnNullRule%282.10%29
Edit: the above answer the 'why' (your stated question). A possible workaround it to create a StackTrace and iterate each StackFrame until the top to see from which assembly it comes from. However this will only work, like you wish, when done from the main (web) application thread (i.e. take great care on where this is called from).
Related
I've read docs for GetEntryAssembly and GetExecutingAssembly trying to make sense of the difference between them. I simply fail to understand how the definitions relate to each other. Altough I see two different formulations, I can't understand the distinction implied. In my head, it's a potayto-potahto situation, which is reinforced by the same contents on my screen when I try to display the values of each returned Assemby object.
Naturally, there must be some difference and it's simply my competence that prevents me from realizing what it is. So I've done some research, only discovering that most of the wisdom out there is about obtaining the path. The lonely resource that was explicitly targeting the comparison between them was here.
Can I ask for a specific example where those two methods return objects the contents of which differ? Preferably with a brief explanation of why.
Let's say you have a console project MyConsoleProject that references library project MyLibrary. Inside MyConsoleProject both Entry and Executing assemblies will be the same. But inside MyLibrary the ExecutingAssembly will refer to library project, not the console one.
GetExecutingAssembly:
Gets the assembly that contains the code that is currently executing.
GetEntryAssembly returns:
The assembly that is the process executable in the default application domain, or the first executable that was executed by ExecuteAssembly(String). Can return null when called from unmanaged code.
The GetEntryAssembly method can return null when a managed assembly has been loaded from an unmanaged application. For example, if an unmanaged application creates an instance of a COM component written in C#, a call to the GetEntryAssembly method from the C# component returns null, because the entry point for the process was unmanaged code rather than a managed assembly.
References:
Assembly.GetEntryAssembly Method - https://learn.microsoft.com/en-us/dotnet/api/system.reflection.assembly.getentryassembly
Assembly.GetExecutingAssembly Method - https://learn.microsoft.com/en-us/dotnet/api/system.reflection.assembly.getexecutingassembly
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.
I want to "hot" load some pre-packaged assembli(es) into a separate AppDomain, the thing however is I do not know the name of the entry point class or even the assembly file. I need to find this entry point so I can run some initialization routine.
So what I intend to do is to run ReflectionOnlyLoad on all the files and find the one that follows a certain convention ie. annotated/implements a certain interface etc.
Question is, will I start leaking memory if I were to run ReflectionOnlyLoad from the main AppDomain over and over? If this can't be run from the main app domain, what are my options, because again I do not know where the entry point is.
Also any additional information about the subtleties in using ReflectionOnlyLoad is appreciated.
I recommend Mono.Cecil. It's a simple assembly you can use on .net (it doesn't require the Mono runtime). It offers an API to load assemblies as data, and works pretty well. I found the API easy to work with, and it suffered from none of the problems I experienced when using reflection-only-load.
You can also use CCI, which is an open source project by MS that offers an assembly reader.
See also: CCI vs. Mono.Cecil -- advantages and disadvantages
ReflectionOnlyLoad won't solve your problem, see docs
Why don't you execute the code for finding the entry point etc. in the new AppDomain?
Cannot reflect through the dlls. Even with reflection only load, the type sticks to the main AppDomain.
2 Solutions:
Put the entry point in an xml somewhere and parse that.
Use a
2 stage AppDomain, one for the reflector, and then another for the
actual object.
I picked (1) since it's the most sensible.
(2) I have to pass through 2 separate proxies in order to issue command to the actual remote object, that or I need to couple the interfaces much more closely than I like. Not to mention being a pain to code.
Lets say I have two .dlls, Dll1 and Dll2.
DLL1 uses or makes calls into DLL2.
Is there a way I can ensure that it is DLL1 and only DLL1 who's making the calls into DLL2?
UPDATE 1
The reason behind this is:
I have a WinForms solution, and to keep it simple, it consists of a view project and a controllers project (which generates a seperate .dll). After installing the application on a client machine, I realise it is possible to view the application .dlls in it's "Program Files" folder. Somebody could potentially add a reference to the controller's .dll. I'd like to avoid this so that it's the view project and only the view project who's making the calls.
UPDATE 2
One of the reasons I like separating controllers into a separate project is that I could potentially have many different view projects calling into and using the same controllers. I then would only need to maintain one controller project for all views. For instance a win forms application and a test project or even a web site using the same controller project. But taking this approach , I would then be faced with the security problem I mention (avoiding and controlling improper use of my dll).
So I have one approach, compiling to one .dll, by using different folders, which I believe is correct and solves my security problem, but it conditions me to only having one view.
On the other hand if I have separate projects I am faced with the security issue.
I am still dubious as to how I should go about this as I would still like to continue using different projects for the reasons I mention.
UPDATE 3
Any suggestions on using the StrongNameIdentityPermission permission demand?
http://msdn.microsoft.com/en-us/library/ff648663.aspx (see: Restrict Which Code Can Call Your Code)
http://blogs.msmvps.com/manoj/2004/10/20/tip-strongnameidentitypermission/ http://www.morganskinner.com/Articles/StrongNameIdentityPermission/
Thanks
You can make all types in DLL2 internal and use InternalsVisibleToAttribute in it set to DLL1.
To ensure that this will not be subverted, you should sign DLL1 and make sure you use its public key in the attribute.
Alternatively, as the author of both DLLs, consider combining the projects into one - set all the public methods that exist in DLL2 to internal, as before, but now only DLL1 exists and they can only be accessed by it.
Note: All the above assumes no reflection is used.
You can using Reflection to check the current callstack. Said that I probably wouldn't do it as it's costly and slow.
You can get the stacktrace this way:
using System.Diagnostics;
// get call stack
StackTrace stackTrace = new StackTrace();
// get calling method name
Console.WriteLine(stackTrace.GetFrame(1).GetMethod().Name);
You could merge the output into a single exe with ILMerge
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.