Edited at

Visual Studioではなく、Windows付属のcsc.exe だけでC#実行ファイルを作る

More than 5 years have passed since last update.

PC遠隔操作事件で弁護士さんが容疑者にはC#を作成する環境(Visual Studio 2010)がなかったと主張( http://goo.gl/wJyOc ) をされています。

この事件の事実や行方、あるいは今の容疑者は真犯人なのかといった事柄とは別に、C#のそこの部分を自分の手で確認してみたくなったので、極簡単なコンパイルのテストをしてみました。

「まぁ、C#の世界はよくわからないけど、念のために今Framework\v4.0.30319のcsc.exeでコンパイルしてみたら、hello.exe の中にそのGeneratorバージョンを埋め込めたので、できることはできるのかなと思う。」http://goo.gl/wqlWg

ということで、Visual Studio 2010なしでC#の実行ファイル作成をテストしてみたメモです。(参考:Windows にデフォルトでインストールされている .NET Framework のバージョン http://goo.gl/ZkpOu)

環境は、Visual Studioではなく、Windows Vistaや7や8には最初から入っているC#コンパイラ csc.exe と テキストエディタ(これも最初から入ってるメモ帳でOK)です。

下記で試しているFrameworkはv2.0.50727です。

P.S. もちろん、これができたからといっても、当の遠隔操作ウィルスでも同じことができるかどうかは、そのウィルスを見たこともないのでわかりません。

P.S.2 こうして試してみるとC#って意外に手軽で楽しそうです^^。


ソースコード

まず、C#のコードを書きます。なんでも良いのですが、たとえばこんな感じ。


hello.cs

using System;

using System.CodeDom;
using System.CodeDom.Compiler;
using System.Reflection;
using System.Windows.Forms;
using System.Drawing;

class HelloNeko : Form {

[STAThread]
public static void Main() {
GeneratedCodeAttribute generatedCodeAttribute =
new GeneratedCodeAttribute(
"Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0"
);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run( new HelloNeko());
}

HelloNeko(){
Text = "Button Click Sample";
ClientSize = new Size(200, 200);
Button btn1 = new Button();
btn1.Location = new Point(50, 50);
btn1.Text = "Click!";
btn1.Click += btn1_Click;
Controls.AddRange(new Control[] { btn1 });
}

void btn1_Click(object sender, System.EventArgs e) {
MessageBox.Show("Hello .NEKO World", "こんちわ");
}
}


ちなみに「"Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0"」の部分はexeファイルに埋め込まれるので Visual Studio で作ったっぽく見えます。


コマンドプロンプトを起動する

上記コードをたとえば hello.cs といった名前にしてC:\testというフォルダへ置きます。

次に、そのフォルダのアドレスバーへ「cmd」と打ち込みエンターすると、そのフォルダのパスでコマンドプロンプトが開きます。

次に、csc.exeを探します。普通は「C:\Windows\Microsoft.NET\Framework」の下にFrameworkのバージョン毎にフォルダが作成されています。

とりあえずここでは、v2.0.50727の下にあるcsc.exeを使うことにします。

つまり、C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe を使います。

そのcsc.exeをコマンドプロンプトへドラッグドロップするとこうなります。

コマンドプロンプト

次に、このC:\test>C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exeの後ろへ半角スペースを打ち込んでから、今度は、最初に作ったhello.csをドラッグドロップします。

そうすると、こうなります。

コマンドプロンプト


さぁ、コンパイル!

改行します。

これだけです。


実行しましょう。

コンパイルするとC:\testホルダに hello.exe というファイルができています。

これをクリックするとこうなります。

実行

ダイアログが表れて、ボタンをクリックすると「Hello .NEKO World」と表示されます。

ちなみに、csc.exeのオプションは下記の通り。たとえば、/t:winexe をつけてコンパイルすれば、コマンドプロンプトが表示されない通常のアプリケーションになります。


Visual C# コンパイラのオプション

                        Visual C# Compiler のオプション

- 出力ファイル -
/out:<ファイル> 出力ファイル名を指定します (既定: メイン
クラスかファースト
ファイルを伴うファイルのベース名)。
/target:exe コンソール アプリケーションをビルドします
(既定)。 (短い形式: /t:exe)
/target:winexe Windows 実行可能ファイルをビルドします。
(短い形式: /t:winexe)
/target:library ライブラリをビルドします。 (短い形式: /t:library)
/target:module 別のアセンブリに追加できるモジュールをビルドしま
す。 (短い形式: /t:module)
/target:appcontainerexe Appcontainer 実行可能ファイルのビルド (短い形式:
/t:appcontainerexe)
/target:winmdobj WinMDExp で使用される Windows
ランタイムの中間ファイルのビルド (短い形式:
/t:winmdobj)
/doc:<ファイル> 生成する XML ドキュメント ファイル
/platform:<文字列> このコードが実行されるプラットフォームの制限:
x86、Itanium、x64、arm、anycpu32bitpreferred、ま
たは anycpu。既定は anycpu です。

- 入力ファイル -
/recurse:<ワイルドカード> ワイルドカードの指定に従い、現在のディレクトリと
サブディレクトリ内のすべてのファイルをインクルー
ドします。
/reference:<エイリアス>=<ファイル>
指定されたエイリアスを使用して、指定されたアセン
ブリ ファイルからメタベースを参照する (短い形式:
/r)
/reference:<ファイル リスト> 指定されたアセンブリ
ファイルからメタベースを参照する (短い形式: /r)
/addmodule:<ファイル リスト> 指定されたモジュールをこのアセンブリにリンクする
/link:<ファイル リスト> 指定された相互運用機能アセンブリ
ファイルからメタデータを埋め込みます (短い形式:
/l)

- リソース -
/win32res:<ファイル> Win32 リソース ファイルを指定します (.res)。
/win32icon:<ファイル> 出力にこのアイコンを使用します。
/win32manifest:<ファイル> Win32 マニフェスト ファイル (.xml)
を指定してください。
/nowin32manifest 既定の Win32 マニフェストを含めません。
/resource:<リソース情報> 指定したリソースを埋め込みます。 (短い形式: /res)
/linkresource:<リソース情報> このアセンブリに指定されたリソースをリンクします
。 (短い形式: /linkres)
リソース情報の形式は <ファイル>[,<文字列名>
[,public|private]]
です。

- コード生成 -
/debug[+|-] デバッグ情報を生成する
/debug:{full|pdbonly} デバッグの種類を指定します (既定値は full
で、実行中のプログラムにデバッガーを付加すること
ができます)。
/optimize[+|-] 最適化を有効にする (短い形式: /o)

- エラーと警告 -
/warnaserror[+|-] すべての警告をエラーとして報告する
/warnaserror[+|-]:<警告リスト> 指定した警告をエラーとして報告する
/warn:<n> 警告レベル (0-4) を設定する (短い形式: /w)
/nowarn:<警告リスト> 指定の警告メッセージを無効にする

- 言語 -
/checked[+|-] オーバーフロー チェックの生成
/unsafe[+|-] アンセーフ コードの許可
/define:<シンボル リスト> 条件付きコンパイル シンボルを定義する (短い形式:
/d)
/langversion:<文字列> 言語バージョン モードの指定:
ISO-1、ISO-2、3、4、5、または Default

- セキュリティ -
/delaysign[+|-] 厳密な名前のキーのパブリックな部分のみを使ってア
センブリを遅延署名します。
/keyfile:<ファイル> 厳密な名前のキー ファイルを指定します。
/keycontainer:<文字列> 厳密な名前のキー コンテナーを指定します。
/highentropyva[+|-] 高エントロピ ASLR の有効化

- その他 -
@<ファイル> 応答ファイルを読み取り、オプションを追加します。
/help この使用法のメッセージを表示します。 (短い形式:
/?)
/nologo コンパイル時の著作権メッセージを表示しません。
/noconfig CSC.RSP ファイルを自動的に含めません。

- 詳細 -
/baseaddress:<アドレス> ビルドするライブラリのベース アドレスです。
/bugreport:<ファイル> 'バグ報告' ファイルを作成します
/codepage:<n> ソース
ファイルを開くときに使用するコードページを指定し
ます。
/utf8output UTF-8
エンコードでコンパイラのメッセージを出力する
/main:<型> エントリ ポイントを含む型を指定します
(他のエントリ ポイントはすべて無視します)。
(短い形式: /m)
/fullpaths コンパイラは絶対パスを生成します。
/filealign:<n> 出力ファイル
セクションで使用する配置を指定します。
/pdb:<ファイル> デバッグ情報ファイル名を指定します (既定: .pdb
拡張子の付いた出力ファイル名)
/errorendlocation 各エラーの終了位置の出力行と出力列
/preferreduilang 出力用の言語名を指定します。
/nostdlib[+|-] 標準ライブラリ (mscorlib.dll) を参照しない
/subsystemversion:<文字列> このアセンブリのサブシステム
バージョンを指定してください
/lib:<ファイル リスト> 参照を検索する追加のディレクトリを指定します。
/errorreport:<文字列> 内部コンパイラ エラーの処理方法を指定します:
prompt、send、queue、または none です。既定値は
queue です。
/appconfig:<ファイル> アセンブリ
バインディング設定を含むアプリケーション構成ファ
イルを指定してください
/moduleassemblyname:<文字列> このモジュールが一部となるアセンブリ名です


.NET Frameworkライブラリ

http://msdn.microsoft.com/ja-jp/library/aa139615.aspx


メモ

・ソース中の[STAThread]について

 アパートメントモデルと、.NETのSTAThreadAttribute

 http://d.hatena.ne.jp/zecl/20070708/p1