2005-09-13

λ [.NET] CDO for Windows2000 でメールを送信する

System.Web.Mail.SmtpMail によるメール送信がどうもうまくいかない。 ドキュメントによると裏ではCDO for Windows2000を呼んでいるだけらしく、 Postfix に接続する際デフォルトでTLSを使おうとして失敗するという状況はCDOの時と同じ症状。 だったら自分でCDO呼べばいいじゃん、とC#に以前のJavaScriptコードを変換した。

Intellisense のおかげで以前はADODB経由でアクセスしていた部分を iMsg.TextBodyPart.ContentTransferEncoding,iMsg.TextBodyPart.Charset と直に値を入れられるのを発見。ありがたい。 でもやっぱりCDO.Configurationの方はだめそげ。

VisualStudioでCOMへの参照設定をしたら、bin ディレクトリの下に Interop.ADODB.dll, Interop.CDO.dll ができていた。 COMと.NETをつなぐ方法を理解したおかげでだんだんトラブル起きにくくなってきて嬉しい。

/// <summary>
/// メールを送信する。SMTPサーバ名は "smtpserver" 固定
/// </summary>
/// <param name="mailto"></param>
/// <param name="mailfrom"></param>
/// <param name="mailsubj"></param>
/// <param name="mailbody"></param>
static bool sendmail(string mailto, string mailfrom, string mailsubj, string mailbody)
{
	try 
	{
		CDO.MessageClass iMsg = new CDO.MessageClass();
		CDO.ConfigurationClass iConf = new CDO.ConfigurationClass();
		string smtpserver = "smtpserver"; // ホスト名「smtpserver」をDNSまたは hosts ファイルに定義する

		iConf.Fields["http://schemas.microsoft.com/cdo/configuration/sendusing"].Value       = 2; // cdoSendUsingPort
		iConf.Fields["http://schemas.microsoft.com/cdo/configuration/smtpserver"].Value      = smtpserver;
		iConf.Fields["http://schemas.microsoft.com/cdo/configuration/smtpserverport"].Value  = 25;
		iConf.Fields["http://schemas.microsoft.com/cdo/configuration/smtpauthenticate"].Value= 0; // 認証なし
		iConf.Fields["http://schemas.microsoft.com/cdo/configuration/smtpusessl"].Value      = false; // SSL(TLS) は使わない
		iConf.Fields["http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout"].Value = 30; // タイムアウト30秒
		iConf.Fields.Update();

		iMsg.Configuration = iConf;
		iMsg.To       = mailto;
		iMsg.From     = mailfrom;
		iMsg.Subject  = mailsubj;
		iMsg.TextBody = mailbody;
		iMsg.TextBodyPart.ContentTransferEncoding = "7bit";
		iMsg.TextBodyPart.Charset = "ISO-2022-JP";

		iMsg.Send();
		// 実際にメール送信するのは、iMsg が消滅する直前。連続送信することができないため、強制的にGC.Collect()を行う。
		GC.Collect();
		return true;
	} 
	catch (Exception e) 
	{
		Console.Write(e.Message);
	}
	return false;
}

catch(Exception e) はイケテナイ気もするが、とりあえず。 元々COM が Unicode前提なので、日本語の変換をする必要はない。中で ISO-2022-JP に変換してくれる。

<URL:http://mimori.org/~h/tdiary/20051227.html>に追記あり。

λ 吉原御免状

そこそこ面白いけど、のめりこむほどではないかなー。笑いのない演劇はツラい。

[]