12 April 2008

(Windows Mobile) C#でメール送信

(Windows Mobile) .NET Compact Framework 1.0 以上、.NET Framework 1.1 以上で利用可能なSMTPサーバを用いたメール送信方法。


private void button_sendmail_tcpclnt_Click(object sender, System.EventArgs e)
{
TcpClient cl = new TcpClient();
NetworkStream sr;
string sMsg, sTmp;
string sDsp = "";
string sAuth = ""; // SMTP認証用文字列

try
{
// メールサーバのサブミッションポート587に接続
cl.Connect("mail.myserver.com", 587);

sr = cl.GetStream();

sMsg = ReadData(sr);
sDsp += sMsg;

// SMTP認証
if(checkBox_auth.Checked)
{
// ユーザ名とパスワードの認証文字列 "user\0user\0password" 形式
sAuth = "user" + "\0" + "user" + "\0" + "mypassword"textBox_password.Text;
// BASE64へ変換
sAuth = ConvertToBase64(sAuth);

// SMTP認証時のコネクション開始
SendData(sr, "EHLO localhost\r\n");
}
else
{
// SMTP認証なしの場合のコネクション開始
SendData(sr, "HELO localhost\r\n");
}

sMsg = ReadData(sr);
sDsp += sMsg;

if(!CheckSmtpStatus(sMsg)) throw(new System.IO.IOException());

// SMTP認証
if(checkBox_auth.Checked)
{
sMsg = "AUTH PLAIN " + sAuth + "\r\n";
SendData(sr, sMsg);

sMsg = ReadData(sr);
sDsp += sMsg;

if(!CheckSmtpStatus(sMsg)) throw(new System.IO.IOException());
}

// 送信元アドレス
sMsg = "MAIL FROM:" + textBox_from.Text + "\r\n";
SendData(sr, sMsg);

sMsg = ReadData(sr);
sDsp += sMsg;

if(!CheckSmtpStatus(sMsg)) throw(new System.IO.IOException());

// 送信先アドレス
sMsg = "RCPT TO:" + textBox_to.Text + "\r\n";
SendData(sr, sMsg);

sMsg = ReadData(sr);
sDsp += sMsg;

if(!CheckSmtpStatus(sMsg)) throw(new System.IO.IOException());

// 本文転送コマンド
SendData(sr, "DATA\r\n");

sMsg = ReadData(sr);
sDsp += sMsg;

if(!CheckSmtpStatus(sMsg)) throw(new System.IO.IOException());

// 本文転送(メールヘッダ)
sMsg = "From:" + textBox_from.Text + "\r\n";
SendData(sr, sMsg);
sMsg = "To:" + textBox_to.Text + "\r\n";
SendData(sr, sMsg);
sMsg = "Subject:=?iso-2022-jp?B?" + ConvertToBase64(textBox_subject.Text) + "?=\r\n"; // BASE64変換した日本語タイトルサポート
SendData(sr, sMsg);
sMsg = "Content-Type: text/plain; charset=\"ISO-2022-JP\"\r\n";
SendData(sr, sMsg);

SendData(sr, "\r\n"); // 本文開始前に改行

// 本文転送
sTmp = textBox_body.Text;
string [] sSplitLine = sTmp.Split(new Char[] {'\n'});

foreach(string s in sSplitLine)
{
if(s == ".\r" || s == ".") sMsg = " .\r\n"; // データ終了コマンドの回避?
else sMsg = s + "\n";
SendData(sr, sMsg);
}

// データ最後の "\r\n.\r\n" を送信する
SendData(sr, "\r\n.\r\n");

sMsg = ReadData(sr);
sDsp += sMsg;

if(!CheckSmtpStatus(sMsg)) throw(new System.IO.IOException());

// 終了コマンド
SendData(sr, "QUIT\r\n");

sMsg = ReadData(sr);
sDsp += sMsg;

}
catch
{
sDsp += "\r\nSerial Connection Error\r\n";
}

try
{
cl.Close();
}
catch
{
}

MessageBox.Show(sDsp);
}

private void SendData(NetworkStream sr, string sMsg)
{
//byte型配列に変換
// byte[] data = Encoding.ASCII.GetBytes(sMsg);
byte[] data = System.Text.Encoding.GetEncoding("shift_jis").GetBytes(sMsg);

sr.Write(data, 0, data.Length);

}

private static string ReadData(NetworkStream sr)
{
int nBufSize = 1024;
byte[] data = new byte[nBufSize+1];
string sMsg = "";
int nLength;

System.IO.MemoryStream ms = new System.IO.MemoryStream();

nLength = sr.Read(data, 0, nBufSize);
ms.Write(data, 0, nLength);
sMsg = Encoding.ASCII.GetString(ms.ToArray(), 0, nLength);

ms.Close();


return sMsg;
}

private bool CheckSmtpStatus(string sResponse)
{
if(sResponse.StartsWith("2")) return true; // 2XX のとき、コマンド成功
if(sResponse.StartsWith("3")) return true; // 3XX のとき、要求待ち(本文送信時)
return false; // コマンド失敗
}

private string ConvertToBase64(string sBuf)
{
if(sBuf.Length <= 0) return "";

byte [] sEncordWorking = System.Text.Encoding.GetEncoding("shift_jis").GetBytes(sBuf);
return System.Convert.ToBase64String(sEncordWorking, 0, sBuf.Length);

}


.NET Framework 1.1 では、メール送信用のクラスが用意されている。


private void button_sendmail_Click(object sender, System.EventArgs e)
{
// System.Web.Mail の MailMessage オブジェクトを作成
MailMessage msg = new MailMessage();

// メール送信文を作成
msg.To = textBox_to.Text; // 送信先アドレス xxx@yyy.zzz.com
msg.From = textBox_from.Text; // 送信元アドレス xxx@yyy.zzz.com
msg.Subject = textBox_subject.Text; // メール題名
msg.Body = textBox_body.Text; // 本文

// SMTPサーバ名 yyy.zzz.com
System.Web.Mail.SmtpMail.SmtpServer = textBox_server.Text;
// SMTPサーバのポート番号の指定 (指定しない場合は、25)
msg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpserverport", textBox_port.Text);

// SMTP認証
if(checkBox_auth.Checked)
{
msg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate", 1);
msg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendusername", textBox_user.Text);
msg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendpassword", textBox_password.Text);
}

// メール送信
try
{
System.Web.Mail.SmtpMail.Send(msg);
}
catch(System.Web.HttpException ehttp)
{
MessageBox.Show(ehttp.ToString());
}
}

.NET Framework 2.0以上では、System.Net.Mail クラスを用いる。