2007年12月20日木曜日

[.NET]MailSlot(その2)

昨日のMailSlotの受信について書きましたが、今日は送信側。コード例は以下のとおりです。
昨日のとあわせてクラス化してみました。
(実は半分くらいMOFさんからのぱくり品)

public class MailSlot
{
    #region Win32 API宣言

    [DllImport("kernel32.dll"CharSet = CharSet.Auto)]
    private static extern SafeFileHandle CreateFile(
        string lpFileName// ファイル名 
        DesiredAccess dwDesiredAccess// アクセスモード 
        ShareMode dwShareMode// 共有モード 
        int lpSecurityAttributes// セキュリティ記述子 
        CreationDisposition dwCreationDisposition// 作成方法 
        FlagsAndAttributes dwFlagsAndAttributes// ファイル属性 
        IntPtr hTemplateFile // テンプレートファイルのハンドル 
        );

    [DllImport("kernel32.dll"CharSet = CharSet.Auto)]
    static extern SafeFileHandle CreateMailslot(
        string lpName,
        uint nMaxMessageSize,
        uint lReadTimeout,
        IntPtr lpSecurityAttributes);

    #endregion

    #region 列挙体

    private enum DesiredAccess : uint
    {
        GENERIC_READ = 0x80000000,
        GENERIC_WRITE = 0x40000000,
        GENERIC_EXECUTE = 0x20000000
    }

    private enum ShareMode : uint
    {
        FILE_SHARE_READ = 0x00000001,
        FILE_SHARE_WRITE = 0x00000002,
        FILE_SHARE_DELETE = 0x00000004
    }

    private enum CreationDisposition : uint
    {
        CREATE_NEW = 1,
        CREATE_ALWAYS = 2,
        OPEN_EXISTING = 3,
        OPEN_ALWAYS = 4,
        TRUNCATE_EXISTING = 5
    }

    private enum FlagsAndAttributes : uint
    {
        FILE_ATTRIBUTE_ARCHIVE = 0x00000020,
        FILE_ATTRIBUTE_ENCRYPTED = 0x00004000,
        FILE_ATTRIBUTE_HIDDEN = 0x00000002,
        FILE_ATTRIBUTE_NORMAL = 0x00000080,
        FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000,
        FILE_ATTRIBUTE_OFFLINE = 0x00001000,
        FILE_ATTRIBUTE_READONLY = 0x00000001,
        FILE_ATTRIBUTE_SYSTEM = 0x00000004,
        FILE_ATTRIBUTE_TEMPORARY = 0x00000100
    }

    #endregion

    private string slot = string.Empty;
    public string Slot
    {
        get { return slot; }
        set { slot = value; }
    }

    /// <summary>
    /// コンストラクタ
    /// </summary>
    public MailSlot()
    {
    }

    /// <summary>
    /// メールスロット名付コンストラクタ
    /// </summary>
    /// <param name="strSlot">メールスロット</param>
    public MailSlot(string strSlot)
        : this()
    {
        Slot = strSlot;
    }

    /// <summary>
    /// メッセージの送信
    /// </summary>
    /// <param name="strMessage">送信する文字列</param>
    public void WriteMailSlot(string strMessage)
    {

        SafeFileHandle fileHandle = null;

        try
        {
            fileHandle = CreateFile(Slot,
                    DesiredAccess.GENERIC_READ | DesiredAccess.GENERIC_WRITE,
                    ShareMode.FILE_SHARE_READ | ShareMode.FILE_SHARE_WRITE,
                    0,
                    CreationDisposition.OPEN_EXISTING,
                    FlagsAndAttributes.FILE_ATTRIBUTE_NORMAL,
                    (IntPtr)0);


            using (FileStream fs = new FileStream(fileHandleFileAccess.Write))
            {
                byte[] msg = Encoding.UTF8.GetBytes(strMessage);
                fs.Write(msg0msg.Length);
            }
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine(ex.Message);
            System.Diagnostics.Debug.WriteLine(ex.StackTrace);
            throw ex;
        }
    }

    /// <summary>
    /// メールスロット受信待ち
    /// </summary>
    /// <param name="maxMessageSize">最大メッセージ数</param>
    /// <param name="readTimeout">タイムアウト</param>
    public string ReadMailSlot(uint maxMessageSizeuint readTimeout)
    {
        string result = string.Empty;
        SafeFileHandle mailslotHandle = null;
        try
        {
            mailslotHandle = CreateMailslot(SlotmaxMessageSizereadTimeout, (IntPtr)0);

            using (FileStream fs = new FileStream(mailslotHandleFileAccess.Read))
            {
                byte[] buf = new byte[maxMessageSize];
                int len = fs.Read(buf0buf.Length);
                result = Encoding.UTF8.GetString(buf0len);

                fs.Close();
           }
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine(ex.Message);
            System.Diagnostics.Debug.WriteLine(ex.StackTrace);
            throw ex;
        }
        return result;
    }
}

0 件のコメント: