6月 13

レジストリに値を設定する

RegistryKeyクラスを使います。
使い方は値を取得する方とほぼ同じです。

using Microsoft.Win32; を忘れずに

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.Win32;  // これを追加

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // HKEY_CURRENT_USER\Software\hogehoge
            RegistryKey key = Registry.CurrentUser;
            
            // キーを作成。既にあるならそれを開く
            key = key.CreateSubKey(@"Software\hogehoge");

            // 値を設定
            key.SetValue("name", "ほげほげ", RegistryValueKind.String); // REG_SZ
            key.SetValue("length", 123, RegistryValueKind.DWord);       // REG_DWORD

            // 最後は閉じます(このタイミングでフラッシュされるので忘れずに)
            key.Close();
        }
    }
}
6月 13

レジストリから値を取得する

RegistryKeyクラスを使います。
以下のサンプルを実行する前に
あらかじめレジストリエディタを開いて
HKEY_CURRENT_USER\Software\hogehoge

REG_SZ(文字列)のname
REG_DWORD(数値)のlength
の2つの値を書き込んでおいてください。

なお、GetValue関数の第二引数は
値が存在しなかった場合のデフォルト値です。

using Microsoft.Win32; を忘れずに

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.Win32;  // これを追加

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // HKEY_CURRENT_USER\Software\hogehoge をオープン
            RegistryKey key = Registry.CurrentUser;
            key = key.OpenSubKey(@"Software\hogehoge");

            // 値を取得
            string value = (string)key.GetValue("name", "設定がありません");

            // 値の型を確認してから取得
            int length = 0;
            RegistryValueKind kind = key.GetValueKind("length");
            if (kind == RegistryValueKind.DWord)
            {
                length = (int)key.GetValue("length", 100);
            }

            // 最後は閉じます
            key.Close();

            MessageBox.Show(value + length.ToString());
        }
    }
}
6月 13

DOSコマンドを実行して結果を得る

System.Diagnostics.Process クラスを利用します。
例ではipconfigコマンドを実行し、その結果を文字列で取得しています。

追記:
fcコマンドでファイルの比較をこの方法で行おうとしたのですが
どうしてもうまくいきませんでした。。。orz
うまくいった方は方法を教えて頂けると参考になります。

>2011.11.01 追記
Hiroさんより掲示板にて情報を頂きました。

UseShellExecute = true;
に設定することで解決できるそうです。

参考:Executing file compare process from C#

http://www.dotnet247.com/247reference/msgs/21/107593.aspx

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Process pro = new System.Diagnostics.Process();

            pro.StartInfo.FileName = "ipconfig";            // コマンド名
            pro.StartInfo.Arguments = "/all";               // 引数
            pro.StartInfo.CreateNoWindow = true;            // DOSプロンプトの黒い画面を非表示
            pro.StartInfo.UseShellExecute = false;          // プロセスを新しいウィンドウで起動するか否か
            pro.StartInfo.RedirectStandardOutput = true;    // 標準出力をリダイレクトして取得したい

            pro.Start();

            string output = pro.StandardOutput.ReadToEnd();
            output.Replace("\r\r\n", "\n"); // 改行コード変換

            MessageBox.Show(output);
        }
    }
}
6月 13

電源を切る、シャットダウンする

方法は色々とありますが(Win32APIのExitWindowsExをコールするとか)
ここでは手っ取り早い方法だけ挙げます。

    System.Diagnostics.ProcessStartInfo psi =
        new System.Diagnostics.ProcessStartInfo();

    psi.FileName = "shutdown.exe";

    // コマンドラインパラメータ -s:シャットダウン -f:強制的に
    psi.Arguments = "-s -f";

    // ウィンドウ非表示に(効果なし?)
    psi.CreateNoWindow = true;

    // シャットダウン
    System.Diagnostics.Process p = System.Diagnostics.Process.Start(psi);
6月 13

システムをスタンバイ、休止状態にする

Application.SetSuspendState 関数を使います。
第2引数は、他アプリに通知するか否か(falseなら強制的に実施)
第3引数は、Wakeイベントでアクティブにならないようにするか否か

        // サスペンド状態に:通電はしてる
        Application.SetSuspendState(PowerState.Suspend, false, false);

        // 休止状態に:メモリをHDDに保存し、電源を切る
        Application.SetSuspendState(PowerState.Hibernate, false, false);
6月 13

電源状態を取得し、変更通知も取得する

電源状態(AC電源か?バッテリーか?)を取得するには
PowerStatusクラスのPowerLineStatusプロパティーを参照します。

電源変更通知を取得する場合は
Microsoft.Win32.SystemEvents.PowerModeChanged
イベントを取得してください。

以下のサンプルは
タスクトレイアイコンに電源変更通知のバルーンを表示します。
FormプロジェクトにnotifyIconを1つ追加してください。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace PowerNotifier
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // タスクトレイアイコンを見えるように
            notifyIcon1.Visible = true;

            // 電源状態が変更されたことを通知する
            Microsoft.Win32.SystemEvents.PowerModeChanged += new Microsoft.Win32.PowerModeChangedEventHandler(SystemEvents_PowerModeChanged);

            // 通知
            Notifier();
        }

        void SystemEvents_PowerModeChanged(object sender, Microsoft.Win32.PowerModeChangedEventArgs e)
        {
            switch (e.Mode)
            {
                // 電源状態が変更された
                case Microsoft.Win32.PowerModes.StatusChange:
                    Notifier();
                    break;
            }
        }

        void Notifier()
        {
            PowerStatus ps = SystemInformation.PowerStatus;

            switch (ps.PowerLineStatus)
            {
                case PowerLineStatus.Online:
                    notifyIcon1.BalloonTipTitle = "電源状態";
                    notifyIcon1.BalloonTipText = "AC電源です";
                    notifyIcon1.ShowBalloonTip(10000);
                    break;

                case PowerLineStatus.Offline:
                    notifyIcon1.BalloonTipTitle = "電源状態";
                    notifyIcon1.BalloonTipText = "バッテリーです";
                    notifyIcon1.ShowBalloonTip(10000);
                    break;

                case PowerLineStatus.Unknown:
                    break;
            }
        }
    }
}
6月 13

メールスロット Mailslot(受信)

詳細は省略します。
メールスロット経由でデータを受信するサンプルです。

タイマーを使って
一定周期でメールスロットに溜まったデータを取得しています。
応用すればデバッグトレースなどに役立つと思います。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;
using System.IO;

namespace MailSlotSample
{
    public partial class FormMain : Form
    {
        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            static extern SafeFileHandle CreateMailslot(
            string lpName,
            uint nMaxMessageSize,
            uint lReadTimeout,
            IntPtr lpSecurityAttributes);

        [DllImport("kernel32.dll")]
            static extern bool GetMailslotInfo(
            SafeFileHandle hMailslot,
            ref uint lpMaxMessageSize,
            ref uint lpNextSize,
            ref uint lpMessageCount,
            ref uint lpReadTimeout);

        [DllImport("kernel32.dll", SetLastError = true)]
            static extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess,
            uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition,
            uint dwFlagsAndAttributes, IntPtr hTemplateFile);

        public const uint FILE_ATTRIBUTE_NORMAL = 0x80;
        public const short INVALID_HANDLE_VALUE = -1;
        public const uint GENERIC_READ = 0x80000000;
        public const uint GENERIC_WRITE = 0x40000000;
        public const uint CREATE_NEW = 1;
        public const uint CREATE_ALWAYS = 2;
        public const uint OPEN_EXISTING = 3;
        public const uint FILE_SHARE_READ = 0x00000001;

        private enum MailSlotStatus : uint
        {
            MAILSLOT_NO_MESSAGE = 0xffffffff,
        }

        const string MAILSLOT_NAME = "\\\\.\\mailslot\\hogehoge";

        //
        // メールスロットハンドル
        //
        SafeFileHandle _handleMailslot = null;

        //
        // メールスロットから情報取得するためのStream
        //
        FileStream _fs = null;

        public FormMain()
        {
            InitializeComponent();

            // メールスロットハンドル生成
            _handleMailslot = CreateMailslot(MAILSLOT_NAME, 0, 0, (IntPtr)0);

            // メールスロットから情報取得するためのStream
            _fs = new FileStream(_handleMailslot, FileAccess.Read);

            // タイマー始動
            timer.Enabled = true;
        }

        ~FormMain()
        {
            _fs.Close();
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            //
            // タイマーを使って一定間隔でメールスロットからRead
            //
            string text = ReadMailSlot(MAILSLOT_NAME, 4096);

            // ここで取得したtextを表示。TextBoxやListBoxに追加するとかお好きにどうぞ
            MessageBox.Show(text);
        }

        private string ReadMailSlot(string slot, uint bufSize)
        {
            string ret = string.Empty;
            try
            {
                if (_handleMailslot.IsInvalid)
                    return ret;

                uint maxMessageSize = 1;
                uint nextSize = 0;
                uint messageCount = 0;
                uint readTimeout = 0;

                GetMailslotInfo(_handleMailslot, ref maxMessageSize, ref nextSize, ref messageCount, ref readTimeout);

                if (messageCount > 0 && nextSize != (uint)MailSlotStatus.MAILSLOT_NO_MESSAGE)
                {
                    byte[] buf = new byte[bufSize];
                    int len = _fs.Read(buf, 0, buf.Length);

                    // 適時、文字コードは送信元に合わせてください
                    ret = Encoding.Unicode.GetString(buf, 0, len);
                }
            }
            catch (Exception ex)
            {
                // 何かエラーだって!
                MessageBox.Show(ex.Message);
            }

            return ret;
        }
    }
}
6月 13

pingを送信する(非同期)

pingを非同期で送信するサンプルです。

Formにホスト名入力テキストボックスと
ping送信、停止ボタンと
結果を表示するテキストボックスを
それぞれ配置しています。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace PingTest
{
    public partial class Form1 : Form
    {
        System.Net.NetworkInformation.Ping _ping = new System.Net.NetworkInformation.Ping();

        bool _bSending = false;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            _ping.PingCompleted += new System.Net.NetworkInformation.PingCompletedEventHandler(_ping_PingCompleted);
        }

        private void buttonStartStop_Click(object sender, EventArgs e)
        {
            buttonStartStop.Enabled = false;

            if(!_bSending)
            {
                _bSending = true;

                // Ping設定: TTL=64,データは断片化されないよう指定
                System.Net.NetworkInformation.PingOptions pingOption =
                    new System.Net.NetworkInformation.PingOptions(64, true);

                // Pingで送信するデータ
                byte[] buffer = System.Text.Encoding.ASCII.GetBytes("ping test data");
            
                // Ping送信:タイムアウト10秒
                _ping.SendAsync(textBoxHostName.Text, 10000, buffer, pingOption, null);
            }
            else
            {
                _bSending = false;

                _ping.SendAsyncCancel();
            }
        }

        void _ping_PingCompleted(object sender, System.Net.NetworkInformation.PingCompletedEventArgs e)
        {
            if(e.Cancelled)
            {
                MessageBox.Show("キャンセルされました。");
                return;
            }

            string msg;

            if(e.Error != null)
            {
                msg = e.Error.Message;
            }
            else
            {
                // 返答あり?
                if(e.Reply.Status == System.Net.NetworkInformation.IPStatus.Success)
                {
                    msg = string.Format(
                        "{0} からの応答: バイト数 ={1} 時間 ={2}ms TTL={3}",
                        e.Reply.Address,
                        e.Reply.Buffer.Length,
                        e.Reply.RoundtripTime,
                        e.Reply.Options.Ttl);
                }
                else
                {
                    msg = string.Format("Ping失敗 {0}", e.Reply.Status);
                }
            }

            textBoxLog.AppendText(msg + "\r\n");

            _bSending = false;

            buttonStartStop.Enabled = true;
        }
    }
}
6月 13

pingを送信する(同期)

DOSプロンプトからpingするように
プログラムからpingする方法です。
簡単に同期呼び出しでよければ次のようにします。

    // Pingクラス生成
    using(System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping())
    {
        // Ping送信
        System.Net.NetworkInformation.PingReply reply = ping.Send("www.yahoo.co.jp");

        // 返答あり?
        if(reply.Status == System.Net.NetworkInformation.IPStatus.Success)
        {
            Console.WriteLine("{0} からの応答: バイト数 ={1} 時間 ={2}ms TTL={3}",
                reply.Address,
                reply.Buffer.Length,
                reply.RoundtripTime,
                reply.Options.Ttl);
        }
        else
        {
            Console.WriteLine("Ping失敗 {0}", reply.Status);
        }
    }