14 Replies - 4651 Views - Last Post: 19 December 2012 - 07:02 AM Rate Topic: -----

#1 Tim.Simon  Icon User is offline

  • New D.I.C Head

Reputation: 13
  • View blog
  • Posts: 26
  • Joined: 12-June 12

Connecting to Exchange with MAPI in .NET

Posted 04 December 2012 - 12:30 PM

I have been assigned to connect to an Exchange Server using MAPI and .NET. I understand that this is not supported, but it is possible. The basic project requires that the application will check mail, send mail, and delete mail for a dedicated account. Thus, all users at a site will use the same account, despite the profile they are logged in to. My understanding of MAPI is that it communicates directly with the Exchange Server, and can do so without Outlook installed if the correct dll is present (MAPI32.dll).

I have made use of simple MAPI, and have all of these features working. Unfortunately, I am experiencing two issues. When I provide a profile name and password to the login, the currently logged in profile is still being accessed. The second issue I am having is that whenever I access the Exchange Server, I am given an access warning.

Does anyone know how to log in using a different profile than the person currently logged in, and how to stop the warning messages? My login code is below:

        public bool Logon()
        {
            if (!isLoggedIn)
            {
                if (String.IsNullOrEmpty(username) || String.IsNullOrEmpty(password))
                {
                    error = MAPILogon(WinHandle, null, null, 0, 0, ref session);
                    Logging.Log("Logged in using credentials for the current user.");
                }
                else
                    error = MAPILogon(WinHandle, username, password, 0, 0, ref session);

                if (error != 0)
                    error = MAPILogon(WinHandle, null, null, MapiLogonUI, 0, ref session);

                if (error != 0)
                    Logging.Log("There was a problem logging in: " + GetLastErrorCode());
                else
                    isLoggedIn = true;
            }

            return error == 0;
        }

        [DllImport("MAPI32.DLL", CharSet = CharSet.Ansi)]
        private static extern int MAPILogon(IntPtr hwnd, string profileName, string password, 
            int flag, int rsv, ref IntPtr session);



Any assistance would be greatly appreciated. Thank you.

Is This A Good Question/Topic? 0
  • +

Replies To: Connecting to Exchange with MAPI in .NET

#2 modi123_1  Icon User is offline

  • Suitor #2
  • member icon



Reputation: 8937
  • View blog
  • Posts: 33,473
  • Joined: 12-June 08

Re: Connecting to Exchange with MAPI in .NET

Posted 04 December 2012 - 12:31 PM

Moving to C#.
Was This Post Helpful? 0
  • +
  • -

#3 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3467
  • View blog
  • Posts: 10,687
  • Joined: 05-May 12

Re: Connecting to Exchange with MAPI in .NET

Posted 04 December 2012 - 05:27 PM

First, parameter 2 of MAPILogon is the profile name, not the username. You seem to be passing in a user name.

Second, if you don't want to use the current logged on profile, you need to pass in MAPI_NEW_SESSION in the flags parameter.

As for warning messages, can you tell us what warnings are being displayed?
Was This Post Helpful? 1
  • +
  • -

#4 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6036
  • View blog
  • Posts: 23,428
  • Joined: 23-August 08

Re: Connecting to Exchange with MAPI in .NET

Posted 04 December 2012 - 05:50 PM

When I think MAPI (shudder), I think Outlook Redemption. It will get you through most of the issues you're likely to encounter. It's well worth the investment.
Was This Post Helpful? 0
  • +
  • -

#5 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3467
  • View blog
  • Posts: 10,687
  • Joined: 05-May 12

Re: Connecting to Exchange with MAPI in .NET

Posted 04 December 2012 - 07:10 PM

Also, do you really need MAPI? Unless you have a really old version of Exchange, current versions of Exchange supports the internet standard protocols like POP3, SMTP, and IMAP.
Was This Post Helpful? 0
  • +
  • -

#6 Tim.Simon  Icon User is offline

  • New D.I.C Head

Reputation: 13
  • View blog
  • Posts: 26
  • Joined: 12-June 12

Re: Connecting to Exchange with MAPI in .NET

Posted 05 December 2012 - 03:28 PM

Thank you both for your responses.

@Skydiver, I actually am using the Profile for my logon. I had named it poorly, and changed the name after posting the question. My logon request now reads:

error = MAPILogon(WinHandle, profileName, password, MapiNewSession | MapiLogonUI, 0, ref session);



My profileName is the email address I am using, which, according to my network administrator, is the profile name. The password I am using is the same as I use to log in to the email account. I have verified that these will log me in to an Exchange profile. When I run now, I get the message that the profile name is not valid, and then the MAPI Logon UI appears, but the only available profile is Outlook. When logging on using the current account, I get the following warning: "A program is trying to send an e-mail message on your behalf. If this is unexpected, click Deny..." Each time a message is sent this appears. There is a similar one for checking mail, but I can allow access for a period of time with that one.

We actually already have an application which does the same thing in SPTP. However, this particular client says he will not allow mail to be sent unless it is through MAPI. I assume it is for security reasons, but it seems like the newer systems would provide better security.

@JackOfAllTrades, The company tries not to use third-party software, so I believe I am on my own on this one. I have come across Redemption in my research, and even received assistance from one of its developers.

Again, thank you both for the assistance.
Was This Post Helpful? 0
  • +
  • -

#7 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3467
  • View blog
  • Posts: 10,687
  • Joined: 05-May 12

Re: Connecting to Exchange with MAPI in .NET

Posted 05 December 2012 - 05:54 PM

View PostTim.Simon, on 05 December 2012 - 05:28 PM, said:

When I run now, I get the message that the profile name is not valid, and then the MAPI Logon UI appears, but the only available profile is Outlook.

That means your admin lied to you about the profile name. The real profile name can be found by looking at the subkeys under: HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles


View PostTim.Simon, on 05 December 2012 - 05:28 PM, said:

When logging on using the current account, I get the following warning: "A program is trying to send an e-mail message on your behalf. If this is unexpected, click Deny..." Each time a message is sent this appears. There is a similar one for checking mail, but I can allow access for a period of time with that one.


I believe that is a feature of the MAPI32.DLL installed by Outlook starting with Outlook 2003. As I recall the out-of-the-box MAPI32.DLL that ships with the OS didn't have that warning. Or at least the shipping OSes at the time of Office 2003.

Of course, that knowledge doesn't help you much after Outlook/Office has overwritten the out-of-the-box MAPI32.DLL. I think that if you use Extended MAPI instead of Simple MAPI, the message doesn't come up, but that could also be a hole that has been patched and it may also a give a warning now as well.
Was This Post Helpful? 1
  • +
  • -

#8 Tim.Simon  Icon User is offline

  • New D.I.C Head

Reputation: 13
  • View blog
  • Posts: 26
  • Joined: 12-June 12

Re: Connecting to Exchange with MAPI in .NET

Posted 06 December 2012 - 08:45 AM

@Skydiver, thank you once again for the reply. I am currently researching Extended MAPI, but having the same logon issues. I've not seen the security warnings, however. I checked the HKEY you said, and my only Profile under Profiles is Outlook. There are several folders under that with hex names. I've looked through them all, and although I have found our domain, I have not found any informaiton on the Profile Name (unless it was encoded in hex). I included the below image to show I am not mistaken.

Attached image(s)

  • Attached Image

Was This Post Helpful? 0
  • +
  • -

#9 Tim.Simon  Icon User is offline

  • New D.I.C Head

Reputation: 13
  • View blog
  • Posts: 26
  • Joined: 12-June 12

Re: Connecting to Exchange with MAPI in .NET

Posted 07 December 2012 - 10:51 AM

I've looked into Extended MAPI, and it looks like the way to avoid the security issues. I'm making my way through developing in the new environment, but it seems to be much more complex and difficult to get anything done. Unfortunately, I seem to come up with the same issues trying to log in. I can get logged in as the current profile, but not as any other profile. My login code is below:

public bool Initialize()
{
    IntPtr pSession = IntPtr.Zero;
    if (MAPINative.MAPIInitialize(IntPtr.Zero) == HRESULT.S_OK)
    {
        int errorCode = MAPINative.MAPILogonEx(0, ProfileName, Password, 
            (uint)(MAPIFlag.EXTENDED | MAPIFlag.NEW_SESSION | MAPIFlag.MAPI_LOGON_UI), out pSession);
        if (pSession == IntPtr.Zero)
            MAPINative.MAPILogonEx(0, ProfileName, Password, 
                (uint)(MAPIFlag.EXTENDED | MAPIFlag.NEW_SESSION | MAPIFlag.USE_DEFAULT), out pSession);
    }

    if (pSession != IntPtr.Zero)
    {
        object sessionObj = null;
        try
        {
            sessionObj = Marshal.GetObjectForIUnknown(pSession);
            session_ = sessionObj as IMAPISession;
        }
        catch { }
    }

    return session_ != null;
}


(Code is largely taken from a sample project I found with some modification)

When run, I pass in a profile name and password (email address and password) of a test profile. I get an error stating that "The profile name is not valid. Enter a valid profile name." When I press OK, I get the screen below with only Outlook available as a profile name. If I log out of Windows, I can enter the email and password to log in as the user, so I assume it is a correct profile.

According to everything I have read, this should be working. Does anyone have an idea of what I am doing wrong. Could it be something in the configuration of the Exchange Server itself?

As always, thank you for any assistance.

This post has been edited by Tim.Simon: 07 December 2012 - 10:53 AM

Was This Post Helpful? 0
  • +
  • -

#10 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3467
  • View blog
  • Posts: 10,687
  • Joined: 05-May 12

Re: Connecting to Exchange with MAPI in .NET

Posted 09 December 2012 - 07:17 AM

I suspect you are passing in a password when none is needed. And again, I suspect you are passing in the wrong profile name.

If you go to Control Panel and switch the view to Large or Small icons, and click on Mail (32-bits), that will bring up the MAPI profile manager. If you click on the "Profiles" button, it will give you the list of available profiles.

With the screen shot you have above, the profile name should be "Outlook", and there should not be any password.
Was This Post Helpful? 1
  • +
  • -

#11 Tim.Simon  Icon User is offline

  • New D.I.C Head

Reputation: 13
  • View blog
  • Posts: 26
  • Joined: 12-June 12

Re: Connecting to Exchange with MAPI in .NET

Posted 17 December 2012 - 03:58 PM

@Skydiver; thank you for your help.

My system has two Outlook accounts set up. One is named Outlook, which is my actual email account, and the other is named TestAccount. I can log in to my Outlook account and access the mail whether Outlook is open or not. This account is set as default. However, when I try to log in to the TestAccount, the login seems to happen successfully, but I get a null when trying to open the Inbox.

When the application is distributed, it will need to log in to an account other than the default account. All mail is sent from a dedicated account monitored by the application for messages that were not sent properly. During this time, Outlook may be opened under a user account.

Is there a way to log in to a secondary MAPI account, say, TestAccount, while a user is logged in to Outlook under a different account? My login code is listed below:

BOOL CMAPIEx::Login(LPCTSTR szProfileName, LPCTSTR szProfilePassword, BOOL bInitAsService)
{
	DWORD dwFlags=MAPI_EXTENDED | MAPI_EXPLICIT_PROFILE  | MAPI_NEW_SESSION;
	if(bInitAsService) 
		dwFlags|= MAPI_NT_SERVICE;
	return (MAPILogonEx(NULL, (LPTSTR)szProfileName, (LPTSTR)szProfilePassword, dwFlags, &m_pSession)==S_OK);
}



Since both accounts log in okay, I figured I would also post the code used to get the Inbox.

CMAPIFolder* CMAPIEx::OpenInbox(BOOL bInternal)
{
#ifdef _WIN32_WCE
	return OpenFolder(PR_CE_IPM_INBOX_ENTRYID, bInternal);
#else
	if(!m_pMsgStore) return NULL;

	ULONG cbEntryID;
	LPENTRYID pEntryID;
	DWORD dwObjType;
	LPMAPIFOLDER pFolder;

	if(m_pMsgStore->GetReceiveFolder(NULL, 0, &cbEntryID, &pEntryID, NULL)!=S_OK) return NULL;
	HRESULT hr=m_pMsgStore->OpenEntry(cbEntryID, pEntryID, NULL, m_ulMDBFlags, &dwObjType, (LPUNKNOWN*)&pFolder);
	MAPIFreeBuffer(pEntryID);

	if(hr==S_OK && pFolder) 
	{
		CMAPIFolder* pMAPIFolder=new CMAPIFolder(this, pFolder);
		if(bInternal) 
		{
			delete m_pFolder;
			m_pFolder=pMAPIFolder;
		}
		return pMAPIFolder;
	}
	return NULL;
#endif
}



Again, thank you to all who may have insight into this issue.
Was This Post Helpful? 0
  • +
  • -

#12 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3467
  • View blog
  • Posts: 10,687
  • Joined: 05-May 12

Re: Connecting to Exchange with MAPI in .NET

Posted 17 December 2012 - 06:54 PM

MAPI was designed to have multiple profiles active. Each of the profiles is just an instance of a profile object. It's object oriented after all. :-)

What error code are you getting in the HRESULT from the IMsgStore when you get a null for the inbox folder?

Have you tried running MapiView (or was it MapiItp?) and logged on to the other other account checked to see if it also gets a null for the inbox folder?
Was This Post Helpful? 0
  • +
  • -

#13 Tim.Simon  Icon User is offline

  • New D.I.C Head

Reputation: 13
  • View blog
  • Posts: 26
  • Joined: 12-June 12

Re: Connecting to Exchange with MAPI in .NET

Posted 18 December 2012 - 01:23 PM

@Skydiver,

The cpp that accesses MAPI is a dll which I access through C# as a COM object, so I cannot debug the code from the actual program. However, i was able to do some modifications on a test application, and found that I am getting an E_ACCESSDENIED returned when I try to send. I am able to read the mail with no problems, as well as delete messages.

I'm not sure what MapiView or MapiItp are, and couldn't find any information on them from Google.
Was This Post Helpful? 0
  • +
  • -

#14 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3467
  • View blog
  • Posts: 10,687
  • Joined: 05-May 12

Re: Connecting to Exchange with MAPI in .NET

Posted 19 December 2012 - 06:25 AM

In the older Windows SDK (circa 1995-2000), there used to be MAPI sample that is pretty much like the present http://www.softpedia...APIViewer.shtml
Was This Post Helpful? 0
  • +
  • -

#15 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6036
  • View blog
  • Posts: 23,428
  • Joined: 23-August 08

Re: Connecting to Exchange with MAPI in .NET

Posted 19 December 2012 - 07:02 AM

I know this isn't your fault, but I'd bet you'd be done with this -- or at least much further along -- if you'd gotten your misinformed bosses to let you use Redemption.

Not being allowed to use "third-party software" is the most asinine thing I've ever heard from someplace that does software development.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1