”ソース == 実行プログラム” な言語に慣れてしまうと、
この実行プログラムのソースはどうなってるんだ・・と一々データサーバー
まで見に行かないといけないのはちょっとやってられないわけで。
いっその事、ソースも埋め込んでしまえばいいんじゃねというのをやってみた。
用意するもの
- .NETフレームワークの入ったWindows(今どきはデフォルトでC#コンパイラ入ってるんですね!すごい!)
C:\tmp>dir
2014/04/16 21:16 259 README.txt
2014/04/16 21:04 822 resource_test.cs
resource_test.cs
/*
* how to execute
* C:\tmp>path=%path%;C:\Windows\Microsoft.NET\Framework64\v4.0.30319
* C:\tmp>csc resource_test.cs /resource:resource_test.cs /resource:README.txt
* C:\tmp>resource_test.exe
*/
namespace Main
{
using System;
using System.IO;
using System.Reflection;
class MainClass
{
static void Main()
{
Assembly asm = Assembly.GetExecutingAssembly();
foreach(string infile in asm.GetManifestResourceNames()) {
string otfile = "w_" + infile;
Console.WriteLine("infile : " + infile);
Console.WriteLine("otfile : " + otfile);
// 書き出し準備
FileStream fs = new FileStream(otfile, FileMode.Create);
BinaryWriter br = new BinaryWriter(fs);
// 書き出し
Stream sr = asm.GetManifestResourceStream(infile);
byte[] bt = new byte[sr.Length];
sr.Read(bt, 0, bt.Length);
br.Write(bt);
}
}
}
}
README.txt
・複数個のファイルは/resourceを連続すれば良い。
・もっと数が多いならzip圧縮するバッチを作成して、
そのzipファイルをコンパイル時に埋め込めば良い。
・リソースエディタとかにかけると埋め込まれているファイルなんて
丸見えなので暗号化かけるとかはよしなに。
実行&結果
ぶじ、かきだせました。
C:\tmp>csc resource_test.cs /resource:resource_test.cs /resource:README.txt
C:\tmp>resource_test.exe
infile : resource_test.cs
otfile : w_resource_test.cs
infile : README.txt
otfile : w_README.txt
C:\tmp>dir
2014/04/16 21:16 259 README.txt
2014/04/16 21:31 968 resource_test.cs
2014/04/16 21:31 5,632 resource_test.exe
2014/04/16 21:31 259 w_README.txt
2014/04/16 21:31 968 w_resource_test.cs
関数化
- ちゃんとしたモジュール化とかは勉強してないので・・・
/*
* how to compile and execute
* C:\tmp>path=%path%;C:\Windows\Microsoft.NET\Framework64\v4.0.30319
* C:\tmp>csc extract.cs /resource:extract.cs /resource:README.txt
* C:\tmp>extract.exe
*/
using System;
using System.IO;
using System.Reflection;
class MainClass
{
static int Main(string[] args)
{
if (args.Length == 0) {
Console.WriteLine("引数がありません");
return 0;
}
if (args[0] == "/e") {
Console.WriteLine("ソース展開");
extractResource();
return 0;
}
Console.WriteLine("何もしません");
return 0;
}
static void extractResource()
{
Assembly asm = Assembly.GetExecutingAssembly();
foreach(string infile in asm.GetManifestResourceNames()) {
string otfile = "w_" + infile;
Console.WriteLine("infile : " + infile);
Console.WriteLine("otfile : " + otfile);
// 書き出し準備
FileStream fs = new FileStream(otfile, FileMode.Create);
BinaryWriter br = new BinaryWriter(fs);
// 書き出し
Stream sr = asm.GetManifestResourceStream(infile);
byte[] bt = new byte[sr.Length];
sr.Read(bt, 0, bt.Length);
br.Write(bt);
}
}
}