.NET Frameworkで画像ビューアを作る

# 環境
Windows 11 Pro (64bit)

# 手順
適当なディレクトリに
`dev.bat`
`wpf.rsp`
`ImgView.cs`
を用意する。

`dev.bat`を起動し
```
csc /t:winexe @wpf.rsp ImgView.cs
```
で`ImgView.exe`が作られる。

# 使い方
適当なbmpファイルを用意し、右クリックメニューから「プログラムから開く」で`ImgView.exe`を指定する。

左右キーで同じディレクトリにある他の画像ファイルを表示。

# ソースなど

```dev.bat
@echo off
path %path%;C:\Windows\Microsoft.NET\Framework64\v4.0.30319
prompt $e[33m$p$g$e[m
cmd
```

```wpf.rsp
# csc @wpf.rsp foo.cs

/r:System.Xaml.dll
/r:WPF\PresentationCore.dll
/r:WPF\PresentationFramework.dll
/r:WPF\WindowsBase.dll
```

```ImgView.cs
/*
csc /t:winexe @wpf.rsp ImgView.cs
*/
using System;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Imaging;

class MyWindow : Window {
	Image img;
	string[] files = null;
	int idx;

	public MyWindow() {
		Title = "ImgView";
		img = new Image();
		Content = img;
		KeyDown += (sender, e) => {
			if (e.Key == Key.Right) {
				idx = (idx + 1) % files.Length;
				disp();
			}
			if (e.Key == Key.Left) {
				if (--idx < 0) idx += files.Length;
				disp();
			}
		};
	}

	public void init(string path) {
		var dir = Path.GetDirectoryName(path);
		files = Directory.GetFiles(dir);
		for (int i = 0; i < files.Length; i++) {
			if (files[i] == path) {
				idx = i;
				break;
			}
		}
		disp();
	}

	void disp() {
		var path = files[idx];
		var ext = Path.GetExtension(path);
		if (! Regex.IsMatch(ext, "(bmp|jpg|png)")) return;
		try {
			var uri = new Uri(path);
			var bi = new BitmapImage(uri);
			img.Source = bi;
		} catch (Exception /*e*/) {
		}
		Title = string.Format("ImgView [{0}] ({1}/{2})",
			path, idx + 1, files.Length);
	}
}

class Program : Application {
	MyWindow wnd;

	protected override void OnStartup(StartupEventArgs args) {
		base.OnStartup(args);

		wnd = new MyWindow() { Width=640, Height=400 };
		if (args.Args.Length != 0) {
			wnd.init(args.Args[0]);
		}
		wnd.Show();
	}

	[STAThread]
	static void Main() {
		new Program().Run();
	}
}
```

# その他
PowerShellでの実装例。

```ImgView.ps1
# powershell -ExecutionPolicy RemoteSigned ./ImgView.ps1 <path>

$ref = @(
	"System.Xaml.dll"
	"WPF\PresentationCore.dll"
	"WPF\PresentationFramework.dll"
	"WPF\WindowsBase.dll"
)

$src = @"
using System;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Imaging;

public class MyWindow : Window {
	Image img;
	string[] files = null;
	int idx;

	public MyWindow() {
		Title = "ImgView";
		img = new Image();
		Content = img;
		KeyDown += (sender, e) => {
			if (e.Key == Key.Right) {
				idx = (idx + 1) % files.Length;
				disp();
			}
			if (e.Key == Key.Left) {
				if (--idx < 0) idx += files.Length;
				disp();
			}
		};
	}

	public void init(string path) {
		var dir = Path.GetDirectoryName(path);
		files = Directory.GetFiles(dir);
		for (int i = 0; i < files.Length; i++) {
			if (files[i] == path) {
				idx = i;
				break;
			}
		}
		disp();
	}

	void disp() {
		var path = files[idx];
		var ext = Path.GetExtension(path);
		if (! Regex.IsMatch(ext, "(bmp|jpg|png)")) return;
		try {
			var uri = new Uri(path);
			var bi = new BitmapImage(uri);
			img.Source = bi;
		} catch (Exception /*e*/) {
		}
		Title = string.Format("ImgView [{0}] ({1}/{2})",
			path, idx + 1, files.Length);
	}
}
"@

Add-Type -TypeDefinition $src -ReferencedAssemblies $ref

if ($MyInvocation.InvocationName -ne ".") {
	if ($Args.Length -eq 0) {
		Write-Host "no args"
		exit
	}
	$wnd = New-Object MyWindow
	$wnd.init($Args[0]);
	[void]$wnd.ShowDialog()
}
```