[C#]csc.exeでWPFアプリケーションをつくる

# この記事は

- `csc.exe`を使ってWPFアプリケーションをつくる
- `csc.exe`はWindows 10 OS に**標準で搭載**されており、**Visual Studioなどインストールしなくとも**C#をコンパイルできる

> csc.exeは、.NET Frameworkに含まれるMicrosoft製のC#コンパイラである。
(Wikipedia)

必要なものは`main.cs`と`MainWindow.xaml`の2ファイル

## メモ帳があればWPFアプリケーションがつくれる

**ソースコードは記事末尾にあります**

メモ帳に貼り付けて、コマンドプロンプトを開いて、このあとの章にあるコマンドを入力！！

# 得られる成果物

１画面のWPFアプリケーションが生成される
画面のサイズを変更したときに、ボタンやテキストボックスも大きさが自在に変わる（それがWPF)

## 機能（と呼べるほどのものはない）

- 1秒ごとに現在時刻を取得し、画面に表示する
- 表示したリストをユーザ指定のフォルダーへ保存する

![Animation1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272511/db11f050-e8c3-7778-a41a-883ea7f6655f.gif)

# csc.exeでC#ソースコードをコンパイルする

## `csc.exe`がある場所

```
cd %systemroot%
dir /b /s | findstr csc.exe$

# Output
C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe
C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe
C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe
C:\Windows\Microsoft.NET\Framework64\v2.0.50727\csc.exe
C:\Windows\Microsoft.NET\Framework64\v3.5\csc.exe
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe
```

## コンパイルコマンド

### パスを通す

```
SET REFPATH="C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0"
echo %REFPATH%

# Output
"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0"
```

### コマンド実態

```
C:\Windows\Microsoft.NET\Framework64\v3.5\csc.exe /t:winexe /r:"%REFPATH%\PresentationCore.dll" /r:"%REFPATH%\PresentationFramework.dll" /r:"%REFPATH%\WindowsBase.dll" main.cs
```

※`v3.5`は適宜自分の環境に合わせて。

### 引数の説明

項目|説明
-|-
`C:\Windows\Microsoft.NET\Framework64\v3.5\csc.exe`|コンパイラ本体
`/t:winexe`|出力形式（EXEファイルやライブラリDLLファイル）
`/r:"%REFPATH%\PresentationCore.dll"`|参照DLL
`/r:"%REFPATH%\PresentationFramework.dll"`|参照DLL
`/r:"%REFPATH%\WindowsBase.dll"`|参照DLL
`main.cs`|ソースコード


# ソースコード

## C#
```csharp:main.cs
using System.Threading;
using System;
using System.IO;
using System.Windows;
using System.Windows.Markup;
using System.Windows.Controls;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;

namespace WPFApp
{
    public class App
    {
        [STAThread]
        public static void Main()
        {
            Window window = null;
            using (var fs = new FileStream("MainWindow.xaml", FileMode.Open, FileAccess.Read))
            {
                window = (Window)XamlReader.Load(fs);
            }
            ButtonSetting(window);
            window.ShowDialog();
        }

        private static void ButtonSetting(Window window)
        {
            var readButton = (Button)window.FindName("ReadButton");
            var stopButton = (Button)window.FindName("StopButton");
            var testButton = (Button)window.FindName("TestButton");
            var saveButton = (Button)window.FindName("SaveButton");
            var list = (ListView)window.FindName("IdList");
            var src = new ObservableCollection<string>();
            list.ItemsSource = src;
            list.DataContext = src;
            Thread thread = null;

            readButton.Click += (sender, e) =>
            {
                readButton.IsEnabled = false;
                stopButton.IsEnabled = true;

                thread = new Thread(new ThreadStart(() =>
                {
                    try
                    {
                        bool flg = true;
                        while (flg)
                        {
                            window.Dispatcher.Invoke(new Action(() => TestButtonClickHandler(src)));
                            Thread.Sleep(1000);
                            flg = (bool)window.Dispatcher.Invoke(new Func<bool>(() => stopButton.IsEnabled));
                        }
                    }
                    catch (Exception e1)
                    {
                        MessageBox.Show(e1.Message);
                    }
                }));

                thread.Start();
            };

            stopButton.Click += (sender, e) =>
            {
                readButton.IsEnabled = true;
                stopButton.IsEnabled = false;
            };

            saveButton.Click += (sender, e) =>
            {
                var saveDir = (TextBox)window.FindName("SaveDir");
                string saveName = Path.Combine(saveDir.Text, DateTime.Now.ToString("yyyyMMdd-hhmmss") + ".txt");
                System.IO.File.WriteAllLines(saveName, src.ToArray());
                MessageBox.Show("保存しました\n" + saveDir + '\n' + saveName);
            };

            testButton.Click += (sender, e) => TestButtonClickHandler(src);

            window.Closing += (sender, e) => thread.Abort();
        }

        private static void TestButtonClickHandler(IList<string> src)
        {
            src.Add(DateTime.Now.ToString());
        }
    }
}
```

## XAML
```xml:MainWindow.xaml
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Hello, WPF!" Width="500">
	<Grid>
		<Grid.RowDefinitions>
			<RowDefinition Height="24" />
			<RowDefinition Height="*" />
			<RowDefinition Height="4*" />
			<RowDefinition Height="*" />
		</Grid.RowDefinitions>
		<Label Grid.Row="0" Content="読み取りを停止してから閉じてください" Foreground="Red" HorizontalAlignment="Right"/>
		<GroupBox Grid.Row="1" Margin="5" FontSize="16" Header="読み取り">
			<Grid>
				<Grid.ColumnDefinitions>
					<ColumnDefinition Width="*" />
					<ColumnDefinition Width="*" />
				</Grid.ColumnDefinitions>
				<Button x:Name="ReadButton" Grid.Column="0" Margin="5" Padding="5" Content="開始" FontSize="16" />
				<Button x:Name="StopButton" Grid.Column="1" Margin="5" Padding="5" Content="停止" FontSize="16" IsEnabled="False" />
			</Grid>
		</GroupBox>
		<GroupBox Grid.Row="2" Margin="5" FontSize="16" Header="読み取り結果">
			<ListView x:Name="IdList" Margin="5">
				<ListView.View>
					<GridView>
						<GridViewColumn Header="ID1234" />
					</GridView>
				</ListView.View>
			</ListView>
		</GroupBox>
		<GroupBox Grid.Row="3" Margin="5" FontSize="16" Header="ファイルの保存先">
			<Grid>
				<Grid.ColumnDefinitions>
					<ColumnDefinition Width="5*" />
					<ColumnDefinition Width="*" />
				</Grid.ColumnDefinitions>
				<TextBox x:Name="SaveDir" Grid.Column="0" Margin="5" VerticalAlignment="Center" Text="C:\Users\t1380\Downloads" />
				<Button x:Name="SaveButton" Grid.Column="1" Margin="5" Padding="5" Content="保存" FontSize="16" IsEnabled="{Binding ElementName=ReadButton, Path=IsEnabled}" />
			</Grid>
		</GroupBox>
		<Button x:Name="TestButton" Content="デバッグ" Visibility="Hidden" />
	</Grid>
</Window>
```

# [糸冬了！！](https://qiita.com/dnobori/items/8cb33d0b567c70e4b6ae#%E7%B3%B8%E5%86%AC%E4%BA%86)

登老师投稿記念パピコ