|
Hi,
I am creating an application that has to send the mails automatically even in the absence of Microsoft outlook. My application is capable of sending the mails without any hitch only when outlook is running. If I close outlook and try sending the mail through my application, it will not send the mail until I run the outlook again. Is there a way to fix this problem? Is there any special API to be used?
My code snippet is as below:
HINSTANCE hlibMAPI = 0;
CString MapiDll = "MAPI32.dll";
hlibMAPI = LoadLibrary(MapiDll);
MapiRecipDesc *mapiCurrentSender;
MapiRecipDesc *lppNewRecips;
lppNewRecips->lpszAddress = "SMTP:harishkj@gmail.com";
lppNewRecips->lpszName = "Harish";
lppNewRecips->ulRecipClass = MAPI_TO;
lppNewRecips->ulEIDSize = NULL;
lppNewRecips->ulReserved = 0;
mapiCurrentSender->lpEntryID = NULL;
mapiCurrentSender->lpszAddress = "SMTP:harishkj@gmail.com";
mapiCurrentSender->lpszName = "KJ";
mapiCurrentSender->ulRecipClass = MAPI_ORIG;
mapiCurrentSender->ulEIDSize = NULL;
mapiCurrentSender->ulReserved = 0;
LPMAPISENDMAIL lpfnMAPISendMail;
LPMAPILOGON MAPILogon;
LHANDLE session = 0;
lpfnMAPISendMail = (LPMAPISENDMAIL) GetProcAddress (hlibMAPI, "MAPISendMail");
MAPILogon = (LPMAPILOGON) GetProcAddress (hlibMAPI, "MAPILogon");
MAPILogon(0,0,0,MAPI_NEW_SESSION,0,&session);
ULONG FAR PASCAL err = (*lpfnMAPISendMail)(session,(ULONG)AfxGetMainWnd()->m_hWnd, MAPI_LOGON_UI, 0L);
I tried with and without having a new session.
In either way it helped
Any help would be greatly appreciated.
Thanks,
KJ<pre></pre><pre></pre>
|
|
|
|
|
I've just looked at (and run) some MAPI wrapper code that I wrote several years ago. I found the following differences:
- I call
OleInitialize and MapiInitialize before opening a session - I opened my session with
MapiLogonEx , using these flags: MAPI_NO_MAIL|MAPI_EXTENDED|MAPI_USE_DEFAULT|MAPI_ALLOW_OTHERS . I don't use MAPISendMail either - I construct the message in my Exchange Server outbox and send it from there using IMessage::SubmitMessage . It works with or without Outlook running. - I added your
MAPILogon and MAPISendMail code and added message creation - that worked fine with or without Outlook running.
So, to summarise - I presume you're calling the relevant initialisation functions?
|
|
|
|
|
PS - what status code is returned from MAPILogon and MAPISendMail ? These could help diagnose your problem.
|
|
|
|
|
Hi Stuart Dootson,
Thanks for the immediate response.
I am sorry that I forgot to mention the return values.
Both "MAPILogon" and "MAPISendMail" calls returns SUCCESS_SUCCESS.
I am not getting where is the problem!
Could you please expalin in detail the code snippet which is working for you with my functions as well?
Thanks and regards,
KJ
|
|
|
|
|
Hi Stuart Dootson,
I even tried using the initialization calls you mentioned as below, but still the result is same.
LPMAPIINITIALIZE lpfnMAPIInitialize;
lpfnMAPIInitialize = (LPMAPIINITIALIZE) GetProcAddress (hlibMAPI, "MAPIInitialize");
MAPIINIT_0 mapiInitObj;
mapiInitObj.ulVersion = MAPI_INIT_VERSION;
mapiInitObj.ulFlags = MAPI_MULTITHREAD_NOTIFICATIONS;
if(OleInitialize(NULL) == S_OK)
MessageBox("SUCCESS", "OleInitialize");
if(lpfnMAPIInitialize(&mapiInitObj) == S_OK );
MessageBox("SUCCESS", "MAPIInitialize");
All the function returns success but the mail is not getting sent.
Please help me.
Thanks,
KJ
|
|
|
|
|
Here's the code I've used (note - I've #include d mapi.h before this) - obviously, my e-mail address isn't "my e-mail address". This works whether Outlook is running or not. If Outlook isn't running, I get a dialog that prompts me to choose the Outlook profile to use.
This would seem to be because the MAPILogon returns MAPI_E_LOGON_FAILURE whether or not Outlook is running when MAPI_NEW_SESSION is set. This is because a) when Outlook is running, it can't create a new session, and b) when Outlook isn't running, it doesn't know what profile to open (I have no default profile). The MAPISendMail will logon, as the flags allow it to display the logon UI.
Changing the MAPILogon flag to MAPI_LOGON_UI allows the logon UI to be displayed and so we can logon if Outlook isn't running. ANd if Outlook is running, we can logon because we've said we're willing to share an existing session.
HRESULT hr;
if (SUCCEEDED(hr = OleInitialize(NULL)) && SUCCEEDED(hr = MAPIInitialize(NULL)))
{
MapiRecipDesc mapiCurrentSender;
MapiRecipDesc lppNewRecips;
lppNewRecips.lpszAddress = "SMTP:<span style="font-style: italic;">my e-mail address</span>";
lppNewRecips.lpszName = "Stu";
lppNewRecips.ulRecipClass = MAPI_TO;
lppNewRecips.ulEIDSize = NULL;
lppNewRecips.ulReserved = 0;
mapiCurrentSender.lpEntryID = NULL;
mapiCurrentSender.lpszAddress = "SMTP:<span style="font-style: italic;">my e-mail address</span>";
mapiCurrentSender.lpszName = "Stu";
mapiCurrentSender.ulRecipClass = MAPI_ORIG;
mapiCurrentSender.ulEIDSize = NULL;
mapiCurrentSender.ulReserved = 0;
MapiMessage message =
{
0,
"Hello",
"Hello",
0,
"2009/01/12 09:01",
0,
0,
&mapiCurrentSender,
1,
&lppNewRecips,
0,
0
};
HINSTANCE hlibMAPI = 0;
hlibMAPI = LoadLibrary(_T("MAPI32.dll"));
LPMAPILOGON MAPILogon;
LHANDLE session = 0;
MAPILogon = (LPMAPILOGON) GetProcAddress (hlibMAPI, "MAPILogon");
ULONG errLogon = MAPILogon(0,0,0,MAPI_NEW_SESSION,0,&session);
LPMAPISENDMAIL lpfnMAPISendMail;
lpfnMAPISendMail = (LPMAPISENDMAIL) GetProcAddress (hlibMAPI, "MAPISendMail");
ULONG errSend = (*lpfnMAPISendMail)(session, 0, &message, MAPI_LOGON_UI, 0L);
}
|
|
|
|
|
Hi Stuart,
Thanks for the suggestions.
I tried using the exact way what you have done, but still the same problem occurs. After running this code, if I open my outlook, all the mails will be held in the outbox and will get sent only when I do Send/Receive in outlook window.
Could you please suggest any more ideas on this?
Can you explain how is your original code that doesn't make use of MAPISendMail function, but you are constructing the message in the Exchange Server outbox and send it from there using IMessage::SubmitMessage?
Thanks and regards,
KJ
|
|
|
|
|
The rough procedure is this:
- Open a MAPI session with
MAPILogonEx and get an IMAPISession interface pointer - Open your message store with
IMAPISession::GetMsgStoresTable and then IMAPISession::OpenMsgStore . This gets you an IMsgStore interface pointer. - Open your address book with
IMAPISession::OpenAddressBook . This gets you an IAddrBook interface pointer. - Open your outbox with
IMsgStore::OpenEntry to get an IMAPIFolder pointer on your Outbox. - Create the new message with
IMAPIFolder::CreateMessage . This returns an IMessage interface pointer. - Set the message attributes:
IMessage::ModifyRecipients to add recipients- The message body is either RTF (complex) or plain text (easy). For plain text, set the
PR_BODY_W property of the message - Set the 'Sent Items' folder for the message by setting the message's
PR_SENTMAIL_ENTRYID property - Set the message's subject by setting the
PR_SUBJECT_W property - Set the message type by setting the
PR_MESSAGE_CLASS_W to the correct string (I used "IPM.Note ")
- Send the message with
IMessage::SubmitMessage - Then release all the interface pointers correctly
I wrote wrappers around all the interface pointers to simplify these operations as much as possible - it's still pretty involved, though...
|
|
|
|
|
Hi Stuart Dootson,
I am really new to MAPI functions. I am trying to use the interface functions you suggested, but facing some difficulty in using them. Is it possible to put your source code here so that I can better understand how to use those functions and succeed.
Thanks and regards,
KJ
|
|
|
|
|
Can I suggest you download the Microsoft MFCMAPI[^] sample - that's got pretty much all the code that I mentioned and it's publicly available - I don't think my employers would be too happy if I were to post some of our application code
|
|
|
|
|
Hi,
I have the same issue as you, please tell me if you solve it!
I am having my app freeze when running mapi without outlook.
tkss
|
|
|
|
|
cPtr = (unsigned char *) &Float1 ;
cPtr += 3;
for (k = 0; k<=4; 4; k++)
{
*cPtr = sBuffer [BufPtr++];
cPtr--;
}
What the equivalent of pointer and address in C++ and C#. How to convert above code into C#?
Thanks
|
|
|
|
|
Hi,
pointers are available in C# although you often don't need them.
When used, you will need to turn on the "allow unsafe code" switch of the compiler,
and the "unsafe" keyword, possibly the "fixed" keyword too. I suggest you read up on those
if you can't live without pointers.
|
|
|
|
|
C# workshop?
Of one Essence is the human race
thus has Creation put the base
One Limb impacted is sufficient
For all Others to feel the Mace
(Saadi )
|
|
|
|
|
|
Hello,
I have written irc client. He stays on server because he answers to PING from server. But... when IRC server is reboot'ed or internet connection is disconected client can't see this happen and is inoperative till client is restarted again.
I want make some detection from client side to check if client is still online or IRC server died/client internet connection died.
How to do this simpliest way?
Help,
Regards
|
|
|
|
|
If you don't receive any pings from the server anymore for 5 minutes, it is probably gone.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
|
|
|
|
|
Yes i was thinking about it but wasnt sure if it is good solution, thanks a lot for answer.
So maybe like this:
DWORD timestamp = GetTickCount();
then in endless loop
if (timestamp < (GetTickCount() - 300000) ){
main(); //restart
}
if (Ping){
answer_pong;
timestamp = GetTickCount();
}
Hope it will work thanks again
|
|
|
|
|
yup it works good ping freq on ircd is 90 sec. so im checking now 110 sec. if client should reconnect.
Im curious how doing it mIRC client because its instant after disconnect from ircd but it isn't known by client ( ircd dont send any message ).
If they use same method as we above, optimally it would be 91 sec. between disconnect and reconnect but its instant.
|
|
|
|
|
Well, if the server (or maybe someone inbetween, like a proxy or such) closes the connection the TCP way (like, the server (the ircd) gets shut down normally), your client will know "rightaway" that the other side is "gone", however, if there is for example a power outage and the server just disappears all of a sudden without a word, your client can't know what happened, it can only guess that since the server doesn't say anything for a while, it's probably gone.
This is probably what happens when there is a split and what you see is that for a while, noone seems to answer you anymore, and after a few minutes you get the flood of people quitting. Something happens between two irc servers and they can't talk to each other anymore, and after a while they consider each other to be gone and generate the split event.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
|
|
|
|
|
I got it done now exactly like mIRC have.
When we have in endless loop recv (sockets) we should monitor for states <= 0. This means we got disconnected .
Reconnect is instant without depending on PING's now.
Thanks again, regards.
|
|
|
|
|
Normally a CSliderCtrl has its low values at the left/top end and its high values at the right/bottom end. I need a CSliderCtrl that has its low values at the right/bottom end and its high values at the left/top end. I've tried doing MyCSliderCtrl.SetRange(100,0) instead of MyCSliderCtrl.SetRange(0,100) but the thumb gets stuck at the left/top end. Surely there must be an easy way of getting CSliderCtrl to do this, but I can't work out what it is. Does anyone know? --- Thanks, Chris
|
|
|
|
|
Can't you just set the range to be 0 -> 100, and do 100 - (slider value) to get the "reverse" value?
|
|
|
|
|
That's probably impossible because of the internal implementation of the control.
BUT! All you have to do is set the range the normal way, SetRange( 0, 100 ), and then say:
RealValue = 100 - MyCSliderCtrl.GetValue();
|
|
|
|
|
I am writing an application using C++ and MFC. I am trying to prompt the user for the name of a file to save his/her data into. I would expect the following statement to do it:
<br />
CFileDialog dlg( FALSE, TEXT("rte"), m_strPathName,<br />
OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY );<br />
if ( dlg.DoModal() == IDOK ) {<br />
However, the above statement appears to do nothing. Could somebody please tell me what I am doing wrong or what the best way to debug this is?
Thanks
Bob
modified on Sunday, January 11, 2009 3:17 PM
|
|
|
|
|