C# プログラム全般


プログラムの終了
// すべての Form を閉じて、プログラムを終了する

Application.Exit() ;

// Note: このメソッドでアプリケーションを終了する場合、Form.Closed イベントと
//       Form.Closing イベントは発生しない!

プログラムの異常終了を防ぐ
// 例外が発生する可能性のある実行コードは、try と catch を使って処理する!

int Y = 123 ;
int X =   0 ;
int slope   ;

try
{
    /* 例外が発生する可能性のある実行コード */
    slope = Y / X ;
}
catch
{
    /* 例外が発生した時の処理を記述 */
    MessageBox.Show("0 で除算できません!") ;
    slope = 999 ;
}

資源の解放を確実に行う
// using ステートメントを利用して 資源の解放を確実に行う

Type1 t1 = new Type1() ;
Type2 t2 = new Type2() ;

using (t1, t2, Type3 t3 = new Type3(), Type4 t4 = new Type4())
{
    /* using スコープ内の処理 */
}

// Note: using のスコープ { } から外れると、Dispose メソッドが呼び出される。
//       また、スコープ内で例外が発生した場合も、同様。

C++ の DLL を使う ( 相互運用 Interop )
// C++ などの DLL(アンマネージコード)を利用する

// アクティブウィンドウのタイトルバー文字列を、定期的に表示する例

using System.Runtime.InteropServices ;  // for DllImport
using System.Text ;                     // for StringBuilder

[DllImport("user32.dll")]
extern static IntPtr GetForegroundWindow() ;

[DllImport("user32.dll")]
extern static int GetWindowText(IntPtr hWnd, StringBuilder lpStr, int nMaxCount) ;

private void timer1_Tick(object sender, System.EventArgs e)
{
    StringBuilder   sb = new StringBuilder(100) ;  // 文字列を new する
    IntPtr        hwnd = GetForegroundWindow() ;   // アクティブウィンドウを取得
    GetWindowText(hwnd, sb, sb.Capacity) ;         // タイトルバー文字列を取得
    textBox1.Text = sb.ToString() ;                // 文字列を表示
}

// Note: 文字列を受け取るには、StringBuilder を使うこと。string は、値を「変更」
//       できない型なのでダメ!! 文字列を渡す場合は、string で OK!!

// Note: 詳細は、下記サイトを参照せよ。
//       1) @IT .NET TIPS『 Win32 API や DLL 関数を呼び出すには? 』
//       2) MSDN『 .NET の相互運用性に関するトラブルシューティング 』
Windows API での 型名C# での 型名
API C C# .NET Framework
HWND void * System.IntPtr
WPARAM unsigned int uint System.UInt32
LPARAM long int System.Int32
LRESULTlong int System.Int32
HANDLE void * System.IntPtr
BYTE unsigned char byte System.Byte
SHORT short short System.Int16
WORD unsigned short ushort System.UInt16
INT
LONG
int
long
int System.Int32
UINT
DWORD
ULONG
unsigned int
unsigned long
unsigned long
uint System.UInt32
BOOL int bool System.Boolean
CHAR char char System.Char
LPSTR
LPWSTR
char *
wchar_t *
System.Text.StringBuilder
LPCSTR
LPCWSTR
const char *
const wchar_t *
string System.String
FLOAT float float System.Single
DOUBLE double double System.Double


コマンドライン引数の取得
// 起動時に指定した、実行ファイル名の後ろのオプション(引数)を取得する

for (int N = 1 ; N < Environment.GetCommandLineArgs().Length ; N ++)
{
    string A = Environment.GetCommandLineArgs()[N] ;  // 第 N 引数の取得
}

// Note: Environment.GetCommandLineArgs().Length は 引数の数 + 1 、
//       Environment.GetCommandLineArgs()[0]     は 実行ファイル名(パス付き)。

Windows のバージョン判定
// Windows のバージョンを判定する



配置 Button, TextBox ;

private void button1_Click(object sender, System.EventArgs e)
{
    OperatingSystem os_ver = Environment.OSVersion ;

    textBox1.Text =
        "OSVersion  : " + os_ver.ToString()                  + "\r\n" +
        " Platform  : " + os_ver.Platform.ToString()         + "\r\n" +
        " Version   : " + os_ver.Version.ToString()          + "\r\n" +
        "  Major    : " + os_ver.Version.Major.ToString()    + "\r\n" +
        "  Minor    : " + os_ver.Version.Minor.ToString()    + "\r\n" +
        "  Build    : " + os_ver.Version.Build.ToString()    + "\r\n" +
        "  Revision : " + os_ver.Version.Revision.ToString() + "\r\n" ;

    string ver = os_ver.Version.ToString() ;
    string os_name =
        (ver.IndexOf("5.1") == 0) ? "Windows XP"     :
        (ver.IndexOf("5.0") == 0) ? "Windows 2000"   :
        (ver.IndexOf("4.0") == 0) ? "Windows NT 4.0" :
        (ver.IndexOf("4.9") == 0) ? "Windows Me"     :
        (ver.IndexOf("4.1") == 0) ? "Windows 98"     :
        "???" ;
    textBox1.Text += "この OS は " + os_name + " です。" ;
}
OS 名9598MeNT 4.02000XP
Major Version444455
Minor Version01090001
// Note: 上記の例では、"Windows 95" もバージョンが 4.0 なので、"Windows NT 4.0"
//       と区別できない筈であるが、"Windows 95" は、C# の実行環境をサポートして
//       いないので、C# のプログラムとしては、これで問題はない。

指定アプリが実行中か確認
// 指定したアプリが実行中か「実行ファイル名で」確認する

using System.Diagnostics ;  // for Process

string exe_name = "HPS" ;  // 実行ファイル名  注:拡張子を含めない

if (Process.GetProcessesByName(exe_name).Length >= 1)
{
    /* "HPS.exe" が実行中の場合の処理 */
}

// Note: GetProcessesByName() は、初回に限り 実行環境によっては、処理時間が非常に
//       かかることがある(10秒 3秒 以上)。

アプリの多重起動を防ぐ
// 同じ実行ファイル名のプロセスは起動しない
// 注) パス違いでも「同名」実行ファイルは起動しない!

using System.Diagnostics ;  // for Process

if (Process.GetProcessesByName(
        Process.GetCurrentProcess().ProcessName).Length > 1)
{
    MessageBox.Show("すでに起動しています!");
    Application.Exit() ;
}

// 同じ Mutex 名を持つプロセスは起動しない(その1) // 注) パス違いでも「同一」実行ファイルは起動しない! using System.Threading ; // for Mutex private static Mutex mutex ; mutex = new Mutex(false, 固有アプリ名) ; // Mutex 生成 ; false = 所有権なし if (!mutex.WaitOne(0, false)) // Mutex 取得 ; false = 再取得なし { MessageBox.Show("すでに起動しています!") ; Application.Exit() ; } // Note: Mutex は、共有リソースへの排他アクセス権を1つのスレッドにだけ与える // 同期プリミティブである。
// 同じ Mutex 名を持つプロセスは起動しない(その2) // 注) パス違いなら「同一」実行ファイルでも起動する! using System.Threading ; // for Mutex private static Mutex mutex ; string mutex_name = "[C#] " + Environment.GetCommandLineArgs()[0] ; // path付 exe名 mutex = new Mutex(false, mutex_name.Replace("\\", "/")) ; // Mutex 生成 if (!mutex.WaitOne(0, false)) // Mutex 取得 { MessageBox.Show( "すでに起動しています!\n\n" + mutex_name.Substring(5) + " ", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Stop) ; Application.Exit() ; } // Note: Mutex 名に '\' を含めてはダメ(例外が発生する)。

指定アプリの起動
using System.Diagnostics ;  // for Process

// アプリを起動する

Process.Start("C:\\Program Files\\Hidemaru\\hidemaru.exe") ;

// コマンドライン引数を付けて、アプリを起動する Process.Start("C:\\Program Files\\Hidemaru\\hidemaru.exe", "memo.txt") ;
// ウィンドウを最小化して、コマンドライン引数を付けて、 // 作業フォルダ(WorkingDirectory)は アプリのあるパスに設定し、 // アプリを起動する Process process = new Process() ; process.StartInfo.FileName = "C:\\Program Files\\Hidemaru\\hidemaru.exe" ; process.StartInfo.Arguments = "memo.txt" ; process.StartInfo.WindowStyle = ProcessWindowStyle.Minimized ; process.StartInfo.WorkingDirectory = "C:\\Program Files\\Hidemaru" ; process.Start() ; // Note: 作業フォルダ(WorkingDirectory)の設定を省略してしまうと、そのアプリを起動 // した側の作業フォルダが使われて(継承されて)しまうので、注意せよ!

指定ファイルを開く
// 指定ファイルを、関連付けられたアプリで開く

using System.Diagnostics ;  // for Process

Process.Start("memo.txt") ;

// Note: 指定ファイルのパスを省略した場合、カレントディレクトリ が使われる。

指定アプリの終了待ち
// 指定したアプリが終了するまで待つ

using System.Diagnostics ;  // for Process

Process process_1 = Process.Start("C:\\BIN\\HPS.exe") ;

process_1.WaitForExit() ;

// Note: WaitForExit() の () 内に数値を記述すると、最大待機時間(単位ms)を指定する
//       ことができる。 戻り値は、プロセスが終了した場合 true、それ以外 false 。

DOS コマンドの出力の取得
// DOS コマンド "DIR" を実行し、その出力を TextBox に表示する



using System.Diagnostics ;  // for Process

private void button1_Click(object sender, System.EventArgs e)
{
    Process p = new Process() ;
    p.StartInfo.FileName = Environment.GetEnvironmentVariable("ComSpec") ; // cmd.exe
    p.StartInfo.CreateNoWindow         = true ;   // 起動に ウィンドウ を使用しない
    p.StartInfo.UseShellExecute        = false ;  // 起動に OS のシェルを使用しない
    p.StartInfo.RedirectStandardInput  = false ;  // 標準リダイレクト入力を不許可
    p.StartInfo.RedirectStandardOutput = true ;   // 標準リダイレクト出力を許可
    p.StartInfo.Arguments = @"/C DIR C:\ /ON" ;   // コマンド設定(/C = 実行後 終了)
    p.Start() ;                                   // 起動

    string output = p.StandardOutput.ReadToEnd() ;  // 出力を取得(参照の宣言のみ)
    p.WaitForExit() ;                               // プロセスが終了するまで待つ
    textBox1.Text = output ;                        // 表示(出力を実際に取得)
}

// Note: DOS コマンド(コマンド プロンプト) の「使い方」は、スタートメニュー から
//       プログラム → アクセサリ → コマンド プロンプト で、"cmd /?" を実行して
//       表示されたヘルプを参照せよ。

// Note: 上記、WaitForExit() の位置に注意せよ!
//       これを、StandardOutput.ReadToEnd() より前に置いてはダメ。

// 参考: MSDN『 C# Process.StandardOutput プロパティ 』 / ms-help

ホームページを開く
using System.Diagnostics ;  // for Process

// ホームページを(既に起動しているブラウザの中で)開く
// 起動しているブラウザがなければ、新しくブラウザを起動する

Process.Start("http://homepage3.nifty.com/midori_no_bike/") ;

// ホームページを(常に)新しく起動したブラウザで開く Process.Start("iexplore.exe", "http://homepage3.nifty.com/midori_no_bike/") ;

メールソフトを開く(送信用)
// メールソフト(標準のメールクライアント)の送信用ウィンドウを開く

using System.Diagnostics ;  // for Process

Process.Start(
    "mailto:abc0123@niftyy.com" +  // 宛先
    "?" +
    "subject=これはテストです"     // 件名
    ) ;

// Note: 件名が不要なら、"?subject=" 以降は 付けなくてよい。

重い処理中でも応答を早く
// 他のイベント処理要求に早く応答するため、時々、Application.DoEvents() により、
// Windows メッセージを処理する    [別方法:重い処理はスレッドを使う]

private void button1_Click(object sender, System.EventArgs e)
{
    button1.Enabled = false ;  // ← 必須!

    // 重い処理
    for (int M = 1 ; M <= 1000 ; M ++)
    {
        for (int N = 1 ; N <= 10000000 ; N ++)
        {
            /* 処理 */
        }
        Application.DoEvents() ;  // 現在ある Windows メッセージをすべて処理
    }

    button1.Enabled = true ;  // ← 必須!
}

// Note: Application.DoEvents() は、副作用を伴う!
//       button1 の処理中に button1 を押すと多重に起動してしまうので、対策として、
//         処理の始めに「button1.Enabled = false」と
//         処理の終りに「button1.Enabled = true 」を
//       実行させる必要がある!

重い処理はスレッドを使う
// 重い処理は「スレッド」にして実行する

using System.Threading ;  // for Thread

private void button1_Click(object sender, System.EventArgs e)
{
    Thread thread_1 = new Thread(new ThreadStart(func_1)) ;  // スレッドの宣言
    thread_1.Start() ;                                       // スレッドの起動
}

private void func_1()
{
    /* スレッドの本体(重い処理)*/
}

// Note: スレッドの中で、Form を生成(new)してはいけない!
//       たとえ生成しても、スレッド記述の文末で Form が消える。
//       これは、Form が、生成されたスレッド内でしか有効でない仕様のため。

// 参考: ms-help『 C# スレッド化チュートリアル 』

スレッドの一時停止
// スレッドを一時停止する

using System.Threading ;  // for Thread

private void func_1()
{
    /* スレッドの本体 */
    // 処理 その1
    Thread.Sleep(3000) ;  // スレッドを 3000ms 一時停止
    // 処理 その2
}

// Note: Thread.Sleep() を、メインのイベント処理の中で 使用すると、メインの処理
//       全体が、そこで停止するので注意すること!
//       たとえば、button1_Click() の中で使用すると、他のボタンの応答処理が待た
//       されてしまう(スレッドの中での使用なら、待たされない)!

スレッドの中止
// スレッドを中止(強制終了)する

using System.Threading ;  // for Thread

Thread thread_1 ;

private void button1_Click(object sender, System.EventArgs e)
{
    thread_1 = new Thread(new ThreadStart(func_1)) ;  // スレッドの宣言
    thread_1.Start() ;                                // スレッドの起動
}

private void button2_Click(object sender, System.EventArgs e)
{
    thread_1.Abort() ;  // スレッドの中止
}

型のエイリアス
// using ディレクティブを使って 型のエイリアス(別名)を定義する

using  MyInt  = System.Int16 ;
using  MyLong = System.Int32 ;

namespace MyExe
{
    MyInt  M =  100 ;
    MyLong N = 2000 ;
     :
     :
}

// 参考: MSDN『 C# using (エイリアス) ディレクティブ 』 / ms-help

配列の宣言
// 配列は、オブジェクト扱い!  ← C, C++ とは、宣言のフォーマットが異なる!

int[]  int_array = new int[5] ;
int[]  int_array = new int[] { 2, 4, 6, 8, 10 } ;  // 初期化を含む宣言

int[,] int_array = new int[2, 5] ;                 // 2次元配列
int[,] int_array = new int[,] { { 2, 4, 6, 8, 10 }, { 1, 3, 5, 7, 9} } ;

ローカル変数
// 変数を、関数内、または、ブロック内で宣言すると、ローカル変数となる

void func_1()
{
                                       ─┐
    int L ;                              │ L は この関数 func_1() 内で有効
                                       ─┘
                                       ─┐
    for (int M = 0 ; M <= 10 ; M ++)     │
    {                                    │
        int N ;                          │ M と N は このブロック内で有効
        /* ブロック内の処理 */           │
    }                                    │
                                       ─┘
}

// Note: 関数内で、同じ変数は、1度しか宣言できない!
//       上記の場合、"int N" のところで、"int L" は宣言できない!

グローバル変数
// C# では、グローバル変数を、サポートしていない!
// 代替策として、static による「擬似」グローバル変数宣言を使う

public class Form1
{
    static public int X = 0 ;  // グローバル変数の宣言
}

public class Form2
{
    int Y = Form1.X ;  // Form1 で宣言されたグローバル変数の使用
}

グローバル関数
// C# では、グローバル関数を、サポートしていない!
// 代替策として、static による「擬似」グローバル関数宣言を使う

public class Form1
{
    static public void glob_func()  // グローバル関数の宣言
    {
        // 関数本体
    }
}

public class Form2
{
    Form1.glob_func() ;  // Form1 で宣言されたグローバル関数の使用
}

複数の値を返す関数 (ref)
// 複数の変数名を ref で渡し、関数内で値を「参照/更新」する

// 引数で指定された2つの変数の値を、それぞれ +1 する関数

int M = 3 ;
int N = 4 ;

INC(ref M, ref N) ;  // M ← 4、N ← 5

void INC(ref int x, ref int y)
{
    x ++ ;
    y ++ ;
}

// Note: 関数を呼び出す前に、必ず ref で渡す変数の値を設定すること。
//       設定しないと、コンパイルエラーとなる!

複数の値を返す関数 (out)
// 複数の変数名を out で渡し、関数内で値を「設定」する

// 引数で指定された2つの変数に、それぞれ 4 と 5 を設定する関数

int M ;
int N ;

SET(out M, out N) ;  // M ← 4、N ← 5

void SET(out int x, out int y)
{
    x = 4 ;
    y = 5 ;
}

// Note: 関数内では、out の値を参照できない(設定のみ可)。
//       参照すると、コンパイルエラーとなる!

// Note: 関数内で、必ず out で渡された変数の値を設定すること。
//       設定しないと、コンパイルエラーとなる!

可変個の引数の関数
// params キーワードにより、可変個の引数を持つ関数を記述する

int N = sum(1, 2, 3, 4, 5) ;  // 引数すべての合計値を求める

private int sum(params int[] args)
{
    int acc = 0 ;
    foreach (int arg in args)
        acc += arg ;
    return acc ;
}

// Note: 複数の引数を記述する場合、params キーワードは、最後の引数にだけ許される。

バイト操作(MemoryStream)
// バイト型の配列を Stream として扱う

//「 textBox2.Text = textBox1.Text + "\r\nABC" 」を MemoryStream で行う例



using System.IO ;    // for MemoryStream
using System.Text ;  // for Encoding

private void button1_Click(object sender, System.EventArgs e)
{
    MemoryStream ms = new MemoryStream() ;

    // textBox1 の文字列を "Shift_JIS"コードで バイト型配列に変換
    byte[] bs1 = Encoding.GetEncoding("Shift_JIS").GetBytes(textBox1.Text) ;

    ms.Write(bs1, 0, bs1.Length) ;  // バイト型配列  を MemoryStream に追加
    ms.WriteByte((byte)'\r') ;      // バイト型データを MemoryStream に追加
    ms.WriteByte((byte)'\n') ;      //  ( 同上 )
    ms.WriteByte((byte)'A') ;       //  ( 同上 )
    ms.WriteByte((byte)'B') ;       //  ( 同上 )
    ms.WriteByte((byte)'C') ;       //  ( 同上 )

    byte[] bs2 = ms.ToArray() ;     // MemoryStream をバイト型配列に変換

    // バイト型配列を "Shift_JIS"コード" とみなし 文字配列に変換
    char[] bs3 = Encoding.GetEncoding("Shift_JIS").GetChars(bs2) ;

    textBox2.Text = new String(bs3) ;  // 文字配列を文字列に変換して出力

    ms.Close() ;
}

// Note: MemoryStream を StreamReader で読む場合、設定は下記のように行う。
//       StreamReader sr = new StreamReader(
//                                 ms,
//                                 Encoding.GetEncoding("Shift_JIS")) ;

ユーザ定義によるソート
// textBox1 の単語を、文字長の小さい順にソートして、textBox2 に表示する



private void button1_Click(object sender, System.EventArgs e)
{
    ArrayList   al = new ArrayList() ;
    string[] conts = textBox1.Text.Replace("\r", "").Split(new char[] {'\n'}) ;
    foreach (string cont in conts)
        al.Add(cont) ;

    MyComparer my_comp = new MyComparer() ;
    al.Sort(my_comp) ;                  // ArrayList をソートする
    
    textBox2.Text = "" ;
    foreach (string cont in al)
        textBox2.Text += cont + "\r\n" ;
}

private class MyComparer : IComparer    // ソート(比較)のユーザ定義文
{
    public int Compare(object x, object y)                  // 定型文
    {
        return ((string) x).Length - ((string) y).Length ;  // 文字長の比較
    }
}

// Note: IComparer.Compare メソッドは、2つのオブジェクトを比較し、一方が他方より
//       小さいか、等しいか、大きいかを示す値を返す。 値の意味は、以下のとおり。
//           0 より小さい値  =  x が y より小さい
//           0               =  x と y は等しい
//           0 より大きい値  =  x が y より大きい

日時の取得と計算 ☆ 書式指定 テスター
// 現在の日時を取得

string A = DateTime.Now.ToString() ;              // "2003/01/16 12:08:41"
string B = DateTime.Now.ToString("F") ;           // "2003年1月16日 12:08:41"
string C = DateTime.Today.ToString() ;            // "2003/01/16 00:00:00"
int    D = DateTime.Today.Year ;                  //  2003 (年)
int    E = DateTime.Today.Month ;                 //     1 (月)
int    F = DateTime.Today.Day ;                   //    16 (日)
string G = DateTime.Today.DayOfWeek.ToString() ;  // "Thursday"
string H = DateTime.Now.TimeOfDay.ToString() ;    // "12:08:41.3146250"

// 基準日との日時差を計算 DateTime J = new DateTime(1995, 1, 1) ; // 基準日 TimeSpan K = DateTime.Now - J ; // 日時差の計算 double L = K.TotalHours ; // 70500.1448052778 (時間の差) double M = K.TotalDays ; // 2937.50603355324 (日の差) int N = K.Days ; // 2937 (日の差 @端数なし) // Note: DateTime での ToString() の引数は、書式指定(日付と時刻)を参照。

PC起動後の経過時間
// PC起動後のミリ秒単位の経過時間を取得する



private void button1_Click(object sender, System.EventArgs e)
{
    int tc = Environment.TickCount ;              // ミリ秒単位で経過時間を取得

    TimeSpan ts = new TimeSpan(0, 0, 0, 0, tc) ;  // 値を TimeSpan 型へ変換する

    textBox1.Text =
        "経過秒数 = " + (tc/1000)  + "秒\r\n" +
        "経過日時 = " + ts.Days    + "日"   +
                        ts.Hours   + "時間" +
                        ts.Minutes + "分"   +
                        ts.Seconds + "秒"   ;
}

// Note: この TickCount は、32ビット符号付き整数である。 そのため、最大値は、
//       24.9日間となる。その後は 0 に戻る。解像度は、500ms未満には設定不可。

曜日の取得
// 今日の "曜日" を取得し TextBox に表示する



private void button1_Click(object sender, System.EventArgs e)
{
    string W = ("日月火水木金土").Substring(
        int.Parse(DateTime.Now.DayOfWeek.ToString("d")),
        1) ;
    textBox1.Text = "今日は、" + W + "曜日です。" ;
}

// Note: DayOfWeek 列挙型は、曜日を表し、日曜日の 0 から土曜日の 7 までを示す。
//       例) DateTime.Now.DayOfWeek.ToString("d")  →  1
//           DateTime.Now.DayOfWeek.ToString("f")  →  Monday

// DateTimePicker の日付に対応する "曜日" を取得し TextBox に表示する 配置 DateTimePicker, TextBox ; private void dateTimePicker1_ValueChanged(object sender, System.EventArgs e) { textBox1.Text = dateTimePicker1.Value.ToString("dddd") ; // "dddd" = 曜日 } // Note: ToString() の引数は、書式指定(日付と時刻)を参照。

月末の日か判定
// 今日が、月末の日か判定する

if (DateTime.Now.AddDays(1).Day == 1)    // 翌日が 1日 か調べる
{
    /*「月末の日」の場合の処理 */
}

閏年か判定
// 閏年かどうかを判定する



private void button1_Click(object sender, System.EventArgs e)
{
    int  this_year = DateTime.Now.Year ;
    bool leap      = DateTime.IsLeapYear(this_year) ;  // 閏年なら true

    textBox1.Text  = "今年" + this_year + "年は、閏年" +
                    (leap ? "です。" : "でありません。") ;
}

和暦(元号の取得)
// DateTime で指定した日時の「元号」を取得する



using System.Globalization ;  // for CultureInfo, JapaneseCalendar

private void button1_Click(object sender, System.EventArgs e)
{
    CultureInfo cult_info             = new CultureInfo("ja-JP") ;
    cult_info.DateTimeFormat.Calendar = new JapaneseCalendar() ;
    textBox1.Text = DateTime.Now.ToString("今日はg(元号)y年M月d日", cult_info) ;
}

// Note: 和暦の場合、DateTime で指定できるのは、明治が始まった時(西暦1868年9月8日)
//       以降。それより前だと、例外 System.ArgumentOutOfRangeException が発生する。

シンプルな時計
// Timer を使って現在の時刻を1秒毎に表示する



配置 Timer, Label ;

private void Form1_Load(object sender, System.EventArgs e)
{
    timer1.Interval = 1000 ;  // タイマの間隔を 1000[ms] に設定
    timer1.Start() ;          // タイマを起動
}

private void timer1_Tick(object sender, System.EventArgs e)
{
    label1.Text = DateTime.Now.ToString("F") ;  // 現在の時刻を表示
}

// Note: タイマの停止は、Stop() を使う。

// Note: Form のスタイルについては、Form を画像の形にする を参照。

// Note: この System.Windows.Forms.Timer のイベント間隔は、システムに対して
//       重い負荷がかかった場合、設定時間より(時には1割以上)長くなる!

実行時間の高精度な計測
// QueryPerformanceCounter を使って、実行時間をマイクロ秒単位で計測する



配置 Button, TextBox ;

using System.Runtime.InteropServices ;  // for DllImport

[DllImport("kernel32.dll")]
extern static short QueryPerformanceCounter(ref long x) ;
[DllImport("kernel32.dll")]
extern static short QueryPerformanceFrequency(ref long x) ;

private void button1_Click(object sender, System.EventArgs e)
{
    long time1 = 0 ;
    long time2 = 0 ;
    long freq  = 0 ;

    QueryPerformanceCounter(ref time1) ;   // 計測開始!
                                           ┐
    for (int N = 1 ; N <= 100000 ; N ++)   │ 計測対象の
        Math.Sqrt(N) ;                     │  コード(一例)
                                           ┘
    QueryPerformanceCounter(ref time2) ;   // 計測終了!

    QueryPerformanceFrequency(ref freq) ;  // カウンタ周波数(3579545Hz)の取得
    textBox1.AppendText(
        "実行時間 = " + 
        (1000000 * (time2 - time1) / freq).ToString() + " μs\r\n") ;
}

// Note: 別のスレッドやプロセスが動作していると、計測誤差が発生する! 誤差を
//       小さくするためには、複数回の計測の必要がある。

// Note: 別の計測方法として、DateTime.Now を利用した「やり方」もあるが、その
//       精度は、15.625ms 単位である。

ビープ音を鳴らす
// ビープ音を鳴らす

using System.Runtime.InteropServices ;  // for DllImport

//-----------------------------------------------------------

[DllImport("user32.dll")]
extern static int MessageBeep(uint n) ;

private void button1_Click(object sender, EventArgs e)
{
    // wave 形式のサウンドを再生
    MessageBeep(0x00) ;
        // 0x00 = MB_OK              / 一般の警告音 
        // 0x10 = MB_ICONHAND        / システムエラー 
        // 0x20 = MB_ICONQUESTION    / メッセージ(問合わせ) 
        // 0x30 = MB_ICONEXCLAMATION / メッセージ(警告) 
        // 0x40 = MB_ICONASTERISK    / メッセージ(情報) 
}

//-----------------------------------------------------------

[DllImport("kernel32.dll")] 
extern static bool Beep(uint dwFreq, uint dwDuration) ;

private void button2_Click(object sender, EventArgs e)
{
    // PC 本体内のブザーを鳴らす
    Beep(440, 2000) ;  // 440Hz, 2000ms
}

サウンドデータの再生
// winmm.dll の PlaySound() を使って「サウンドデータ」を再生する(簡単な方法)

using System.Runtime.InteropServices ;  // for DllImport

[DllImport("winmm.dll")]
extern static bool PlaySound(string s1, IntPtr i1, int i2) ;
// 返り値 = true @正常終了, false @エラー
// s1 = Sound File Name / Resource ID
// i1 = Instance Handle @SND_RESOURCE
// i2 = Flags(↓)
const int SND_SYNC     = 0x00000 ;  // 同期再生  (再生終了後に制御を返す)
const int SND_ASYNC    = 0x00001 ;  // 非同期再生(即座に制御を返す)
const int SND_LOOP     = 0x00008 ;  // 繰り返し再生
const int SND_FILENAME = 0x20000 ;  // s1 は Sound File Name
const int SND_RESOURCE = 0x40004 ;  // s1 は Resource ID

private void button1_Click(object sender, System.EventArgs e)  // 再生の例
{
    // button1 が押されたら、再生する(非同期再生)
    PlaySound(@"C:\test\サンプル.wav", IntPtr.Zero, SND_FILENAME | SND_ASYNC) ;
}

private void button2_Click(object sender, System.EventArgs e)  // 停止の例
{
    // button2 が押されたら、停止する
    PlaySound(null, IntPtr.Zero, 0) ;
}

// Note: "winmm.dll" は、Windows に標準でインストールされている。

// Note: 再生可能なサウンド形式は、WAVE のみ。

// Note: PlaySound() では、ファイルのオープン/クローズの記述は必要ない。

// Note: 細かい制御が必要な場合は、下記の mciSendString() を使用せよ。

// winmm.dll の mciSendString() を使って「サウンドデータ」を再生する(高機能) using System.Runtime.InteropServices ; // for DllImport using System.Text ; // for StringBuilder [DllImport("winmm.dll")] extern static int mciSendString(string s1, StringBuilder s2, int i1, int i2) ; // 返り値 = 0 @正常終了 // s1 = Command String // s2 = Return String // i1 = Return String Size // i2 = Callback Hwnd private int sound_open(string file_name) { // ファイルを open return mciSendString("open \"" + file_name + "\" alias my_sound", null, 0, 0) ; /* 注) alias で、デバイス名を my_sound と定義。他の適当な文字列でも OK。*/ } private void sound_close() { // ファイルを close mciSendString("close my_sound", null, 0, 0) ; } private void sound_play() { // 再生を開始 mciSendString("play my_sound", null, 0, 0) ; } private void sound_stop() { // 停止 mciSendString("stop my_sound", null, 0, 0) ; } private void sound_pause() { // 一時停止 mciSendString("pause my_sound", null, 0, 0) ; } private void sound_resume() { // 一時停止解除 mciSendString("resume my_sound", null, 0, 0) ; } StringBuilder sb = new StringBuilder(32) ; // mciSendString() の // Return String 格納用 private string sound_get_mode() { // 状態を取得 // 返り値: 再生中 = "playing" // 停止中/再生終了 = "stopped" // 一時停止中 = "paused" mciSendString("status my_sound mode", sb, sb.Capacity, 0) ; return sb.ToString() ; } private int sound_get_position() { // play 中のファイルの位置を ms単位 で返す mciSendString("status my_sound position", sb, sb.Capacity, 0) ; return int.Parse(sb.ToString()) ; } private int sound_get_length() { // open 中のファイルの曲長を ms単位 で返す mciSendString("status my_sound length", sb, sb.Capacity, 0) ; return int.Parse(sb.ToString()) ; } private void button1_Click(object sender, System.EventArgs e) // 再生の例 { // button1 が押されたら、再生する sound_open(@"C:\test\サンプル.mp3") ; sound_play() ; } private void button2_Click(object sender, System.EventArgs e) // 停止の例 { // button2 が押されたら、停止する sound_stop() ; sound_close() ; } // Note: "winmm.dll" は、Windows に標準でインストールされている。 // Note: 再生可能なサウンド形式は、WAVE/MIDI/MP3/WMA など。 // Note: Windows 98 などの古い OS の場合、mciSendString でファイルを open する時、 // 「長いファイル名」では稀に失敗することがある(失敗条件不明)。 // その場合は「短いファイル名」を使って open せよ。⇒ 短いファイル名の取得
// MMControl を使って「サウンドデータ」を再生する(少し特殊な方法) 配置 MMControl, Button, TextBox ; // MMControl は下記 Note 参照。 private void button1_Click(object sender, System.EventArgs e) { // 多重 Open しないようにする if (axMMControl1.Mode != (int)MCI.ModeConstants.mciModeNotOpen) axMMControl1.Command = "Close" ; // textBox1 で指定したファイルのサウンドデータを再生する axMMControl1.FileName = textBox1.Text ; axMMControl1.Command = "Open" ; axMMControl1.Command = "Play" ; } // Note: 上記 MMControl をデザイナから呼び出すには、事前に登録が必要。 // ツール → ツールボックスのカスタマイズ... を選択し、COM コンポーネント // 「Microsoft Multimedia Control」のチェックを行うこと。 // Note: Form に貼り付けた MMControl の画像表示が邪魔なら "axMMControl1.Hide()" // で隠してもよい(サウンド出力は正常に行う)。 // Note: textBox1 で指定したファイルが存在しない場合、button1 を押しても、何も // 起こらない(例外も発生しない)! // Note: サウンド出力が終了しないうちに 再度 button1 を押した場合、前のサウンド // 出力は強制中断し、すぐに次のサウンド出力を開始する。 // Note: 再生可能なサウンド形式は、WAVE/MIDI/MP3/WMA など。 // MPEG の場合、別ウィンドウが開いて、そこに動画が表示される。 // Note: MCI(Media Control Interface)ランタイム MCI32.OCX, MCIJP.DLL が必要。 // "\WINDOWS\system32" フォルダ内に該当ファイルがあるかで、確認可能。 // Vector サイトの『 VB6 ランタイムスペシャル 』などを利用すると良い。

空きメモリ量を取得
// GlobalMemoryStatus() API を使って、空きメモリ量を取得し、textBox1 に表示する



配置 Button, TextBox ;

using System.Runtime.InteropServices ;  // for DllImport

[DllImport("kernel32.dll")]
extern static void GlobalMemoryStatus(ref tagMEMORYSTATUS lpBuffer) ;

public struct tagMEMORYSTATUS
{
    public int dwLength ;
    public int dwMemoryLoad ;
    public int dwTotalPhys ;      // 合計 物理メモリ     
    public int dwAvailPhys ;      // 空き 物理メモリ
    public int dwTotalPageFile ;  // 合計 ページファイル
    public int dwAvailPageFile ;  // 空き ページファイル
    public int dwTotalVirtual ;   // 合計 仮想メモリ(2GB 固定?)
    public int dwAvailVirtual ;   // 空き 仮想メモリ
}

private void button1_Click(object sender, System.EventArgs e)
{
    tagMEMORYSTATUS ms = new tagMEMORYSTATUS() ;
    ms.dwLength = Marshal.SizeOf(ms) ;  // 準備
    GlobalMemoryStatus(ref ms) ;        // メモリ情報を取得
    
    textBox1.Text =
        "合計 物理     " + ms.dwTotalPhys.ToString("n0")     + " Byte\r\n" +
        "空き 物理     " + ms.dwAvailPhys.ToString("n0")     + " Byte\r\n" +
        "合計 ページ   " + ms.dwTotalPageFile.ToString("n0") + " Byte\r\n" +
        "空き ページ   " + ms.dwAvailPageFile.ToString("n0") + " Byte\r\n" +
        "合計 仮想   "   + ms.dwTotalVirtual.ToString("n0")  + " Byte\r\n" +
        "空き 仮想   "   + ms.dwAvailVirtual.ToString("n0")  + " Byte\r\n" ;
}

CPU 使用率を取得
// PerformanceCounter を使って、CPU 使用率を取得し、textBox1 に表示する



配置 Button, TextBox ;

using System.Diagnostics ;  // for PerformanceCounter

PerformanceCounter performanceCounter1 ;
PerformanceCounter performanceCounter2 ;

private void Form1_Load(object sender, System.EventArgs e)
{
    performanceCounter1 = new PerformanceCounter() ;
    performanceCounter1.CategoryName = "Processor";
    performanceCounter1.CounterName  = "% Idle Time";
    performanceCounter1.InstanceName = "_Total";

    performanceCounter2 = new PerformanceCounter() ;
    performanceCounter2.CategoryName = "Processor";
    performanceCounter2.CounterName  = "% User Time";
    performanceCounter2.InstanceName = "_Total";
}

private void button1_Click(object sender, System.EventArgs e)
{
    textBox1.Text =
      "ALL  " + (100 - performanceCounter1.NextValue()).ToString("f0") + "%\r\n" +
      "User " +         performanceCounter2.NextValue().ToString("f0") + "%\r\n" ;
}

// Note: CPU使用率(ALL)は、100% から Idle 時間[%]を引いて算出している。

// Note: 初回の NextValue() の取得値は、ゼロになる!
//       初回の NextValue() の実行完了には、時間がかかる(約10秒)!

// Note: PerformanceCounter は、デザイナを使っても設定が可能。

// Note: PerformanceCounter は、他の情報も取得可能。下記に一例を示す。
//
//       CPU動作周波数[MHz]
//           CategoryName = "ProcessorPerformance";
//           CounterName  = "frequency";
//           InstanceName = "ACPI\\GenuineIntel_-_x86_Family_6_Model_11\\_0_0";
//
//       空き物理メモリ[MB]
//           CategoryName = "Memory";
//           CounterName  = "Available MBytes";
//
//       使用仮想メモリ[Byte]
//           CategoryName = "Memory";
//           CounterName  = "Committed Bytes";
//
//       仮想メモリサイズ[Byte]
//           CategoryName = "Memory";
//           CounterName  = "Commit Limit";

// Note: PerformanceCounter は、PC環境によっては、取得できないカウンタ情報もある。
//       そのPCで使用可能なカウンタを(手動で)調べるには、
//       perfmon.exe(コントロールパネル →管理ツール →パフォーマンス @WindowsXP)
//       を実行し、コンソール のツリーの中の システムモニタ をクリックし、ツール
//       バーの「+」ボタンをクリックする。
//       そうすると、カウンタ追加ダイアログ が表示される。その中のリストボックス
//      「一覧からカウンタを選ぶ」に表示されているものが使用可能なカウンタである。

レジストリのデータを取得
// RegistryKey を使って、レジストリのデータを取得し、textBox1 に表示する

// プロセッサの情報を表示する例



配置 Button, TextBox ;

using Microsoft.Win32 ;  // for RegistryKey

private void button1_Click(object sender, System.EventArgs e)
{
    string      sub_key = "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0" ;
    RegistryKey reg_key = Registry.LocalMachine.OpenSubKey(sub_key) ;
    
    textBox1.Text =
        "Name  : " + reg_key.GetValue("ProcessorNameString") + "\r\n" +
        "ID    : " + reg_key.GetValue("Identifier")          + "\r\n" +
        "Clock : " + reg_key.GetValue("~MHz")                + "MHz" ;
}

// Note: SubKeyの作成は、OpenSubKey(SubKey名) の代わりに CreateSubKey(SubKey名)
//       メソッドを使う。

// Note: データの設定は、GetValue(名前) の代わりに SetValue(名前, データ)
//       メソッドを使う。

// Note: データの削除は、GetValue(名前) の代わりに DeleteValue(名前)
//       メソッドを使う。

Web からダウンロード
// Web からファイルをダウンロードする

// textBox1 で指定した URL のファイルを、TMP フォルダにダウンロードし、結果を
// textBox2 に表示する。

using System.Net ;  // for WebClient

private void button1_Click(object sender, System.EventArgs e)
{
    string url  = textBox1.Text ;
    string file = "C:\\TMP\\" + url.Substring(url.LastIndexOf("/") + 1) ;

    WebClient wc = new WebClient() ;
    try
    {
        wc.DownloadFile(url, file) ;  // ダウンロードする
    }
    catch
    {
        textBox2.Text = "エラーです!" ;
        return ;
    }
    textBox2.Text = "ダウンロード終了!" ;
}

Web ブラウザを組み込む
// Web ブラウザを組み込み、ホームページを表示する(.NET Framework 2.0 以降)



配置 WebBrowser, Button ;

private void button1_Click(object sender, System.EventArgs e)
{
    string my_url = "http://homepage3.nifty.com/midori_no_bike/" ;
    webBrowser1.Navigate(my_url) ;
}

// Note: WebBrowser は .NET Framework 2.0 以降で使用可能 !

Web から HTML を取得 (1)
// Web から HTML テキストを取得する(.NET Framework 2.0 以降)
// → 上記「Webブラウザを組み込む」を利用する

// textBox1 で指定した URL の HTML を、textBox2 に表示する



配置 WebBrowser, Button, TextBox, TextBox ;

private void button1_Click(object sender, EventArgs e)
{
    // ホームページを表示する
    string my_url = textBox1.Text ;
    webBrowser1.Navigate(my_url) ;
}

private void webBrowser1_DocumentCompleted(
    object sender, WebBrowserDocumentCompletedEventArgs e)
{
    // HTML テキストを取得する

    HtmlDocument doc = webBrowser1.Document ;
    textBox2.Text    = doc.GetElementsByTagName("html")[0].OuterHtml ;

    // 注) 取得した HTML テキストは、オリジナルと比べて、微妙に異なる!
    //       1) タグ名が、大文字に変換される。
    //       2) 属性名が、小文字に変換される。
    //       3) 属性値の引用符 および 改行 が、一部、削除される。
    //     厳密にオリジナルと同じテキストを取得するには、下記のコードにする。
    // -------------------------------------------------------------------------
    //     int    len = (int)webBrowser1.DocumentStream.Length ;
    //     byte[] doc = new byte[len] ;
    //     webBrowser1.DocumentStream.Read(doc, 0, len) ;
    //     Encoding enc  = Encoding.GetEncoding(webBrowser1.Document.Encoding) ;
    //     textBox2.Text = enc.GetString(doc) ;

    // 注) 単純に「 textBox2.Text = webBrowser1.DocumentText ; 」と記述すると、
    //     文字化けする!
}

// Note: WebBrowser は .NET Framework 2.0 以降で使用可能 !

// 参考: MSDN『 C# からの DHTML DOM へのアクセス 』

Web から HTML を取得 (2)
// Web から HTML テキストを取得する(ネットワーク用のクラスを利用する方法)

// textBox1 で指定した URL の HTML を、textBox2 に表示する



配置 Button, TextBox, TextBox ;

using System.Net  ;  // for HttpWebRequest, HttpWebResponse
using System.IO   ;  // for StreamReader
using System.Text ;  // for Encoding

private void button1_Click(object sender, System.EventArgs e)
{
    string my_url = textBox1.Text ;
    HttpWebRequest  req = WebRequest.Create(my_url) as HttpWebRequest ;
    HttpWebResponse res = null ;
    try
    {
        res = req.GetResponse() as HttpWebResponse ;
    }
    catch
    {
        textBox2.Text = "指定した Web ページが応答していません!" ;
        return ;
    }
    StreamReader reader = new StreamReader(res.GetResponseStream(),
                                           Encoding.GetEncoding("Shift_JIS")) ;
    textBox2.Text = reader.ReadToEnd() ;
    reader.Close() ;
}

// Note: WebRequest.Create() で、URL の書式が適切でないと、例外が発生する!

// Note:「Web から HTML を取得(1)」の場合と異なり、取得した HTML テキストは、
//       オリジナルと全く同じ!

Web から HTML を取得 (3)
// Web から HTML を操作する(.NET Framework 2.0 以降)

HtmlElement html_body = null ;

private void webBrowser1_DocumentCompleted(
    object sender, WebBrowserDocumentCompletedEventArgs e)
{
    html_body = webBrowser1.Document.Body ;
}

private int html_body_scrollTop()        // プロパティの取得例
{
    // html_body.scrollTop を 取得
    return html_body.ScrollTop ;
}

private void html_body_scrollTop(int x)  // プロパティの設定例
{
    // html_body.scrollTop を x に設定
    html_body.ScrollTop = x ;
}

// Note: .NET Framework 2.0 では、特殊な dll を使うことなく、基本的な HTML
//       を操作することができる。
//       一方、.NET Framework 1.0 / 1.1 では、下記に示すように、少し複雑な
//       手続きが必要である。

// Web から HTML を操作する(.NET Framework 1.0 / 1.1) // AxWebBrowser を操作する方法として、mshtml を使うことが一般的だが、実際に、 // それを使用したプログラムを一般ユーザーへ配布する場合、Microsoft.mshtml.dll // (約8MB!!)も配布しなければ使えないので、問題である。 // ここでは Microsoft.mshtml.dll を使わず InvokeMember で実現する例を示す。 using System.Reflection ; // for BindingFlags Type typ ; object html_doc = null ; object html_body = null ; private void axWebBrowser1_DocumentComplete( object sender, AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEvent e) { typ = Type.GetTypeFromProgID("mhtmlfile") ; // ↑ MHTML Document \WINDOWS\system32\mshtml.dll html_doc = axWebBrowser1.Document ; html_body = typ.InvokeMember( "body", BindingFlags.GetProperty, null, html_doc, null) ; } private int html_body_scrollTop() // プロパティの取得例 { // html_body.scrollTop を 取得 return (int)typ.InvokeMember( "scrollTop", BindingFlags.GetProperty, null, html_body, null) ; } private void html_body_scrollTop(int x) // プロパティの設定例 { // html_body.scrollTop を x に設定 typ.InvokeMember( "scrollTop", BindingFlags.SetProperty, null, html_body, new object[] {x}) ; } // Note: Microsoft.mshtml.dll は、下記フォルダに存在する。 // \Program Files\Microsoft.NET\Primary Interop Assemblies\ // 参考: Microsoft サポート オンライン『 MSHTML のプライマリ interop ... 』

メールの送信
// SMTP (Simple Mail Transfer Protocol) で送信する(.NET Framework 2.0 以降)



配置 Button, TextBox, TextBox, TextBox, TextBox ;

using System.Net.Mail ;  // for SmtpClient

private void button1_Click(object sender, EventArgs e)
{
    MailMessage message = new MailMessage(
        textBox2.Text,  // from
        textBox1.Text,  // to
        textBox3.Text,  // subject
        textBox4.Text   // body
        ) ;
    SmtpClient smtp = new SmtpClient() ;
    smtp.Host = "xxx.yyy.ne.jp" ;  // SMTP 用ホスト名の設定
    smtp.Send(message) ;           // 送信
}

// Note: 本サンプルは、エンコードを指定していないので、utf-8 が使用される。
//       必要に応じて、message.SubjectEncoding、message.BodyEncoding などの
//       プロパティに、JISコード Encoding.GetEncoding("iso-2022-jp") を設定
//       すること。

// Note: 下記に示す SmtpMail クラスは、.NET Framework 2.0 では「非推奨」。

// SMTP (Simple Mail Transfer Protocol) で送信する(.NET Framework 1.0 / 1.1) 配置 Button, TextBox, TextBox, TextBox, TextBox ; using System.Web.Mail ; // for SmtpMail private void button1_Click(object sender, System.EventArgs e) { SmtpMail.Send( textBox2.Text, // From (Returned mail 先) textBox1.Text, // To textBox3.Text, // Subject textBox4.Text) ; // 本文 } // Note: "using System.Web.Mail ;" を有効にするためには 参照の追加 が必要。 // 具体的には、メインメニューで、プロジェクト → 参照の追加... を選択 // して、.NET のコンポーネント名「System.Web.dll」を追加する。 // Note: 複数の宛先(To)がある場合は、各メールアドレスを「,」で区切る。 // Note: 例外は、宛先(To)が NG、または、送信元(From)が空白 の場合にも発生する。 // Note: 本プログラムは、Windows 2000 / XP Professional / .NET Server family // でのみ、動作する。 // Note: 当然ながら、メール送信環境が起動していないと、送信に失敗する! // 送信に失敗する場合、他のメーラーで送信できるかチェックすること。

(C)緑のバイク