6月 14

DomainUpDownコントロールの使い方

DomainUpDownコントロールは
NumericUpDownコントロールと似ています。
こちらは文字列を扱えます。

ただ、その役割はComboBoxと似ていますし
プルダウン表示がないので一覧が見れず
使い所がよくわかりません。
本当の使い方?が実はあるのかもしれませんが

ここでは
選択肢の追加方法と
選択中の文字列の取得方法のサンプルを書いてみました。

domainupdown

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 Form1_Load(object sender, EventArgs e)
        {
            // ひとつずつ追加
            domainUpDown1.Items.Add("apple");
            domainUpDown1.Items.Add("orange");

            // まとめて追加:その1(配列)
            string[] data = {"melon", "banana"};
            domainUpDown1.Items.AddRange(data);

            // まとめて追加:その2(List<>)
            List list = new List();
            list.Add("itigo");
            list.Add("suika");
            domainUpDown1.Items.AddRange(list);

            // 先頭要素を選択
            domainUpDown1.SelectedIndex = 0;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show(domainUpDown1.Text);
        }
    }
}
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);
        }
    }
6月 13

ホスト名からIPアドレスを取得する

ホスト名からIPアドレスを取得するには
System.Net.DnsクラスのGetHostEntry関数を使います。

    // IPを調べたいホスト名
    string hostname = "www.yahoo.co.jp";

    // IPHostEntry取得
    System.Net.IPHostEntry hostEntry = System.Net.Dns.GetHostEntry(hostname);

    // 最初のアドレスを取得
    System.Net.IPAddress ip = hostEntry.AddressList[0];

    // xxx.xxx.xxx.xxx形式の文字列を取得
    string IPaddress = ip.ToString();
6月 13

IPアドレスを取得する

PCのIPアドレスを取得する方方です。
まずホスト名を取得し、それを元にエントリーを列挙しています。

IPアドレスは1つとは限らないので注意が必要です。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;   // これが必要

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

        private void button1_Click(object sender, EventArgs e)
        {
            // ホスト名を取得
            string hostname = Dns.GetHostName();

            // ホスト名からエントリー取得
            IPHostEntry ipentry = Dns.GetHostEntry(hostname);

            // IPアドレスは2つ以上のケースもあるのですべて列挙(有線+無線など)
            string msg = string.Empty;
            foreach (IPAddress ip in ipentry.AddressList)
            {
                msg += ip.ToString() + "\r\n";
            }

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

ホスト名を取得する

PCのホスト名を取得するには
System.Net.DnsクラスのGetHostName関数を使います。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;   // これが必要

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

        private void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show(Dns.GetHostName());
        }
    }
}