Tag Archives: Interop

Office 365 Developer: Mail, Calendar, Contacts REST APIs and Hybrid Exchange


If you’re an Azure/Office 365 application developer, then this session is for you. In this Office 365 Developer session (as part of Redmond Interoperability Protocols Plugfest 2017), Deepak Singh, Program Manager, delivered presentation on Mail, Calendar, and Contacts REST APIs and Hybrid Exchange.

https://channel9.msdn.com/Events/Open-Specifications-Plugfests/Redmond-Interoperability-Protocols-Plugfest-2017/Mail-Calendar-and-Contacts-REST-APIs-and-Hybrid-Exchange/player

Please make use of it.

Monitoring Event Sink # 32 – Best Practices: Performance related issues with Event sinks


I would like to share certain best practices – in order to improve the performance or overcome performance related issues associated with event sink and Programming guidelines for event sinks before you develop for your reference.

  • Exchange store events do not by themselves generate Windows Event Log entries. The underlying ExOLEDB provider generates performance counters for each event sink. The code that executes in response to an Exchange store event code can also generate Windows Event Log events and information for Windows Performance Counters.
  • Exchange store events that can be misused, or that can cause problems if installed incorrectly, should implement the ICreateRegistration interface, and programmatically prevent the event sink from being improperly registered. Cross-store access from within an event sink is not possible. Once registered and wrapped as COM+ applications, any user who knows the name of the event sink can register it in a folder to which they have write permissions.
  • If you have to register an event sink for all mailboxes in a store, you should register the event sink for store-wide events.
  • When Exchange starts up, it looks for and loads all registered event sinks, which takes some time.
  • Using many individual event sink registrations instead of a single store-wide event registration item significantly increases server startup time.
  • Always use care when running store event sinks, especially when using synchronous event sinks.
  • A synchronous event sink is triggered after a data request to the Exchange store but before the item is committed to the store.
  • The synchronous event sink has exclusive control over the item while it is processing. Therefore, a complex or poorly written sink can lock a resource for some time, or even bring an Exchange server to its knees.
  • But, I would recommend you to go through the Programming guidelines for event sinks before you develop:
    • For optimal performance, create an in-process Component Object Model (COM) class that supports execution in a multi-threaded apartment (MTA). The event dispatcher threads execute from within the Microsoft Internet Information Services (IIS) MTA. If your sink supports the single-threaded apartment (STA) only, then all interfaces will be marshaled across the MTA apartment and STA apartment boundaries.
    • Provide an implementation of the IEventIsCacheable interface by your sink. If you implement the IEventIsCacheable interface and the IsCacheable method returns S_OK, the event dispatcher will cache the sink and will use the same object for subsequent events; otherwise, each event will create a new instance of the sink.
    • Never install an untested sink on a production server, especially a sink that runs in- process. Exceptions thrown from within these in-process sinks may disable the IIS (inetinfo.exe) process or cause it to stop responding.
    • Do not place Microsoft Collaboration Data Objects (CDO) interface definitions in your sink’s interface definition language (IDL) file (if you use one directly) when working in C or C++. Information about CDO types—including all classes, interfaces, enumerations, and modules—can be found in the supplied headers. If you do place IDL information in your IDL file, and any of these types are referenced from within your library statement, you will re-map various Interface IDs (IIDs) from the CDO dynamically link library (DLL) to your DLL. This will not cause immediate harm because your DLL contains the necessary type library information required for the universal marshaller to function properly; however, if you subsequently remove the sink from the registry, the CDO libraries will function improperly.

Happy programming !!

Best Practices : How to quit Outlook application after automation from Visual Studio .NET client?


When you automate a Microsoft Outlook application from Microsoft Visual Basic .NET or Microsoft Visual C# .NET, the Outlook application does not quit when you call the Quit method. You can notice the application is closed, but still if we notice either the application or Outlook is running in behind the scenes. To make sure that the Office application quits, make sure that your automation code meets the following criteria:    

  • Use System.Runtime.InteropServices.Marshal.ReleaseComObject when you have finished using an object. This decrements the reference count of the RCW.
  • To release the reference to the variable, set the variable equal to Nothing or Null.
  • Use the Quit method of the Office application object to tell the server to shut down.
  • You can try this C#.Net code snippet:

    //If you are using Visual C# .NET, reference the code for the ReleaseObj() function:
     
    private void ReleaseObj(object obj)
    {
        try 
        {
            System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
        }
        catch {}
        finally 
        {
            obj = null;
        }
    }

    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, “Courier New”, courier, monospace;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }

    In this scenario, you can use the GC.Collect() method and the GC.WaitForPendingFinalizers() method after you release the last object. Because the runtime performs garbage collection on the RCW, the GC.Collect() method forces the garbage collector to run and might release any references that the RCW still has. The GC.Collect() method tries to reclaim the maximum memory that is available.

    Note: That this does not guarantee that all memory will be reclaimed.

    For more reference and detailed information, read blog post series by Matt.

    mstehle- The CDOs and CDONTS of Messaging Development – OOM.NET- Part # 1

    mstehle- The CDOs and CDONTS of Messaging Development – OOM.NET- Part # 2

    mstehle- The CDOs and CDONTS of Messaging Development – OOM.NET

    Outlook Object Model : Why i can’t able to assign value for MAPIFolder.WebViewURL ?


    One of my customer had created an Outlook Add-in using VSTO & Outlook Object Model (OOM). As per the business logic, he need to implement the WebViewURL in it. The MAPIFolder.WebViewURL works fine and take’s us to set value to it most of the times, but it doesn’t function as expected in some time; the strange thing is it’s not throwing any error or exception when we execute the code.

    //[Code Snippet : C# , VSTO, Outlook Object Model (OOM)]
    ...
    //Provide the non-default store path
    String pstPath = @"providelocalpath like c:personals.pst";
     
    MAPIFolder _pstFolder;
    //Add the PST
    this.Application.Session.AddStoreEx(pstPath, OlStoreType.olStoreDefault);
    _pstFolder = this.Application.Session.Folders[2];
     
    //Provide PSTFolder Name
    _pstFolder.Name = "SampleFolder";
     
    //Set the values
    MAPIFolder mf = _pstFolder.Folders.Add("MyHtmlView", Type.Missing);
     
    //Assign value for MAPIFolder.WebViewURL
    mf.WebViewURL = "http://www.microsoft.com";
    mf.WebViewOn = true;
    ...

    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, “Courier New”, courier, monospace;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }

    MAPIFolder.WebViewURL Property (Microsoft.Office.Interop.Outlook) Returns or sets a String (string in C#) indicating the URL of the Web page that is assigned to a folder. Read/write.

    http://msdn.microsoft.com/en-us/library/microsoft.office.interop.outlook.mapifolder.webviewurl.aspx

    When we start troubleshooting the case, we found that the issue happens for the non-default stores.

    During research we found couple of community blog post references, Randy & Ryan’s MS Press book that with respect to Microsoft Office Outlook 2007, the home page setting is disabled for non-default stores. Non-default stores can include Personal Folders files (.pst) or the Microsoft Windows SharePoint Services folders. These folders are also stored in a .pst file. To see the home page setting for a non-default store, right-click the store in the Navigation Pane, click Properties, and then click the Home Page tab.

    By default, you cannot type or paste a URL in the Address box. This issue occurs because, by default, home pages are disabled for non-default stores. To overcome this issue, we don’t have any programmatic resolution; but we can implement the resolution by refer the following support KB.

    Nutshell : MSXML is not supported in .Net applications


    I started working from Visual Basic 6, where i had used XML Parser (MS XML) to fetch the data’s using WebDAV. But the same logic won’t apply for you when you do with .Net applications.

    So, where we need to use MSXML and .Net Framework classes’s for XML?

    • Microsoft XML Core Services (MSXML) : As i updated you earlier you can easily use MSXML in Visual Studio 6.0 applications as DOM and SAX Parser with support for XSLT and XPath.
    • .NET Framework Classes for XML : But when you’re planning to implement the XML, then you need to make use of System.XML, the .Net framework classes for XML instead of MSXML.
      • Because the System.Xml namespace provides standards-based support for processing XML.
      • System.xml is not just the managed version of MSXML;
      • its functionality may overlap that of the MSXML COM library, and it also contains a rich object model and hierarchy.

    FYI: You can go through this below given article, which gives overall view and design goals of XML in the .Net Framework.

    Design Goals for XML in the .NET Framework
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpcondesigngoalsforxmlframeworkinnet.asp

    No Official support. Do you know why it so?

    Officially Microsoft does not support the use of MSXML (Microsoft’s COM-based XML parser) in .NET applications.

    This is because MSXML uses threading models and garbage-collection mechanisms that are not compatible with the .NET Framework. Using MSXML in .NET applications through COM interoperability can result in unexpected problems that are difficult to debug.

    Please note that Microsoft does not recommend or support directly instantiating and using MSXML objects in .NET code, nor does Microsoft recommend or support marshalling MSXML interface pointers across the interop boundary

    So what is the workaround or best practice needs to be done?

    Support for implementing standards-based XML functionality in .NET applications is built into the .NET Framework. The .NET Framework classes in the System.xml namespaces should be used to implement standards-based XML functionality in .NET applications.

    Code snippets: FYI: I have enclosed couple of code snippets for your reference.

    Earlier we might have created a web request to a web server like this using MSXML,

       1:  Dim oXMLHttpRequest As New MSXML2.XMLHTTP
       2:  ' Provide the respective values
       3:  oXMLHttpRequest.open "GET", "http://[servername]/[virtualdirectory]/[filename.xml]", False, "", ""
       4:  oXMLHttpRequest.send
       5:  Debug.Print (oXMLHttpRequest.responseText)

    When you create the .Net applications, you need to do the same by using .Net framework classes like,
    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, “Courier New”, courier, monospace;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }

       1:      using System;
       2:      using System.Xml;
       3:      using System.Net;
       4:      
       5:      public class Sample    
       6:      {
       7:          public static void Main()        
       8:          {
       9:              // Provide the respective values
      10:              HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://[ServerName]/[virtualdir]/[filename.xml]");
      11:   
      12:              // Provide the Username and password.
      13:              request.Credentials = new NetworkCredential("[username]", "[password]");
      14:   
      15:              // It downloads the XML file from the specified server.
      16:              HttpWebResponse response = (HttpWebResponse)request.GetResponse();
      17:              
      18:              // Then it loads the XmlDocument.
      19:              XmlDocument doc = new XmlDocument();            
      20:              doc.Load(response.GetResponseStream());
      21:              doc.Save(Console.Out);
      22:   
      23:              // Finally don't forgot to release the resources of the response.
      24:              response.Close();
      25:          }
      26:      }
     
     

    Outlook Programming Series # 13 : Programmatic equivalent for Outlook UI’s Send/Receive


    Whenever we work with Outlook 2007 UI, we click either “Send/Receive button” or press “F9” to send and receive emails. In couple of our cases we use to do programmatically you can make use of Outlook Object Model’s (OOM) SendAndReceive method. You need to know that calling the SendAndReceive method is synchronous only.


    Syntax: expression.SendAndReceive(showProgressDialog)


    Here, showProgressDialog – Indicates whether the Outlook Send/Receive Progress dialog box should be displayed, regardless of user settings


    Note:



    • SendAndReceive provides the programmatic equivalent to the Send/Receive All command that is available when you click Tools and then Send/Receive.

    • If you do not need to synchronize all objects, you can use the SyncObjects collection object to select specific objects. For more information, see NameSpace.SyncObjects.

    • All accounts defined in the current profile are used in Send/Receive All.

    • If an online connection is required to perform the Send/Receive All, then the connection is made according to user preferences.

    Using with Outlook Object Model & Visual Basic 6:


    Use NameSpace.SendAndReceive Method. Initiates immediate delivery of all undelivered messages submitted in the current session, and immediate receipt of mail for all accounts in the current profile.


    Using in .Net environment & Outlook interop:


    Use NameSpaceClass.SendAndReceive Method (Microsoft.Office.Interop.Outlook). The types and members of the Microsoft.Office.Interop.Outlook namespace provide support for interoperability between the COM object model of Microsoft Office Outlook 2007 and managed applications that automate Outlook.


    This is a .NET class or a member of a .NET class created when processing a COM coclass that is required by managed code for interoperability with the corresponding COM object. Use this class only when you have to access an earlier event in this class that has been subsequently extended in a later version of Outlook. Otherwise, use the .NET interface derived from the COM coclass.


    Code snippet (used in the add-in):


    C#


       1:  public virtual void _NameSpace.SendAndReceive (
       2:      [InAttribute] bool showProgressDialog
       3:  )

    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, “Courier New”, courier, monospace;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }

    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, “Courier New”, courier, monospace;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }

    then we need to use the SyncObject,


       1:  //trap the SyncObject.SyncStart Event 
       2:    this.Application.Session.SyncObjects[1].SyncStart += new Microsoft.Office.Interop.Outlook.SyncObjectEvents_SyncStartEventHandler(ThisAddIn_SyncStart);
       3:   
       4:  //finally don’t forget to trap the SyncObject.SyncEnd Event 
       5:  this.Application.Session.SyncObjects[1].SyncEnd += new Microsoft.Office.Interop.Outlook.SyncObjectEvents_SyncEndEventHandler(ThisAddIn_SyncEnd);
       6:   

    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, “Courier New”, courier, monospace;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }

    Visual Basic:


       1:  Dim instance As NameSpaceClass
       2:  Dim showProgressDialog As Boolean
       3:   
       4:  CType(instance, _NameSpace).SendAndReceive(showProgressDialog)

    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, “Courier New”, courier, monospace;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }


    Reference(s):


    http://msdn.microsoft.com/en-us/library/microsoft.office.interop.outlook.namespaceclass.sendandreceive.aspx
    http://msdn.microsoft.com/en-us/library/microsoft.office.interop.outlook.syncobjectevents_event_members.aspx