How to print the current code, which executes a program in runtime? - c#

I have an application ( web-service ).
I want to print some function's hints/description of it, but NOT from the DB, textfile or other prepared context, BUT from the current web-service, which is running in live mode.
I want just to copy the source code of it and then post it via web to the client for showing the real function definiton in realtime/runtime. It's important to make him always available to look the fresh changes and for NOT depending on perviously required prepared context for hints.
Are there any suggestions?
I know, that CLR metadata is easy to disassemble and may there is a way to do it for my aim, what do you think?

You can not access the code of the function in execution, but I doubt that you actually need a code of the function itself, instead you need a definition of the function.
For this you can use StackTrace class, that provides information about StackTrace at runtime.

This future you can be implemented only by embedding your classes and methods with attributes after the assembly has been built only. The logic is:
Build you assembly
On post-build execute utility which:
gets as parameters you assembly and path to source code
finds methods' and classes' definitions in source code files
using somesthing like PostSharp adds attribute to every method and class of your assembly (attribute will contain method or class code)
at runtime service will find this attribute value and will use it as you need.

Related

How to run managed code on different version assemby

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.

How do I know that a method in a DLL calls a method of another DLL?

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.

Difference between GetEntryAssembly and GetExecutingAssembly

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

get information on an assembly

I want to get information on an Assembly in my C# application. I use the following:
Assembly.GetCallingAssembly();
This works perfectly returning information on the calling Assembly.
I want to share this functionality with other applications, so I include this in a class in my class library.
I reference this class library in multiple applications. When I make a call to this method from my applications, it returns information on the class library and not the application. Is there a way I can alter my above code to return information on the web applications assembly while still having the code included in the class library?
Instead of having the class library being intelligent why don't you have the caller pass an Assembly as argument to the method? So when you call the method from within some application you would pass Assembly.GetExecutingAssembly() and the method within the class library will now be able to fetch the assembly of the actual caller.
I'm not sure what you provide on top of reflections, but maybe you're abstracting a facility that doesn't need to be abstracted. Reflections already handles this, so why not let it do its job?
But if this API gives you back some useful information (such as plugging nicely into your database, etc), then maybe your approach makes some sense. But I still recommend that you refactor it:
Put this code in only one shared project/assembly, and just link that project/assembly when you need to call that functionality. Needing to duplicate code to get your job done is considered code smell.
Take an Assembly object as a parameter, rather than trying to determine the current assembly. This will allow more flexibility in case you come up with some code that wants to get data on a bunch of other assemblies, and will still allow you to pass the current assembly. (Note: Darin already made this point)

How to get Classes and methods from a .cs file using Reflections in C#.?

How to get the classes that are available in a '.cs' file.? Like we can get the classes and methods in an Assembly using,
Assembly.GetTypes() and Type.GetMethods()
to get the Class and methods in an Assembly.
Similarly how to get all the classes present within a C# file(.cs file).? I need to get the classes in a .cs file from which i can easily get the methods within them and further details like parameters of methods etc.
Short of using a C# parser, there's no direct way of doing it. You could compile the .cs file using CSharpCodeProvider (which only works if the file compiles on its own and you can tell all the referenced assemblies to the compiler) and use reflection on the resulting assembly.
I recommend you to use a parser generator tool to generate a quick c# parser, you can use Antlr.
Also you can check this and this
The compiler erases all notions of a codefile from your code as it is compiled. That being said perhaps it is possible to retrieve the information you want from debugging symbols if they are available in your assembly.
From with in the class you can always call
this.GetType()
or outside the class you can always call
obj.GetType()
however when you compile an application, which is required for reflection to work, you can no longer get their definitions by file.
I've done this previously by invoking the C# compiler, compiling the C# file and then using reflection on the outputted type. This is possible if the C# file is a standalone file and doesn't have any dependencies.
However, the correct way would be to use a parser - something which isn't that easy to do. There are a couple of options available, MinosseCC being one of them.
Incidentally, C# 5.0 will make it a lot easier to compile code on the fly by being able to compile a String and getting back executable code. Can't wait for this - it's sure to confuse everyone that reads my code.
First of all, there is no such thing as the .cs file in which a class is defined. A class can be marked as partial and parts can be defined in several .cs files.
When you compile with debug information, the filenames for each method remain in the assembly (for each line of the source file, the corresponding IL commands are tagged).
Unfortunately, I don't know an easy way to get to that information from within the running application (without parsing the assembly file manually).
If you are safe calling the method, you can call it and in parallel construct a stack trace (from another thread) - in the StackFrame object you will find the original file name. But this is slow (as you have to call every method just to find that the filename is different) and risky (what if the method formats your hard drive?).
So, the only way you could go is try to parse the .cs file with a parser like AntLR yourself.

Categories

Resources