zip ファイルなどを圧縮した際に、自己解凍形式のファイルを出力するソフトとかあるじゃないですか。
あんな感じで exe ファイルを生成するソフトの .NET 版を作ってみたいなと思い、色々リサーチしてみたので、その時のメモ。
実は .NET には CSharpCodeProvider というとんでもないクラスが存在しているので、これを使ってみました。
今回開発した EnjoiCrypto にもこのテクは使っています。
一応環境。
.NET Framework 1.1/Mono 1.2
using System;
using System.IO;
using System.Resources;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
namespace Test
{
class Test
{
[STAThread]
static void Main(string[] args)
{
CSharpCodeProvider csprov = new CSharpCodeProvider();
ICodeCompiler compiler = csprov.CreateCompiler();
CompilerParameters compilerparams = new \
CompilerParameters(new string[] {"System.dll"}, \
"output.exe", false);
compilerparams.GenerateExecutable = true;
compilerparams.CompilerOptions = "/target:exe";
CompilerResults cr = compiler.CompileAssemblyFromSource (compilerparams,
@"using System;
namespace Test
{
class Test
{
[STAThread]
static void Main(string[] args)
{" +
" Console.WriteLine (\"Hello World\");" +
@" }
}
}");
}
}
}
$ gmcs test.cs test.cs(20,29): warning CS0219: The variable `cr' is assigned but its value is never used test.cs(15,45): warning CS0618: `Microsoft.CSharp.CSharpCodeProvider.CreateCompiler()' is obsolete: `Use CodeDomProvider class' Compilation succeeded - 2 warning(s) $ ls test.cs test.exe $ mono test.exe $ ls output.exe test.cs test.exe $ mono output.exe Hello Worldどうやらうまくいっているようです。
解説ですが、コードを見て分かるとおり、元のアプリは実行中に内部でコードをコンパイルしているわけです。
まずは CSharpCodeProvider は compiler オブジェクトを生成ます。
次に、コンパイル時のパラメータを指定するための CompilerParameters クラスのオブジェクトを生成し、ここに生成する Exe が必要な dll を指定したり、出力ファイルの名称、コンパイルオプション、リソースファイルがあればリソースを設定したりします。
そして最後に実際のコードを CompileAssemblyFromSource 関数でコンパイルしてできあがりです。