Windows 7 C# Build @ .NET4.0

正月といえば、やはりプログラミングですよね。

前回は .NET Framework 3.5 の WPF を使いました。
それは Windows 7 なら最初から必ず入っているからという理由もありますが。
実は .NET 4.0 でやってみたけど上手くいかなかったから…

やはり現在の最新技術である 4.0 を使ってみたいじゃないですか。
ということで色々と自分で実験してみた。
技術文書とかは読まず(解らないもん)自力で漁った結果と前置きして。

.NET 3.5 での reference はカレント及び csc.exe のディレクトリ
それと C:\Windows\assembly を探すようだ。

このファイルに見えるものは実態ではない、端末で見れば解る。
Linux ばかり使っていて良かった、以前なら端末で見ようなんて絶対に思わない。

サブディレクトリ内に実態がある、正直なんだかよく解らない。
とにかく 4.0 の csc.exe ではこの位置の PresentationCore.dll は見つけられない。

4.0 の csc.exe があるディレクトリをよく見ると、ぶっちゃけ下記だが
C:\Windows\Microsoft.NET\Framework64\v4.0.30319
に WPF というディレクトリがありソコにも PresentationCore.dll 等が。
ということはコッチを /lib オプションで指定すればいいようだ。

/lib 指定でビルド、System.Xaml.dll が見つからないとエラー…
って .NET 3.5 までは System.Xaml アセンブリなんて無かったような気がするんだが。
上記 assembly ディレクトリを漁ってもやはり見当たらないし。

WPF 4(VS 2010&.NET 4シリーズ) ? @IT

どうも .NET Framework 4.0 からのようで、XAML を使っていなくても必要なのね。
csc.exe のディレクトリ直下にある、ので System.Xaml.dll を参照追加指定だけ。
暗黙のリンクはやってくれない、何か事情があるのだろう。

ところで 64bit ディレクトリ指定にして配布は大丈夫なのだろうか?
exe に位置情報が埋め込まれていたりすると 32bit では動かないんだが。
32bit と 64bit の csc.exe でビルドして diff してみる。

exe 名以外は特に違いが見つからない、というかパス情報は無いみたい。
というかどちらも AnyCPU ビルドなんだからほとんど同じものが作られるんだね。
ネイティブで動くか WOW64 で動くかの違いだけなのかな?

どっちでも同じなら 32bit 位置指定のほうが心配が少なそうだから今後はそれで。
ということで 64 でないほうのディレクトリ指定でバッチを作る。

build32.bat

C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe ^
/lib:C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF ^
/reference:System.Xaml.dll ^
/reference:PresentationCore.dll ^
/reference:PresentationFramework.dll ^
/reference:WindowsBase.dll ^
/target:winexe ^
/out:TextReader.exe ^
/win32icon:icon.ico ^
/optimize+ ^
src.cs
PAUSE

v4.0.30319 というディレクトリ名は皆同じなんだろうか…
この Blog は自分で作って自分で使う(遊ぶ)人向けなのだからオケということで。

ということで今回は自分で復習のつもりでテキストリーダーを作ってみた。
UTF-8 以外は文字化けします、私は全部 UTF-8 保存しているので問題無し。
エントリポイントが解りにくいので __main__ という名前にしたw

src.cs

using System;
using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Microsoft.Win32;

class TextReader : Window
{
	private TextBox _textbox;

	public TextReader()
	{
		this.Title = "てきすとりぃだぁ!";
		this.Width = 400;
		this.Height = 400;
		this.CreateControls();
	}
	private void CreateControls()
	{
		_textbox = new TextBox();
		_textbox.TextWrapping = TextWrapping.NoWrap;
		_textbox.AcceptsReturn = true;
		_textbox.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
		_textbox.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;
		// Button
		var button = new Button();
		button.Content = "Open the Text";
		//button.Click += new RoutedEventHandler(on_button_click);
		button.Click += on_button_click;
		DockPanel.SetDock(button, Dock.Top);
		// DockPanel
		var dockpanel = new DockPanel();
		// Append
		dockpanel.Children.Add(button);
		dockpanel.Children.Add(_textbox);
		this.Content = dockpanel;
	}
	void on_button_click(object sender, RoutedEventArgs e)
	{
		var dlg = new OpenFileDialog();
		var res = dlg.ShowDialog(this);
		if (res.Value)
		{
			var sr = new StreamReader(dlg.FileName, Encoding.UTF8);
			_textbox.Text = sr.ReadToEnd();
			sr.Close();
		}
	}
}

class __main__
{
	[STAThread]
	public static void Main(string[] args)
	{
		var app = new Application();
		app.Run(new TextReader());
	}
}

textreader.zip

new RoutedEventHandler() を使わずにイベントハンドラが追加できたんだが…
以前からそうなのかな、VisualStudio だと強制的に書き込まれるはずなんだが。
余計な new が少ないのは嬉しいよ。

.NET 4.0 なので Microsoft.Win32 名前空間のダイアログも最新だ。
それ以外は 4.0 の恩恵が何も無いという…

3.0 時のような劇的進化は特に無いし 3.5 でイイやとか思ってしまうよ。
とにかく .NET 4.0 でも何もインストールせずに遊ぶ方法が解ったのでよし。