mapiを利用して、メール送信のプログラムを作成しています。
http://hp.vector.co.jp/authors/VA036850/airpark/tips/#mapi_sendからの抜粋:
#include mapi.h
typedef ULONG (WINAPI *MAPI_SEND_MAIL_PROC)( LHANDLE lhSession,\
ULONG ulUIParam, lpMapiMessage lpMessage, FLAGS flFlags, ULONG ulReserved );
// 送信元情報
MapiRecipDesc Sender;
Sender.ulReserved = 0;
Sender.ulRecipClass = MAPI_ORIG;
Sender.lpszName = 送信元メールアドレス;
Sender.lpszAddress = NULL;
Sender.ulEIDSize = 0;
Sender.lpEntryID = NULL;
// 受信先情報(複数の場合は配列にする)
MapiRecipDesc Receiver;
Receiver.ulReserved = 0;
Receiver.ulRecipClass = MAPI_TO; // MAPI_CC, MAPI_BCCもあり
Receiver.lpszName = 受信先メールアドレス;
Receiver.lpszAddress = NULL;
Receiver.ulEIDSize = 0;
Receiver.lpEntryID = NULL;
// 添付ファイル情報(複数の場合は配列にする)
MapiFileDesc AttachFile;
AttachFile.ulReserved = 0;
AttachFile.flFlags = 0;
AttachFile.nPosition = 0xffffffff;
AttachFile.lpszPathName = 添付ファイル名;
AttachFile.lpszFileName = NULL;
AttachFile.lpFileType = NULL;
// 送信設定
MapiMessage Message;
Message.ulReserved = 0;
Message.lpszSubject = 件名;
Message.lpszNoteText = 本文;
Message.lpszMessageType = NULL;
Message.lpszDateReceived = NULL;
Message.lpszConversationID = NULL;
Message.flFlags = MAPI_RECEIPT_REQUESTED;
Message.lpOriginator = &Sender; // 送信元情報へのポインタ
Message.nRecipCount = 1; // 受信先情報の数
Message.lpRecips = &Receiver; // 受信先情報へのポインタ
Message.nFileCount = 1; // 添付ファイル情報の数(なければ0)
Message.lpFiles = &AttachFile; // 添付ファイル情報へのポインタ(なければNULL)
// メールクライアントソフトでダイアログを表示するかのフラグ
FLAGS flag = 0;
if( ダイアログを表示する場合 ) flag = MAPI_DIALOG;
// MAPIルーチンを使用して送信
HINSTANCE hInst;
hInst = LoadLibrary( mapi32.dll );
if( hInst == NULL ){
AfxMessageBox( mapi32.dllがロードできませんでした。送信に失敗しました。 );
}
else {
MAPI_SEND_MAIL_PROC MAPISendMailProc =
(MAPI_SEND_MAIL_PROC)GetProcAddress( hInst, MAPISendMail );
if( MAPISendMailProc( 0, 0, &Message, flag, 0 ) != SUCCESS_SUCCESS ){
AfxMessageBox( 送信に失敗しました。 );
}
else AfxMessageBox( 送信完了しました。 );
FreeLibrary( hInst );
}
ただし、これを利用するには、
事前に既定のメールアカウントを設定しておく必要があるらしい。
設定されていない場合は、送信に失敗しましたといわれてしまいます。
メールアカウントを設定しておいて、
送信元情報にメールアドレスや表示名を指定しても、
既定のメールアカウントが送信元として、送信されます。
しかも、送信するしないかのダイアログが出てしまいます。
簡単に言えば、自動メールサービスを作成しようとしています。
処理中にエラーが発生してしまったら、システム管理者にメールを自動的送信する。
送信元は、エラーの発生元のユーザーのメールアドレス。
もちろん、ダイアログ画面が要りません。
こういう処理はmapiで可能ですか?
> こういう処理はmapiで可能ですか?
マニュアル/ドキュメントに'こういう処理'のできそうな
操作が明記されていなければ、できないんでしょうね。
僕ならSMTPに素で送りつけるな。
επιστημη さん
ご返答ありがとうございます。
> 僕ならSMTPに素で送りつけるな。
SMTPに素で送りつけるの意味をもっと詳しく説明していただけませんか?
SMTP(Simple Mail Transfer Protocol)とはその名の通り、
メールを送信するためのプロトコルです。
SMTPサーバに対して、'ドコ'から'ドコ'へ'ナニ'を送って
とお願いすれば、メールを投げてくれます。
mapiとやらも、つまるところこの SMTP でメールを送っているに過ぎません。
最もプリミティブなやり方なので面倒ではありますが、その分'何でも'できます。
そうですか、それでは、調べてみます。
ただ、1点だけ理解できませんが、
サンプルソースの中で
> // 送信元情報
> MapiRecipDesc Sender;
> Sender.ulReserved = 0;
> Sender.ulRecipClass = MAPI_ORIG;
> Sender.lpszName = 送信元メールアドレス;
> Sender.lpszAddress = NULL;
> Sender.ulEIDSize = 0;
> Sender.lpEntryID = NULL;
のように、送信元の情報を設定していました。
送信するときにも
> Message.lpOriginator = &Sender; // 送信元情報へのポインタ
と、送信元を指定しました。
結局、デフォルトのメールアカウントが送信元とされてしまいますので、
送信元の情報を設定する意味がないではないかと。
> 結局、デフォルトのメールアカウントが送信元とされてしまいますので、
> 送信元の情報を設定する意味がないではないかと。
そのふたつの送信元が異なるとき、どうなるか実験してみましたか?
> そのふたつの送信元が異なるとき、どうなるか実験してみましたか?
実験してみました。
異なるときは、OutLookExpressで設定した既定のメールアカウントが優先されます。
既定のメールアカウントが設定されていない場合は、送信に失敗してしまいます。
つまり、既定のメールアカウントを使用して、メールを送りつけている感じ。
…そうなんだ。 既定のメールアカウントはSMTPにつなぐため、
Sender.lpszName は メール・ヘッダに使われるのかと思ってた。
ちなみに下記の内容からすると
http://www.geocities.co.jp/SiliconValley-PaloAlto/4878/vol49.txt
MapiRecipDescの使い方が違うような気がしますね。
HELP内容を読んでも佐倉さんのコードは説明にあっていないような気がします。
HELPが英語で書いてあっても辞書を片手にでも読んでみた方が良いです。
Web上の情報が全て正しいとは限りませんし、
結局、集めた情報から試行錯誤してみるしかないわけですから
試行錯誤するための指針としてHELPの内容は大切だと思います。
あと、SMTPを実装する気なら
猫でもわかるプログラミングの228章から続けて3章分くらい読んでみては?
http://www.kumei.ne.jp/c_lang/index.html
Web情報は頼りになるけど、原則は一次情報であるマニュアル/ドキュメントですって。
# '英語が苦手'は言い訳にならん。 苦手なのは誰だって同じ。
> Sender.lpszName = 送信元メールアドレス;
> Sender.lpszAddress = NULL;
Sender.lpszAddress のほうが、送信元メールアドレスですね。
Sender.lpszName は、あくまでも、表示名に過ぎません。
確かに、ここが違っています。
自分がテストしているコードでは、これを直しました。
言い忘れて、申し訳ございません。
直しても、結果が同じです。
PATIOさんが提示していただいたコードもやってみましたが、同じ結果です。
送信元の情報が全て無視されてしまうような気がします。
SMTPを実装することにしようか!
ありがとうございました。
メール処理では広く使われている(らしい?)Basp21 のライブラリを使ってみるとか。
既に優れたライブラリがあるのなら、それを使うべきです。
いあ、俺ぁ Basp21 使ったことないから優れてるかどうか知らないんですが。
Basp21 の一部である BSMTP.DLL とかが使えそうですな。
> いあ、俺ぁ Basp21 使ったことないから優れてるかどうか知らないんですが。
> Basp21 の一部である BSMTP.DLL とかが使えそうですな。
別の掲示板でちょこっと調べていました。
使い慣れないBSTR型が出てくるのでちょいと苦労しそうです。
(そちらは解決したようなので、調べるのは中断しましたが)