Created
January 24, 2020 20:08
-
-
Save GrabYourPitchforks/ec80a0d8b75167749f6022bc32ce4234 to your computer and use it in GitHub Desktop.
Module initializer sample
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |
<!-- ... --> | |
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | |
<!-- This task adds a module initializer to {IL}.txt. --> | |
<UsingTask TaskName="InjectModuleInitializer" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll"> | |
<ParameterGroup> | |
<Path ParameterType="System.String" Required="true" /> | |
<InitializerMethod ParameterType="System.String" Required="true" /> | |
</ParameterGroup> | |
<Task> | |
<Using Namespace="System" /> | |
<Using Namespace="System.IO" /> | |
<Using Namespace="System.Text" /> | |
<Code Type="Fragment" Language="cs"><![CDATA[ | |
StringBuilder sb = new StringBuilder(); | |
string s = File.ReadAllText(Path, Encoding.UTF8); | |
sb.Append(s); | |
sb.AppendLine(); | |
sb.AppendLine(@"// Module initializer"); | |
sb.AppendLine(@".method private specialname rtspecialname static void .cctor() cil managed {"); | |
sb.AppendLine(@".maxstack 0"); | |
sb.Append(@"call void "); | |
sb.Append(InitializerMethod); | |
sb.AppendLine(@"()"); | |
sb.AppendLine(@"ret"); | |
sb.AppendLine(@"} // end of global method .cctor"); | |
File.WriteAllText(Path, sb.ToString(), Encoding.UTF8); | |
]]></Code> | |
</Task> | |
</UsingTask> | |
<PropertyGroup> | |
<!-- by default, we're not optimized --> | |
<IlasmDebugMode>impl</IlasmDebugMode> | |
<!-- if build optimization is enabled, pass the OPT parameter to ilasm --> | |
<IlasmDebugMode Condition="'$(Optimize)' == 'true'">opt</IlasmDebugMode> | |
<IntermediateIlFile>$(IntermediateOutputPath)$(TargetName).il</IntermediateIlFile> | |
<IntermediateResourceFile>$(IntermediateOutputPath)$(TargetName).res</IntermediateResourceFile> | |
</PropertyGroup> | |
<Target Name="AfterCompile" Inputs="@(IntermediateAssembly)" Outputs="$(IntermediateIlFile)"> | |
<!--Disassemble the DLL, inject the module initializer, then reassemble--> | |
<Delete Files="$(IntermediateIlFile)" /> | |
<Exec Command=""$(SDK40ToolsPath)ildasm.exe" /nobar /linenum /utf8 /typelist /out="$(IntermediateIlFile)" "@(IntermediateAssembly)"" WorkingDirectory="$(MSBuildProjectDirectory)" /> | |
<!-- Create a static method somewhere with the following signature: | |
internal static void Initialize() { /* ... */ } | |
Then update "InitializerMethod" below to have the value "{namespace}.{typename}::{initializer_method_name}". | |
The sample below is what the Microsoft.Web.Infrastructure assembly uses. --> | |
<InjectModuleInitializer Path="$(IntermediateIlFile)" InitializerMethod="Microsoft.Web.Infrastructure.ModuleInitializer::Initialize" /> | |
<Exec Command=""$(MSBuildToolsPath)\ilasm.exe" /nologo /quiet /dll /debug=$(IlasmDebugMode) /resource="$(IntermediateResourceFile)" /output="@(IntermediateAssembly)" "$(IntermediateIlFile)"" WorkingDirectory="$(MSBuildProjectDirectory)" /> | |
<!--Absolutely necessary the touch the IL file so that this target gets correctly skipped in incremental builds--> | |
<Touch Files="$(IntermediateIlFile)" /> | |
</Target> | |
</Project> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment