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
Related
I'm working with one application that that has and C# API. This program has different versions of it. But the api stays the same through its versions.
So i have written a managed code to one of its versions, and now i want to run the same code at different version of the application at runtime where i exactly know witch version of the app is running.
Question is:
Is it possible to replace assembly version and dll location at run time without writing unmanaged code using reflections?
Yes, you can use Assembly.LoadFrom to load an assembly. You can then use reflection to go thru the types of said assembly and call methods.
To avoid needing to use reflection for everything there should be a shared interface-assembly that define your api. There should also be a single entry point to the API. So you can use reflection find the class that implements the entry-interface, create an instance of this class and cast it to the interface. That lets the rest of the code use actual types.
You still need to be careful however, if there is any miss match between the interface and the actual types, you will get an runtime exception. You will not get an exception when the interface method is called (as might be expected), but when the method that calls the interface method is called. This due to the jitter resolving types when a method is compiled, and this is done the first time it is called.
In compiled system languages (like C/C++), generally, the entry point is resolved at link time, which gives the ability to have the main function in a DLL so the linker won't complain and set the entry point address to the symbol in the DLL (or the function in the import library, not sure about that).
I recently started using C# and I would like to do something similar, where I have the Main method in a library (which preferably build against .NET Standard) and the actual exe don't define any entry point and uses the one in the library.
I get that I could just write a Main method in the exe and call the Main of the library in it, but the point is that I would like to avoid that.
I believe Winforms and WPF provide something similar, so hopefully what I'm trying to do is possible, otherwise, please educate me on the reasons why .NET doesn't provide such mechanism.
There seems to be a misunderstanding here:
In .NET, the only difference between a DLL and an EXE is purely the presence of .entrypoint in the header, which identifies the starting method that the CLR bootstrapper calls.
If there isn't one then it's a library rather than an application. It makes no sense to have an EXE which has no .entrypoint on any method, it won't run because the CLR bootstrapper won't know what to do with it.
Winforms and WPF do not do what you claim: they have a normal .entrypoint, it just happens to be boiler plate code which you don't need to worry about.
For clarity: the actual extension of the file is somewhat irrelevant. It's perfectly legal to call an assembly whatever you want, and you can link an assembly containing .entrypoint within another one, whether or not it has .exe extension or any other.
However, Windows will only bootstrap a file automatically if it has the .exe extension, as the CLR bootstrapper itself needs bootstrapping. You can though call AppDomain.ExecuteAssembly which essentially does the same thing from within another app.
For example:
There is API a.1 in DLL A and API B.1 in DLL B.
API A.1 calls API B.1.
Is there an open source tool or method to know this call path(A.1->B.1)?
.Net assemblies contain a list of referenced assemblies. This can be inspected by tools like IL SPy.
There is no easy way to check if a specific method on one assembly may calls another assembly. You could perhaps inspect the CIL code for this, but it will require a bit more work.
There is also native dependencies, these are not listed in the same way, and use another method to load.
My analyzer will match methods with certain signatures. I would like from inside my analyzer to create an instance of the class I'm analyzing and call the method that caused the analyzer to kick in.
Assuming the source code is in a compilable state, is it possible?
Getting the class name and method name is pretty easy, but Type.GetType(...) will always return null.
The purpose of this is that I would like for my analyzer to kick in when I'm on a test method and run it, failing if the test fails.
If the code is not ready for compilation, it would be fine to just return.
It seems possible, but you'd need to check the efficiency of these solutions. Also, you can't guarantee that the code is compilable.
You can grab the Compilation object (from let's say context.SemanticModel.Compilation), call Emit on it, and write it to disc. Then use Assembly.Load to load it, and then it's simple reflection to instantiate the class, whose name you already know, and call the method on it with appropriate arguments.
Another approach would be to use the Compilation in a scripting session as a reference assembly, and use the Roslyn Scripting API to invoke the method. There is a ToMetadataReference method on the Compilation, so you could get a MetadataReference, which could be then passed to ScriptOptions.Default.AddReferences. And then you'd need to pass the resulting options instance to CSharpScript.EvaluateAsync().
There's another fundamental reason you can't run code from the user's compilation, even if it did actually compile -- it might be the wrong environment. Consider a scenario where you're targeting Windows Phone, or Xamarin Android/iOS, .NET Core on Linux, or whatever. In any of these cases the compiler has reference assemblies that you can compile against but obviously you can't actually run that code because it's targeting a different platform. People often ask why you can't convert an ITypeSymbol to a reflection System.Type and back, and this is one of the reasons why -- the compiler can compile code on platform A for platform B, when it can't actually run (or fully load) B's assemblies in the first place.
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).