locked
Outlook Automation using C++ RRS feed

  • Question

  • Hello everybody ! Our customers access the applications in the Citrix environment. Windows 10 is installed on all terminal servers. One of the applications written in C ++ uses Outlook Automation ( Outlook Object Model ) for sending e-mails. If the application tries to programmatically set an e-mail address of the recipient (IMailItemPtr-> Recipients-> Add (recipient)), the following message from Outlook appears: "A program is trying to access your e-mail address information in Outlook" . We want to suppress it. We tried to sign the application digitally and added the certificate to the "Trusted Publishers" in Outlook. Unfortunately it did not help. For security reasons, the administrators do not want to activate the option "Never warn me about suspicious activity (not recommended)" in Outlook ... Can the problem be solved in other ways ( programmatically )? Why doesn't digital signature work ? Thanks in advance !
    Monday, September 14, 2020 9:28 PM

All replies

  • The easiest workaround is to make sure you install an up-to-date AntiVirus app.

    If you cannot control the environment, then your options are

    1. Extended MAPI

    2. Redemption

    3. ClickYes.


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Monday, September 14, 2020 9:39 PM
  • AntiVirus is installed in the Citrix environment. But Outlook is unable to check AntiVirus status when installed on a Windows Server...

    Monday, September 14, 2020 9:51 PM
  • Then the other 3 options apply...

    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Monday, September 14, 2020 10:47 PM
  • If I understand correctly, the second and third options require an external software and are subject to a fee ... What exactly do you mean with "Extended MAPI" ?

    Could you also tell me why digital signature doesn't work ( regardless of the fact that certificate was added to the "Trusted Publishers" in Outlook ) ? For which purpose does digital signature then serve ?

    Tuesday, September 15, 2020 7:17 AM
  • Extended MAPI is the native Outlook API. It is not subject to the security prompts. Play with MFCMAPI or OutlookSpy to get a feel for it.

    The certificate would not work because it was never supposed to work - Outlook cannot and woudl not be able to check whether a signed executable is calling into it.


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Tuesday, September 15, 2020 4:06 PM
  • Redemption is built on top of Extended MAPI, so I'd combine both options into a single one. It just provides a convenient high level API for developers. But in case of C++ I don't see any problems with using original Extended MAPI code (MFCMAPI is an open source application written in C++). 

    As for other options you may consider:

    1. Security Manager for Microsoft Outlook which allows turning off and on security prompts in Outlook dynamically by using a single line of code.

    2. Set up a group policy to prevent security prompts in Outlook. See Security Behavior of the Outlook Object Model for more information. You must have a valid antivirus software installed on the system. 

    3. Develop a COM add-in which has access to the trusted Application object. And then communicate from a standalone application with an add-in using standard .Net tools (Remoting) or other ways if you don't use .Net framework.


    profile for Eugene Astafiev at Stack Overflow, Q&A for professional and enthusiast programmers

    Thursday, September 17, 2020 6:51 AM
  • Hi Eugene, thank you very much for your suggestions! Two additional questions:

    1. Could you please describe in few words how to use Extended MAPI or provide a simple example of using it ?

    2. Do I understand correctly that it is not enough to register a COM add-in in a "normal" COM way and it is also necessary to make it known for Outlook somehow? Should I sign a COM DLL digitally or what exactly should be done ? 
    Thursday, October 1, 2020 10:24 AM
  • 1. To get a taste for Extended MAPI, download MFCMAPI from https://github.com/stephenegriffin/mfcmapi. Play with the binary as well as look at its source code. You might also want to download OutlookSpy (http://www.dimastr.com/outspy) to see the live MAPI object.

    2. Besides exposing a regular IDispatch derived COM object, your addin must implement the IDTExtensibility2 interface - see https://docs.microsoft.com/en-us/dotnet/api/extensibility.idtextensibility2?view=visualstudiosdk-2019. Outlook will load your addin if it is listed inHKCU\SOFTWARE\Microsoft\Office\Outlook\Addins


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.24 is now available!


    Friday, October 2, 2020 4:20 AM
  • Hi Dima,

    1. As Dmitry already mentioned, MFCMAPI is the best and complex example, see https://github.com/stephenegriffin/mfcmapi .

    2. Your add-in should be registered in the windows registry, see Registry entries for VSTO Add-ins. Beside the VSTO manifest, all other keys are valid for all kind of add-ins. 


    profile for Eugene Astafiev at Stack Overflow, Q&A for professional and enthusiast programmers

    Friday, October 2, 2020 5:56 AM
  • Hello, both of you. 

    As you might have already understood, I am not a big specialist in Office automation. Just to avoid any misunderstanding, I would like to describe step by step and as simple as possible what the problem is. 

    We have an online application written in C++ and running on Windows 10 64-bit. In this environment, a 32-bit version of Outlook 2016 is installed. The online application should be able to open Outlook and to set the recipient's E-mail-address, the title and the text of the E-mail automatically. The user has only to correct the text (if necessary) and to press on the Send-Button to send a mail ( or to cancel sending ).

    If I understood your suggestion correctly to realize this plan, I could create a COM component based on Outlook object model and implementing "ISendMail" interface. A corresponding ATL COM class could look like this (let's limit ourselves to the case where client sets the title of the E-mail only):

    // SendMail.cpp : Implementation of CSendMail
    
    #include "stdafx.h"
    #include "SendMail.h"
    #include <iostream>
    #include <objbase.h>
    #include "mso.tlh"
    #include "msoutl.tlh"
    
    STDMETHODIMP CSendMail::sendMail(const BSTR title)
    {
    	// Initialize the COM Library
    	HRESULT hr = CoInitialize(NULL);
    
    	if (SUCCEEDED(hr))
    	{
    		// Create the Outlook application
    		Outlook::_ApplicationPtr spOutlook(__uuidof(Outlook::Application));
    
    		// Get the MAPI namespace
    		Outlook::_NameSpacePtr pMAPI = spOutlook->GetNamespace("MAPI");
    
    		// Initiate a new Outlook-session
    		pMAPI->Logon("", "", false, true); // Log on by using the default profile or existing session (no dialog box).
    
    		// Query the MailItem interface
    		Outlook::_MailItemPtr IMailItemPtr = spOutlook->CreateItem(Outlook::olMailItem);
    
    		IMailItemPtr->Subject = title;
    
    		IMailItemPtr->Recipients->Add("xxx@yyy.zz");
    
    		hr = IMailItemPtr->Display(true);
    	}
    
    	CoUninitialize();
    
    	return S_OK;
    }

    After "normal" registration ( via regsvr32 ), the client code can use a new component:

    #include <iostream>
    #include <objbase.h>
    #include "Outlook_i.h"
    
    int main()
    
    {
    	////// COM-Objekt erzeugen
    	CoInitialize(NULL);
    	ISendMail* pISendMail = NULL;
    	CoCreateInstance(CLSID_SendMail, NULL, CLSCTX_INPROC_SERVER, IID_ISendMail, (void**)&pISendMail);
    
    	////// COM-Funktionen nutzen
    	pISendMail->sendMail(OLESTR("TEST123"));
    
    	////// COM-Objekt vernichten
    	pISendMail->Release();
    	CoUninitialize();
    }

    Locally (on my PC) it works perfectly fine. The Outlook opens immediately without any warnings. Unfortunately, on the Windows Server the security warning "A program is trying to access e-mail address information etc" is popping up and the COM component is not recognized as a valid Office Add-In (can't be added to COM-Add-Ins in Outlook).

    Do you have an idea, what am I doing wrong ? 

    Thank you in advance for your response!

    Monday, October 5, 2020 3:02 PM
  • Why do you need to create a COM addin if all you want if a new email compose window? And Outlook won't recognize your COM object as an addin unless it implements IDTExtensibility2 interface and is registered in the appropriate registry keys.

    Firstly, the prompt is shown if there is no up-to-date anto-virus app installed.

    Secondly, instead of using MailItem.Recipients.Add, set the MailItem.To property - the prompt is triggered only when reading that property, but not when setting.

    Thirdly, unless you plan to do a lot more than what you showed above, just call ShellExecute() and pass a mailto url, e.g. "mailto:user@dimain.com?subject=test%20subject"


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Monday, October 5, 2020 3:14 PM
  • Thank you very much ! The problem is solved ! :)
    Tuesday, October 6, 2020 5:03 AM