皆さん、こんにちは!
上越市を拠点にし、「FA設備・装置開発」と「画像処理」に強い会社、NSIです!
私達は豊富な経験と専門知識で、各種業界の自動化・システム化のお手伝いをしています。
2月も終わりに近づき、気付けばもうすぐ春ですね。
それにしてももう1年の6分の1が終わっているとは…。
さて、プログラムネタではPythonを多く取り上げていましたが、久しぶりにC#の記事となります。
今回は C#を使ってメールの添付ファイルを一括保存する方法 をまとめました。
いつも通り、導入 → 実装 → 実行まで、詳しく解説していきます!
ちょっと長くなってしまいますが、お付き合い頂けると嬉しいです。
…ここだけの話、NSIではPythonよりもC#を使ったソフト開発の方が多いよ。
そもそも、C#でメールを受信できるメリットとは?
メールの添付ファイルを保存するには、まずメールを受信する必要があります。
メールを受信するにはメーラーと呼ばれる専用のソフトを使用するのが一般的です。
有名なものだと、GmailやOutlook、Thunderbird 等がそれに当たります。
ここで、メールを受信する際の仕組みを図で見てみましょう。
メーラーには「ブラウザ上で使えるもの」と「PCにインストールして使えるもの」の2種類あります。
ただし、どちらもメールサーバーからメールを取得することには変わりありません。
ブラウザ上で使えるメーラー
ブラウザを介してアクセスするので、デバイスを問わずにメールの閲覧が可能です。
ただし、ネットが使えない環境だと閲覧はできません。
PCにインストールして使えるメーラー
PCにインストールするため、ネットが使えない環境でも過去のメールの閲覧が可能※です。
ただし、端末毎にソフトをインストールする必要があります。
※メールを受信する際にネットを介すため、最新のメールは閲覧することができません。
多くのメーラーが存在する中、わざわざ自分でメーラーを作るメリットとは何か?
ズバリ、「既存のメーラーにはない機能が実装できる」というのが挙げられます。
活用事例
ここで、弊社での活用事例をご紹介。
弊社では、日々の日報をメールで送信しており、その際に各作業の工数を記録したExcelも添付して送信するのが決まりとなっています。このExcelは月末に集計するのですが、従業員一人一人のメールを開いて添付されているExcelを保存するという作業は結構手間がかかります。
…ということで、添付ファイルを一括保存するソフトを作成しました。
おかげで手作業と比べ、格段に集計スピードがアップしました。
C#でメール受信してみる
今回はメールを受信し、添付ファイルを保存する処理まで実装していきます。
記事内で作成したソフトを元に、「指定した名前の添付ファイルだけ保存する機能」や「ファイルの添付忘れをチェックする機能」なんかもあるとより使いやすくなりそうですね。
1. MailKitのインストール
今回は「MailKit」というライブラリを使用します。
まず、Windowsアプリケーション(.NET Framework)のプロジェクトを作成します。
作成後、メニューバーの ツール > NuGetパッケージマネージャー > ソリューションのNuGetパッケージの管理 を選択します。
NuGetの画面が表示されたら、参照が選択された状態で、「MailKit」と検索します。
先頭に出てきた項目を選択し、チェックを入れてインストールします。
正常にインストールできれば、準備は完了です。
インストール時に以下のエラーが出てしまった場合、.NET Frameworkのバージョンが非対応の可能性があります。
このエラーは、対象のフレームワークを変更することで解決することが可能です。
エラーを見ると、.NET Frameworkの場合、4.6.2, 4.7, 4.8のいずれかに対応しているみたいだね。
ソリューションエクスプローラー > プロパティ > アプリケーション を選択します。
「対象のフレームワーク」を変更し、再度インストールをお試しください。
2. 画面の作成
続いて画面を作成していきます。画面構成は以下の通りです。
GroupBox、Labelについては特に参照しないため、省略します。(名前はデフォルトのままで問題ありません。)
No. | コントロール名 | 名前 |
① | TextBox | textBox_保存先 |
② | Button | button_保存先 |
③ | TextBox | textBox_サーバー名 |
④ | NumericUpDown | numericUpDown_ポート番号 |
⑤ | TextBox | textBox_ユーザー名 |
⑥ | TextBox | textBox_パスワード |
⑦ | Button | button_接続確認 |
⑧ | Button | button_保存 |
フォントは自分の好きなものでOK!画像ではメイリオを使っているよ。
3. 処理の作成(接続確認)
メールサーバーと接続できるか確認する処理をForm1.csに作成します。
まずは、以下の関数を作成します。
/// <summary>
/// メールサーバーへ接続する
/// </summary>
/// <returns></returns>
private bool ConnectServer(out Pop3Client client)
{
// UIの値を取得
string serverName = textBox_サーバー名.Text;
int portNum = (int)numericUpDown_ポート番号.Value;
string userName = textBox_ユーザー名.Text;
string password = textBox_パスワード.Text;
// 初期化
client = new Pop3Client();
try
{
// タイムアウトを設定(3秒)
client.Timeout = 3000;
// サーバー名からIPアドレスを取得
IPAddress[] ipAdrs = Dns.GetHostAddresses(serverName);
// POP3サーバーへ接続
client.Connect(ipAdrs[0].ToString(), portNum, MailKit.Security.SecureSocketOptions.None);
client.Authenticate(userName, password);
}
catch (Exception ex)
{
return false;
}
return true;
}
この関数では、メールサーバー設定の内容を元にPOP3サーバーへアクセスを行い、接続結果を返します。
注意点として、client.Connectのオプションである「MailKit.Security.SecureSocketOptions.None」の部分は使用しているメールサーバーによって異なります。
本記事の執筆時に使用しているメールサーバーはSSL/TLSに対応していないため「None」を設定していますが、使用しているメールサーバーに応じて変更してください。(下記参考)
オプション | 解説 |
None | SSL/TLSを使用せずに接続を行う。 セキュリティがない環境や、サーバーがSSL/TLSに対応していない場合に使用される。 |
Auto | MailKitが自動的に最適なオプションを選択して接続を行う。 |
SslOnConnect | 接続開始時からSSL/TLSを使用して接続を行う。 |
StartTls | 接続時は暗号化されず、その後STARTTLSコマンドを使用してSSL/TLS接続を行う。 |
StartTlsWhenAvailable | サーバーがSTARTTLSをサポートしている場合のみSSL/TLSを使用して接続を行う。 サポートしていない場合はセキュリティなしで接続が継続される。 |
作成した関数を「接続確認」ボタンのクリックイベントで呼び出します。
クリックイベントは、Form1.csのデザイナー上で対象のボタンをクリックすることで、自動生成されます。
/// <summary>
/// メールサーバーとの接続確認
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button_ConnectCheck_Click(object sender, EventArgs e)
{
// メールサーバーへ接続後、メッセージを返す
if (ConnectServer(out Pop3Client client))
{
MessageBox.Show("接続に成功しました。", "接続確認", MessageBoxButtons.OK, MessageBoxIcon.Information);
client.Disconnect(true);
}
else
{
MessageBox.Show("接続に失敗しました。", "接続確認", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
このイベントでは、「ConnectServer」の戻り値に応じて異なるメッセージを表示します。
trueなら「接続に成功しました。」と表示後、サーバーとの接続を切断します。
falseなら「接続に失敗しました。」と表示します。(サーバーと接続できていないため、切断処理は不要です。)
「接続確認」処理はこれで完成です。早速実行してみましょう。
UIにメールサーバーの設定を入力し、接続確認をクリックします。
「接続に成功しました。」とメッセージが表示されたらOKです!
接続できなかった場合は、設定が正しいか確認し、問題なければ接続時のオプションを変更してみてください。
4. 処理の作成(保存先の指定)
続いて、添付ファイル保存先を指定するための処理をForm1.csに作成します。
「…」ボタンのクリックイベントに以下の処理を記述します。
/// <summary>
/// 保存先を指定する
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_保存先_Click(object sender, EventArgs e)
{
// フォルダ選択ダイアログ
using (FolderBrowserDialog fbd = new FolderBrowserDialog())
{
// デフォルトの保存先を指定
fbd.SelectedPath = textBox_保存先.Text;
// ダイアログ表示
if (fbd.ShowDialog() == DialogResult.OK)
{
// 指定した保存先をテキストボックスにセット
textBox_保存先.Text = fbd.SelectedPath;
}
}
}
このイベントでは、フォルダ選択ダイアログを表示し、選択したフォルダを保存先としてセットしています。
「保存先の指定」処理はこれだけです。「…」ボタンをクリックして実行してみましょう。
フォルダ選択ダイアログが表示され、選択したフォルダのパスがテキストボックスにセットされればOKです。
5. 処理の作成(添付ファイルの保存)
最後に、添付ファイルを保存する処理をForm1.csに作成します。
「保存」ボタンのクリックイベントに以下の処理を記述します。
/// <summary>
/// 添付ファイルを保存する
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button_Save_Click(object sender, EventArgs e)
{
int saveCount = 0;
string saveDir = textBox_保存先.Text;
// 保存先が設定されているか確認
if(saveDir == "")
{
MessageBox.Show("保存先を設定してください。", "保存", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
// メールサーバーへ接続
if(ConnectServer(out Pop3Client client))
{
// 保存先がなければ作成
if(!Directory.Exists(saveDir))
Directory.CreateDirectory(saveDir);
// メールサーバー上のメール数を取得
int mailCount = client.GetMessageCount();
for (int i = 0; i < mailCount; i++)
{
// メールを取得
MimeMessage msg = client.GetMessage(i);
// 取得したメールの添付ファイルを取得
foreach (MimeEntity attachment in msg.Attachments)
{
// 添付ファイル名を取得し、パスを生成
string fileName = attachment.ContentDisposition.FileName;
string filePath = Path.Combine(saveDir, fileName);
// ファイルを生成し、デコードして保存
using (FileStream stream = File.Create(filePath))
{
MimePart part = (MimePart)attachment;
part.Content.DecodeTo(stream);
saveCount++;
}
}
}
// サーバーとの接続を切断
client.Disconnect(true);
// 結果メッセージ表示
MessageBox.Show($"{saveCount} 件 保存しました。", "保存", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show("保存に失敗しました。", "保存", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
このイベントでは、メールサーバーへ接続し、サーバー上の各メールの添付ファイルを保存先に保存しています。
注意点として、使用しているメーラーで、受信したメールをサーバーからすぐ削除する設定を行っている場合、取得できるメールが存在しないため、実行結果は0件となってしまいます。
添付ファイルが存在するのに保存されない場合は、メーラーの設定をご確認ください。
さて、問題がなければ早速実行してみましょう。
添付ファイルが保存できると、保存した件数がメッセージ表示されます。
※添付ファイル名が重複している場合は上書きされ、メッセージの件数と実際の保存数が異なる場合があるため、注意してください。
上書きしたくない場合、既に同じ名前のファイルがあるか確認した上でリネームする必要がありそうだね。
最後に
今回は C#でメールの添付ファイルを一括保存する方法 をご紹介しました。
複数の添付ファイルを一括保存したい!という方はぜひご活用ください。
他にもまだまだ、C#を使ってできることはたくさんあるので、引き続きご紹介していきたいと思います!
ここまで読んでいただき、ありがとうございました。
ご質問・ご要望・ご相談などは、下記お問い合わせフォームからお気軽にご連絡ください。
http://www.net-nsi.co.jp/toiawase.html
この記事がいいねと思ったらGoodボタンを押してね~