I got .net dll (originally, written in C#) which is being updated / released from time to time. There's a small part of code I need to modify inside this dll which suits my usage needs.
I'm able to do these changes every time using dnSpy but I don't like doing it manually every time.
Is there possibility to automate the process of code change inside dll and how can it be done?
Is it easier to convert dll to IL and change IL instructions and then compile it back or should I do full decompile to C# and then recompile it back using Roslyn?
The code I change is always the same and is changed to the same result code.
A possible solution for what you want to achieve is Mono.Cecil.
With Cecil, you can load existing managed assemblies, browse all the
contained types, modify them on the fly and save back to the disk the
modified assembly.
This library is being used by tools like coverlet which change the assembly on the fly in order to be able to compute code coverage.
That being said, I highly agree with Marc Gravell comment that at the first glance this seems to be the wrong approach and a change in design would be more appropriate.
Related
Is it possible to parameterize a reference in c#?
I'm using an external library (google.dfp) and i need to update it every year with the new version. The library name contains the version (for example: "using Google.Api.Ads.Dfp.v201708;").
I would like to set the version in the app/web.config and build the using directive with this value. Is there any possibility to set a placeholder or something like this?
Thank you
As per #Damien_The_Unbeliever's comment:
using directives are only made use of at compile time.
That's pretty much the end of the discussion; it can't be done because it requires recompilation.
At best, you can write a small console application that generates the correct usnig statement, but you would still have to update the code and recompile (and redeploy).
The code change is so minimal that I wouldn't even write a small code generator for this. Copy/pasting the generated code costs as much effort as simply updating the value manually, so you're not really gaining any efficiency.
Having a server that other devs use, I currently log the version of the dll they use. I do that by having the client that use Reflection to retrieve its version:
Assembly.GetEntryAssembly().GetName().Version.ToString();
It's nice, but since it come from dev that uses TFS and do themself the build, I can not see if they have the latest version of the sources. Is there a trick, like a compilation tag, that would easily allow a hash of the generating source code?
Note: I have try to send the MD5 of the dll (using assembly.Location), but it is useless since the hash value changes between 2 compilations (I suppose there is some compilation timestamp inside the generated dll).
This is most collaboraton issue then a coding.
In the moment that you find out that the version is old one.notify them about it.
If the real version is not old one, that means that developers before making buold did not increment the version ID, which is mistake.
In other words, ordanize it among people, and not relly on these kind of tools (if there is any). You trying to create a complicated tool, that will help you avoid mistakes, but humans will find a way to make them again.
So it's better to create solid relation structure among you, imo.
Create a tool on pre build event to hash/last-write-time your code files.
Write the result to a cs file or a embedded resource file.
The result file must exclude in above action.
For prevent skip build (up-to-date) feature not work,Compare the file before write.
And if youre opening the file in IDE will get a prompt `changed from out side' when build.
Seem there is no easy way to do it.
This is what I'm trying to accomplish:
I have two applications. One is a client application the other one would be a compiler. Client uses encryption and for safety reasons I would like the users to be able to run the 'compiler' application, that would hard code a security key inside already compiled binary, so each client has its own encryption key stored inside of it. Is this even possible or the solution would be crazy? Thanks.
Sure all you are talking about is rewritting the MSIL code. Microsoft does this all the time with code contracts. Here is a link to an article explaining how: http://msdn.microsoft.com/en-us/magazine/cc188743.aspx
Another example: http://www.codeproject.com/Articles/20565/Assembly-Manipulation-and-C-VB-NET-Code-Injection
If your assembly is strongly signed, you cannot modify it. You cannot save back a modified .net assembly to disk. However, you can build your assemble ( As Kevin stated) to be able to modify the code loaded in memory at runtime. It will not affect the image on the disk and the modification will be run at every time the application is started.
Is it possible to generate and build some c# code based on the code from the same project. I tried with T4 and Reflection, but there are some assembly locking issues. Is there any other way?
Reflection works fine for me. You can get around assembly locking issues by isolating your build task to a separate AppDomain within VS. When the task completes, any assemblies you need to use for code generation will be unloaded together with the task's AppDomain. See AppDomainIsolatedTask.
You can definitely write your own code generator, all in C# - after all, "code" that's being generated is just a text file you write out.
But what's wrong with T4 templates? They offer a lot of functionality that you don't have to reinvent yet again - why not use it? Can you tell us in more detail what problems you're having with T4?
T4 is really just a bunch of classes in .NET, too - so you could definitely write your own code generator handling some of the logic, and use T4 to do the templating & replacing those template values part. But again: in order to help you diagnose your T4 problems, we'd need to know more about those....
This example from Oleg Sych uses FXCop's introspection engine instead of reflection. That way, the assemblies do not get locked.
Unfortunately, Reflection is optimized
for code execution. One particular
limitation makes it ill-suited for
code generation - an assembly loaded
using Reflection can only be unloaded
with its AppDomain. Because T4
templates are compiled into .NET
assemblies and cached to improve
performance of code generation, using
Reflection to access the component
assembly causes T4 to lock it.
Alternatively, if you're only targeting Linq to SQL classes, you could generate code from the dbml file instead of the code that L2S generates from the dbml. I've got an example of something similar (an edmx file) on my own blog.
There is a third party C# .NET variant of JavaCC that we use at work.
Also an interesting article about how to make one:
http://msdn.microsoft.com/en-us/magazine/cc136756.aspx
It really depends on what exactly are you trying to achieve, but on a general case I'd recommend using T4 templates.
And yes, it is possible to use T4 templates inside your project to generate code in your project based on some local settings, but you should define what are you trying to do.
If you want to generate code based on some classes that you define in the same project - this doesn't sound like something easily achievable (after all you want to compile some of the classes in the current project, generate some code based on them and after that generate classes again... umm.. ?)
But if you want to store some settings and then run the T4 template and generate some code based on these settings - this is easily achievable. T4MVC is an example (they generate code based on a settings file that is copied and stored in the project alongside the T4 template). This template also looks at the current files available in the solution, and generates string constants based on each file. That kind of sounds like it would really help you with your problem, whatever it is :)
If you're still unsure - you can specify more details about what you want to do, and we'll try to help you :)
Before start let me tell my experience: I am experienced with C#.NET, web services, XML part and few more. Reflection is something new to me, though I have read extensively on it and tried out some experimental code, but haven't made anything great using reflection
I checked out many examples of how we can create Type at runtime and then which can be saved in an assembly (.dll) files. Of all the examples I have seen is about saving the created types in the .dll files instead of code file. Isn't there any way to create the code file out of reflection?
I need to create code file since I want to distribute code instead of compiled assemblies. What I want to do is something like xsd.exe does, either spit out a .dll or the code file(in any language).
Isn't there any way to create a code file, since most of the place I can find is
AssemblyBuilder ab = System.AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Save);
and then lastly
ab.Save("QuoteOfTheDay.dll");
There is no disassembler built into the .NET framework. You could use Reflector to convert the IL you emitted to one of the source code languages it supports. It isn't terribly likely that this will work without problems, Reflector was designed to convert code that was generated by a compiler back to source code. Compilers tend to be conservative about the IL they generate, unlike the anything-goes approach that System.Reflection.Emit offers.
If you want source code then you're best off by generating it in the first place. Use System.CodeDom. That's what System.Xml.Serialization uses.
Generally either the string classes or CodeDOM (http://msdn.microsoft.com/en-us/library/y2k85ax6.aspx) are used to generate C# source.