たまにこういうコードを書かないと忘れるので少し書いてみます。
需要はありませんが、こんなことも出来るっていう参考になれば幸いです。
function Hello-World-Il() { $domain = [System.AppDomain]::CurrentDomain $assemblyName = New-Object System.Reflection.AssemblyName("Test") $directory = "c:\temp" $assemblyBuilder = $domain.DefineDynamicAssembly($assemblyName, [System.Reflection.Emit.AssemblyBuilderAccess]::RunAndSave, $directory) $moduleBuilder = $assemblyBuilder.DefineDynamicModule("sample.exe"); $typeBuilder = $moduleBuilder.DefineType("Program", [System.Reflection.TypeAttributes]::Class); $methodBuilder = $typeBuilder.DefineMethod("Main", [System.Reflection.MethodAttributes]::Static); $write = [System.Console].GetMethod("WriteLine", [type[]]([string])) $readLine = [System.Console].GetMethod("ReadLine") $concat = [System.String].GetMethod("Concat",[type[]]([string],[string])) $il = $methodBuilder.GetILGenerator(); $il.Emit([System.Reflection.Emit.OpCodes]::Nop); $a = $il.DeclareLocal([string]) $il.Emit([System.Reflection.Emit.OpCodes]::Nop) $il.Emit([System.Reflection.Emit.OpCodes]::Ldstr, "文字を入力して下さい。") $il.Emit([System.Reflection.Emit.OpCodes]::Call, $write) $il.Emit([System.Reflection.Emit.OpCodes]::Nop) $il.Emit([System.Reflection.Emit.OpCodes]::Call, $readLine) $il.Emit([System.Reflection.Emit.OpCodes]::Stloc, $a) $il.Emit([System.Reflection.Emit.OpCodes]::Ldloc, $a) $il.Emit([System.Reflection.Emit.OpCodes]::Ldstr, "と入力しました。") $il.Emit([System.Reflection.Emit.OpCodes]::Call, $concat) $il.Emit([System.Reflection.Emit.OpCodes]::Call, $write) $il.Emit([System.Reflection.Emit.OpCodes]::Nop) $il.Emit([System.Reflection.Emit.OpCodes]::Call, $readLine) $il.Emit([System.Reflection.Emit.OpCodes]::Pop) $il.Emit([System.Reflection.Emit.OpCodes]::Ret) $typeBuilder.CreateType(); $assemblyBuilder.SetEntryPoint($methodBuilder); $assemblyBuilder.Save("sample.exe") } Hello-World-Il
上記のコードを実行すると sample.exe が c:\temp 配下に作成されます。
この作成されたexeは、以下のコードをコンパイルして作成されるILとほぼ同じ振る舞いをするILとなります。
アセンブラとほぼ変わらんですね。なかなか大変な、、、
static void Main() { Console.WriteLine("文字を入力して下さい。"); var a = Console.ReadLine(); Console.WriteLine(a + "と入力しました。"); Console.ReadLine(); }