コードの作成
実装する機能の概要は次のとおりです。
- 送信者、宛先をコンボに入力します。cc、bccがある場合は、それぞれのボタンを押すとInputBoxが表示されるので、ここから入力します。cc、bccはいくつも入力できますが、実際に送信されるのは最後に入力されたアドレスのみです。
- 添付ファイルがある場合は、ボタンを押すと[ファイルを開く]ダイアログボックスが表示されるので、ここから添付ファイルを指定します。添付ファイルも1件のみ指定できます。
- 件名と本文をエディットコンポーネントに入力します。入力がないのに送信しようとすると、メッセージボックスで確認を求めます。
- メールの送信処理は、すべて[送信する]ボタンのClickイベントハンドラで行います。
- Timerコントロールを使って、StatusStripに現在の日時を表示します。
- メールの送受信を行うと、SmtpコンポーネントにはTraceイベントが発生します。このイベントハンドラの引数「SegmentEventArgs」には、メール送信の詳しいデータが格納されますので、これを使って送信記録を作成します。
cc、bccの入力と時刻表示、添付ファイル名の取得処理
[cc][bcc]ボタンが押されたときの処理を作成します。
cc、bccはモジュールレベルの変数に格納します。
- 「Dart.PowerTCP.Mail」名前空間をインポートして、3つのモジュールレベル変数を用意します。
- ボタン[cc]のClickイベントハンドラでは、InputBoxを表示し、アドレスを入力してもらいます。そして、そのアドレスをStatusStripコントロールの
ToolStripStatusLabel
オブジェクトの、DropDownItems
コレクションに追加します。 - ボタン[bcc]のイベントハンドラでも同様の処理を行います。
- TimerコントロールのTickイベントハンドラで、
Now
関数を使って現在の日時を取得します。Iterval
プロパティはデフォルトの100ミリ秒のままです。 - [添付ファイル]ボタンのClickイベントハンドラで、[ファイルを開く]ダイアログボックスを表示し、ユーザーに添付ファイルを選択してもらいます。
Imports Dart.PowerTCP.Mail Public Class Form1 Public tocc As String = "" 'ccのアドレスを格納 Public tobcc As String = "" 'bccのアドレスを格納 Public attachfname As String = "" '添付ファイル名を格納
Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click tocc = InputBox("ccのアドレスを入力してください") If tocc <> "" Then Me.ToolStripStatusLabel1.DropDownItems.Add(tocc) End If End Sub
Private Sub Button2_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button2.Click tobcc = InputBox("bccのアドレスを入力してください") If tobcc <> "" Then Me.ToolStripStatusLabel2.DropDownItems.Add(tocc) End If End Sub
Enabled
プロパティをTrueにするのを忘れないでください。Private Sub Timer1_Tick(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Timer1.Tick Me.ToolStripStatusLabel4.Text = Now() End Sub
attachfname
にフルパスで格納し、その内容をLabelで表示します。Private Sub Button4_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button4.Click Dim ret As Integer ret = Me.OpenFileDialog1.ShowDialog If ret = Windows.Forms.DialogResult.OK Then attachfname = Me.OpenFileDialog1.FileName Me.Label1.Text = attachfname End If End Sub
メール送信処理
メール送信の処理は、すべて[送信する]ボタンのClickイベントハンドラで処理します。
- 最初に、宛先が入力されているかどうかをチェックします。入力されていなければ、送信処理を中止します。
- 次に、件名と本文が入力されているかどうかをチェックします。入力されていなければ、そのまま送信するのかどうかをユーザーに確認します。
- 送信内容を作成します。これは、
MessageStream
クラスのインスタンスを作成して、送信するようにします。 - 宛先は、同じメールを同時に複数のアドレスに送信する場合があるので、
MessageStream
オブジェクトのTo
プロパティでMailAddress
コレクションにアクセスし、Add
メソッドでコレクションに追加する、という形をとります。Add
メソッドの引数はアドレスを文字列で渡すのではなく、MailAddress
オブジェクトに変換して渡します。MailAddress
オブジェクトは、クラスのコンストラクタの引数にアドレスを文字列で渡します。 - 件名と本文は、それぞれ
Subject
プロパティとText
プロパティに文字列のまま設定します。 - 添付ファイルは、設定されていれば
MimeAttachmentStream
オブジェクトを作成し、これをAttachments
コレクションに加える、という形をとります。これも複数のファイルを添付できるようにAttachment
オブジェクトのコレクションを使用します。 - ccとbccのアドレスが設定されている場合は、これも
MessageStream
オブジェクトに組み込みます。 - メールの送信は、
Smtp
クラスのメンバを操作します。まず、メールサーバのアドレスをServer
プロパティに文字列で設定します。
If MeCombo2.Text = "" Then MessageBox.Show("宛先が入力されていません") Exit Sub End If
If Edit1.Text = "" Then Dim ret As Integer = MessageBox.Show( _ "件名がありません。送信しますか?", "確認", _ MessageBoxButtons.YesNo, MessageBoxIcon.Question) If ret = Windows.Forms.DialogResult.No Then Exit Sub End If End If If Me.Edit2.Text = "" Then Dim ret As Integer = MessageBox.Show( _ "本文がありません。送信しますか?", "確認", _ MessageBoxButtons.YesNo, MessageBoxIcon.Question) If ret = Windows.Forms.DialogResult.No Then Exit Sub End If End If
Send
メソッドで行うのですが、この引数に送信者や受信者のアドレス、件名、本文を指定する際に日本語(2バイト文字)を使うと、受信するメーラーによっては文字化けを起こしてしまいます。MessageStream
オブジェクトとしてSend
メソッドで送信すると、文字化けを起こしません。MessageStream
オブジェクトは、送信メールの各データを一括で格納するオブジェクトです。Dim msg As New MessageStream()
With msg .To.Add(New MailAddress(Me.Combo2.Text))
From
プロパティに設定します。これも、アドレスを文字列からMailAddress
オブジェクトに変換して設定します。.From = New MailAddress(Me.Combo1.Text)
.Subject = Edit1.Text .Text = Edit2.Text
MimeAttachmentStream
クラスのコンストラクタからインスタンス作成します。コンストラクタの引数は、添付ファイル名です。If attachfname <> "" Then Dim attach As MimeAttachmentStream = Nothing attach = New MimeAttachmentStream(attachfname)
MimeAttachmentStream
オブジェクトを、Add
メソッドを使ってAttachments
コレクションに追加します。.Attachments.Add(attach) End If
CC
プロパティを使ってMailAddresses
コレクションにアクセスし、このコレクションにMailAddress
オブジェクトとして追加します。MailAddress
オブジェクトは、クラスのコンストラクタを使って作成します。引数はccのアドレス文字列です。If tocc <> "" Then .CC.Add(New MailAddress(tocc)) End If
MailAddress
コレクションに組み込みます。If tobcc <> "" Then .BCC.Add(New MailAddress(tobcc)) End If End With
MessageStream
オブジェクトとして作成されました。With Me.Smtp1 .Server = "mail.xxxxx.ne.jp"
Send
メソッドを実行します。引数には、送信データをMessageStream
オブジェクトで指定します。.Send(msg) End With
Me.ToolStripStatusLabel3.Text = _ "メールを送信しました。送信ログを記録しました。" End Sub
メール送信ログの作成処理
メールを送信すると、SmtpコンポーネントにはTraceというイベントが発生します。そして、このイベントハンドラの引数「e As Dart.PowerTCP.Mail.SegmentEventArgs
」には、SMTPサーバとのやり取りなどの送信状況が記録されます。
そこで、その内容を取り出しファイルに書き出してログファイルを作成します。
Private Sub Smtp1_Trace(ByVal sender As Object, _ ByVal e As Dart.PowerTCP.Mail.SegmentEventArgs) Handles Smtp1.Trace
- まず、
Byte
型の配列を用意します。そして、GetBytes
メソッドを使用してイベントハンドラの引数e
からの情報を取得し格納します。SegmentEventArgs
オブジェクトのSegment
オブジェクトには、送受信されたデータやこのデータのバイト数などの情報が含まれています。 - つぎに、
FileStream
オブジェクトを作成してファイルを作ります。
Dim buffer As Byte() = _ System.Text.Encoding.Default.GetBytes(e.Segment.ToString())
Dim fs As New IO.FileStream("C:\メール送信ログ.log", _ IO.FileMode.Append)
FileStream
クラスのWrite
メソッドを使用して、Byte
型配列buffer
の中身をファイルに書き出します。fs.Write(buffer, 0, buffer.Length) fs.Close()
まとめ
メール送信処理を組み込んだアプリケーションを作ってみました。
アドレスの文字列をオブジェクトに変換して使う点で少し手間がかかりますが、コンポーネントのメソッド・プロパティを操作するだけで、CCやBCC、添付ファイルなどに対応したメールを手軽に送信できるようになるのはとても魅力です。