Nayan's [MSFT] Blog

  • Exchange 2003 and Outlook 2003 moves to Extended Support

    Exchange Server 2003 goes into Extended Support on 4/14/2009.
    Details on our lifecycle policy for Exchange 2003 can be found at http://support.microsoft.com/lifecycle/?LN=en-us&p1=1773&x=11&y=9

    Products Released General Availability Date

    Mainstream Support Retired

    Extended Support Retired Service Pack Retired Notes
    Exchange Server 2003 Enterprise Edition 9/28/2003 4/14/2009 4/8/2014

    5/25/2005

     
    Exchange Server 2003 Service Pack 1 5/25/2004 Not Applicable Not Applicable 1/8/2008  
    Exchange Server 2003 Service Pack 2 10/19/2005 Review Note Review Note  

    Support ends 12 months after the next service pack releases or at the end of the product's support lifecycle, whichever comes first.  For more information, please see the service pack policy at  http://support.microsoft.com/lifecycle/#ServicePackSupport

    Exchange Server 2003 Standard Edition 9/28/2003

    4/14/2009

    4/8/2014 5/25/2005  


    Outlook 2003 goes into Extended Support on 4/14/2009.
    http://support.microsoft.com/lifecycle/?p1=2520

    Products Released General Availability Date Mainstream Support Retired Extended Support Retired Service Pack Retired Notes
    Outlook 2003 11/20/2003 4/14/2009 4/8/2014    
  • Outlook Rules!

    Rules are evaluated in sequence according to the increasing order of this value. The evaluation order for rules that have the same value in this property is undefined.
    PidTagRuleSequence: http://msdn.microsoft.com/en-us/library/dd188686.aspx

    The Rule.ExecutionOrder property could be used to assign priority to rules. Rules.Item(1) represents a rule with ExecutionOrder being 1, Rules.Item(2) represents a rule with ExecutionOrder being 2, and Rules.Item(Rules.Count) represents the rule with ExecutionOrder being Rules.Count.
    http://msdn.microsoft.com/en-us/library/bb176165.aspx

    The below VBA script changes the Execution order of the 2nd rule whose execution order is 2nd to last.
    Whenever the order for the rule x changed to x+n, all the rules from x+1 till x+n is shifted up.

    E.g. If there are 5 rules and the 2nd rule whose Execution order is 2nd is changed to 5:
    Rule 3 execution order is changed to 2
    Rule 4 execution order is changed to 3
    Rule 5 execution order is changed to 4
    Rule 2 execution order is changed to 5

    Sub CreateRule()
        Dim colRules As Outlook.Rules
        Dim oRule As Outlook.Rule
        Dim colRuleActions As Outlook.RuleActions
        Dim oMoveRuleAction As Outlook.MoveOrCopyRuleAction
        Dim oFromCondition As Outlook.ToOrFromRuleCondition
        Dim oExceptSubject As Outlook.TextRuleCondition
        Dim oInbox As Outlook.Folder
        Dim oMoveTarget As Outlook.Folder
        Dim intCounter As Integer
        Dim oRuleCount As Integer 
    
        Set oInbox = Application.Session.GetDefaultFolder(olFolderInbox)
        'Get Rules from Session.DefaultStore object
        Set colRules = Application.Session.DefaultStore.GetRules()
        oRuleCount = colRules.Count
        Debug.Print oRuleCount
        intCounter = 1
        Do While intCounter < (colRules.Count + 1)
            Set oRule = colRules.Item(intCounter)
            Debug.Print oRule.Name
            Debug.Print oRule.ExecutionOrder
            intCounter = intCounter + 1
        Loop
        Set oRule = colRules.Item(2)
        oRule.ExecutionOrder = oRuleCount
        'Update the server and display progress dialog
        colRules.Save
    End Sub

    If a rule is created using the Outlook Rules Wizard, its value is least and has highest priority. The existing rules gets pushed down by 1 i.e. PR_RULE_SEQUENCE gets increased by 1 for all the existing rules.
    Conversely, a new rule gets higher priority when created using Outlook wizard or using Outlook Object model programmatically.

  • Outlook 2007 and Simple MAPI

    We have seen a lot of applications that use Simple MAPI. Unlike Extended MAPI (or MAPI), it is supported in managed code as well.

    Also, a lot developers have come across issues with Simple MAPI with Outlook 2007.
    Starting with Outlook 2007, Simple MAPI is no longer supported. However, its still supported by Exchange 2003.
    http://msdn.microsoft.com/en-us/library/cc815424.aspx

  • Using Powershell to send email message using CDOSYS

    Scripts are used do a pre-check before getting started with debugging application.
    VB Scripts being the favourite on Microsoft platform.

    Most common being CDOSYS issues.

    Below is the Powershell script to send email using System.Net.Mail namespace.

    [System.Net.Mail.MailMessage]$message = New-Object System.Net.Mail.MailMessage("from@contoso.com", "to@contoso.com", "This is Subject", "This is body")
    [System.Net.Mail.SmtpClient]$client = New-Object System.Net.Mail.SmtpClient("XXX.XXX.XXX.XXX")
    $client.Timeout = 100
    $client.Send($message)

    Long live Powershell!

  • PST folder Hierarchy

    The article sheds light into how PST folder hierarchy is created.

    Adding a PST to an existing profile doesn't create the all the Special Folders and looks as below:

    image

    We have the IPM Root, Common Views, Search Results, Deleted Items under the "Top of Personal Folders".
    In short, the IPM subtree doesn't gets fully constructed which should include Outbox folder, Sent Items Folder and the Receive folder like the Inbox.

    However, if the PST is set as the Default folder, we will see all the eight special folders that are part of IPM subtree are created and usually cannot be deleted in Outlook.

     image

  • What you need to know about MAPI properties

    MAPI properties runs from 0001 to 3FFF
    4000 to 7FFF belongs to message and recipient properties, and either clients or service providers can define properties in this range
    Named properties – 8000 onwards
    Secure profile properties for Service providers - 0x67F0 through 0x67FF

    When we use Named properties, MAPI picks up an available property identifier. This way it avoids conflict with the properties that are being used by MAPI clients like Outlook.

    Transmittable/Non-transmittable properties

    Non-transmittable properties usually contain information that is of value only to clients and service providers operating with the current session. These properties would not necessarily be useful to another messaging system and another set of service providers.

    A non-transmittable message property exposed at both the sending and receiving ends of a transmission, with different values depending upon the client application or store provider involved. This property is initialized by the client or message store provider when a message is created and saved for the first time and then updated periodically by the message store provider, a transport provider, and the MAPI spooler as the message is processed and its state changes.

    Transmittable properties are transferred with a message; non-transmittable properties are not transferred with a message. The concept of transmittable properties applies primarily to transport providers.

  • GetAttachment doesn't get Size of the attachment

    For those, who don't use Exchange Web Services API, but bank on its Requests and Responses.

    An email message has a attachment table that contains the attachments, and these in turn contain the properties such as PR_ATTACH_SIZE, PR_ATTACH_DATA_BIN etc. This means that email message doesn't have any of the attachment properties on it.

    The GetItem could be used to get the all the properties of an email message, the extended properties being got by PathToExtendedFieldType.

    The GetAttachment doesn't get the PR_ATTACH_SIZE MAPI Property when being given the Attachment ID. The size could be found by using the Length property of the Content fetched in the byte array.

    This is also validated with PathToExtendedFieldType, which when usen in GetAttachment request doesn't send back the PR_ATTACH_SIZE.

    GetAttachmentType getAttachmentRequest = new GetAttachmentType();
    getAttachmentRequest.AttachmentShape = new AttachmentResponseShapeType();
    PathToExtendedFieldType pteftFlagStatus = new PathToExtendedFieldType();
    pteftFlagStatus.PropertyTag = "0x0E20"; // Tag of PR_ATTACH_SIZE
    pteftFlagStatus.PropertyType = MapiPropertyTypeType.Long;

    REQUEST
    <?xml version="1.0"?>
      <GetAttachmentType xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <AttachmentShape xmlns="http://schemas.microsoft.com/exchange/services/2006/messages">
          <AdditionalProperties xmlns="http://schemas.microsoft.com/exchange/services/2006/types">
            <ExtendedFieldURI PropertyTag="0x0E20" PropertyType="Long" />
          </AdditionalProperties>
        </AttachmentShape>
        <AttachmentIds xmlns="http://schemas.microsoft.com/exchange/services/2006/messages">
        <AttachmentId Id="AAAaAEFkbWluaXN0cmF0b3JAZGMxMjkw...</AttachmentIds>
    </GetAttachmentType>

    RESPONSE
    <?xml version="1.0"?>
      <GetAttachmentResponseType xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <ResponseMessages xmlns="http://schemas.microsoft.com/exchange/services/2006/messages">
          <GetAttachmentResponseMessage ResponseClass="Success">
            <ResponseCode>NoError</ResponseCode>
              <Attachments>
               <FileAttachment xmlns="http://schemas.microsoft.com/exchange/services/2006/types">
                 <AttachmentId Id="AAAaAEFkbWluaXN0cmF0b3JAZG...<Name>smime.p7m</Name>
                     <ContentType>multipart/signed</ContentType>
                       <Content>TUlNRS1WZXJza.....
                       </Content>
               </FileAttachment>
              </Attachments>
          </GetAttachmentResponseMessage>
        </ResponseMessages>
    </GetAttachmentResponseType>

    There we go. The response doesn't yield the Extended Field type property.
    Hence, the theorem.

     

  • Personal Store (PST) without Outlook

    Is there a way to access Personal Store (PST) wihtout having Outlook installed?
    Reason: Take out the Outlook dependency from PST ;-)

    Further to SGRIFFIN'S blog:
    http://blogs.msdn.com/stephen_griffin/archive/2007/03/19/mapi-and-exchange-2007.aspx

    Exchange 2007 onwards, MAPI isn't included on the box and available as separate download:
    http://www.microsoft.com/downloads/details.aspx?FamilyID=e17e7f31-079a-43a9-bff2-0a110307611e&DisplayLang=en

    The MSPST32.DLL shipped in this ExchangeMapiCdo download is the one of Exchange, that doesn't provide support for Unicode.

    So, there is no way to access Unicode PSTs other than installing Outlook.

    Long live Outlook!

  • How to get the body of the email message using Exchange 2007 Web services

    Futher to SGriffin's Weblog as below:
    http://blogs.msdn.com/stephen_griffin/archive/2007/02/09/exchange-web-services-and-internet-message-headers.aspx

    in order to access the body of an email message, the MAPI property PR_BODY_HTML (0x1013) could be used.
    However, we need to remember the property is binary in nature and base64 encoded.
    Here comes Convert.FromBase64String, System.Text.ASCIIEncoding to our rescue using which the ASCII of the body could be got, as below:
     
      byte [] bAscii = Convert.FromBase64String(it.ExtendedProperty[0].Item.ToString());
      System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
      string str = enc.GetString(bAscii);

    /* Source Code */
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Text;
    using System.Net;
    using System.IO;
    using System.Xml.Serialization;
    using WebServices1.localhost;

    namespace WebServices1
    {
      class Program
      {
        static void Main(string[] args)
        {
          ExchangeServiceBinding esb = new ExchangeServiceBinding();
          esb.Credentials = new NetworkCredential("username", "password", "domain");
          esb.Url = @http://localhost/EWS/Exchange.asmx;
          DistinguishedFolderIdType[] folderIDArray = new DistinguishedFolderIdType[1];
          folderIDArray[0] = new DistinguishedFolderIdType();
          folderIDArray[0].Id = DistinguishedFolderIdNameType.inbox;
          //set the props that we want to retrieve
          FolderResponseShapeType frst = new FolderResponseShapeType();
          frst.BaseShape = DefaultShapeNamesType.AllProperties;
          GetFolderType myfoldertype = new GetFolderType();
          myfoldertype.FolderIds = folderIDArray;
          myfoldertype.FolderShape = frst;
          Console.WriteLine("Getting inbox");
          GetFolderResponseType myFolder = esb.GetFolder(myfoldertype);
          FolderInfoResponseMessageType firmtInbox = (FolderInfoResponseMessageType)myFolder.ResponseMessages.Items[0];
          Console.WriteLine("got folder: {0}", firmtInbox.Folders[0].DisplayName);
          PathToUnindexedFieldType ptuftSubject = new PathToUnindexedFieldType();
          ptuftSubject.FieldURI = UnindexedFieldURIType.itemSubject;
          PathToExtendedFieldType pteftFlagStatus = new PathToExtendedFieldType();
          pteftFlagStatus.PropertyTag = "0x1013"; // PR_BODY_HTML
          pteftFlagStatus.PropertyType = MapiPropertyTypeType.Binary;
          FindItemType findItemRequest = new FindItemType();
          findItemRequest.Traversal = ItemQueryTraversalType.Shallow;
          findItemRequest.ItemShape = new ItemResponseShapeType();
          findItemRequest.ItemShape.BaseShape = DefaultShapeNamesType.AllProperties;
          findItemRequest.ItemShape.AdditionalProperties = new BasePathToElementType[2];
          findItemRequest.ItemShape.AdditionalProperties[0] = ptuftSubject;
          findItemRequest.ItemShape.AdditionalProperties[1] = pteftFlagStatus;
          findItemRequest.ParentFolderIds = new FolderIdType[] { firmtInbox.Folders[0].FolderId };
          FindItemResponseType firt = esb.FindItem(findItemRequest);
          foreach (FindItemResponseMessageType firmtMessage in firt.ResponseMessages.Items)
          {
            if (null != firmtMessage.RootFolder && firmtMessage.RootFolder.TotalItemsInView > 0)
            {
              foreach (ItemType it in ((ArrayOfRealItemsType)firmtMessage.RootFolder.Item).Items)
              {
                Console.WriteLine("got item subject: {0}", it.Subject);
                if (null != it.ExtendedProperty)
                {
                  Console.WriteLine("Prop PR_BODY_HTML(Binary): {0}", it.ExtendedProperty[0].Item.ToString());
                  byte [] bAscii = Convert.FromBase64String(it.ExtendedProperty[0].Item.ToString());
                  Console.WriteLine();
                  System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
                  string str = enc.GetString(bAscii);
                  Console.WriteLine("Prop PR_BODY_HTML(ASCII): {0}", str);
                }
                else
                {
                  Console.WriteLine("Prop PR_BODY_HTML: not found");
                }
              }
            }
          }
          Console.WriteLine("\nHit any key to continue");
          Console.ReadKey(true);
        }
      }
    }

  •  getting inserted before the base64 encoded representation of the binary data of GIF image

    When an application is creating a CDO[6.5.6756.0] Message and inserting a BodyPart of the type GIF image, and the base64 encoded representation of the binary data is initialized to the body part as shown below:
    Const c_Base64Sample = "R0lGODlhEAAOAPcAAAAAAIAAAACAAICAAAAAgIAAgACAgICAgMDAwP8AAAD/AP//AAAA//8A/wD"

    sFile = "sample.gif"
    sContentType = "image/gif"
    Set iPartAttach = iPartBody.AddBodyPart
    iPartAttach.ContentMediaType = sContentType & "; name=""" & sFile & """"
    iPartAttach.ContentTransferEncoding = "base64"
    iPartAttach.Fields("urn:schemas:mailheader:priority") = ""
    iPartAttach.Fields("urn:schemas:mailheader:importance") = ""
    iPartAttach.Fields("urn:schemas:mailheader:content-transfer-encoding") = "base64"
    iPartAttach.Fields("urn:schemas:mailheader:content-disposition") = "attachment; filename=""" & sFile & """"
    iPartAttach.Fields.Update

    Set stmWrite = iPartAttach.GetEncodedContentStream
    stmWrite.WriteText c_Base64Sample
    stmWrite.Flush
    stmWrite.Close

     getting inserted before the base64 encoded representation of the binary data of GIF image, and displayed when read back as below:

    Dim stm As ADODB.Stream
    Set stm = i_iMsg.GetStream()
    Text1.Text = stm.ReadText
    stm.Close

    
    R0lGODlhEAAOAPcAAAAAAIAAAACAAICAAAAAgIAAgACAgICAgMDAwP8AAAD/AP//AAAA//8A/wD

    This could be corrected by setting the charset of the stream to "us-ascii"
    stmWrite.Charset = "us-ascii"

  • PropertyAccessor object in Outlook 2007 OOM

    As mentioned in the http://support.microsoft.com/kb/266353, programmatically reading MAPI properties by using APIs such as Extended MAPI the PropertyAccessor object in the Microsoft Office Outlook 2007 object model is supported.
    Here's how we do it in C++.

    #pragma warning(disable:4146)

    #import "C:\Windows\System32\stdole2.tlb" rename_namespace("Outlook")
    #import "C:\Program Files\Common Files\Microsoft Shared\OFFICE12\mso.dll" rename_namespace("Outlook")
    #import "C:\Program Files\Microsoft Office\OFFICE12\msoutl.olb" rename_namespace("Outlook")

    #pragma warning(default:4146)

    #include <stdio.h>
    #include <tchar.h>

    using namespace Outlook;

    struct StartOle
    {
     StartOle()
     {
      CoInitialize(NULL);
     }

     ~StartOle()
     {
      CoUninitialize();
     }
    }_inst_StartOle;

    void dump_com_error(_com_error &e)
    {
        _tprintf(_T("Oops - hit an error!\n"));
        _tprintf(_T("\a\tCode = %08lx\n"), e.Error());
        _tprintf(_T("\a\tCode meaning = %s\n"), e.ErrorMessage());
        _bstr_t bstrSource(e.Source());
        _bstr_t bstrDescription(e.Description());
        _tprintf(_T("\a\tSource = %s\n"), (LPCTSTR) bstrSource);
        _tprintf(_T("\a\tDescription = %s\n"), (LPCTSTR) bstrDescription);
    }

    void main(int argc, char* argv[])
    {
     try
     {
      _ApplicationPtr pApp("Outlook.Application");
      
      _NameSpacePtr pNameSpace;
      pNameSpace = pApp->GetNamespace(L"MAPI");

      MAPIFolderPtr pAppointmentMAPIFolder;
      
      pAppointmentMAPIFolder = pNameSpace->GetDefaultFolder(olFolderCalendar);

      _ItemsPtr pItems;
      _AppointmentItemPtr pAppointmentItem;

      pItems = pAppointmentMAPIFolder->GetItems();

      printf("No of items : %d\n", pItems->Count);

      pAppointmentItem = pItems->GetFirst();

      /* The following code uses GetPropertyAccessor: gets the user property WORKS */

      _PropertyAccessorPtr pPropAccPtr;
      pPropAccPtr = pAppointmentItem->GetPropertyAccessor();
      _variant_t var;
      var = pPropAccPtr->GetProperty(L"http://schemas.microsoft.com/mapi/string/{00020329-0000-0000-c000-000000000046}/SomeID");

      /* The following code uses GetUserProperties: does not get the user property DOES NOT WORK */

      //UserPropertiesPtr pUP;
      //pUP = pAppointmentItem->GetUserProperties();
      //UserPropertyPtr uPP = pUP->Item(L"SomeID");
      //_variant_t var;
      //var = pPropAccPtr->GetProperty(L"http://schemas.microsoft.com/mapi/string/{00020329-0000-0000-c000-000000000046}/SomeID");
      //var = uPP->GetValue();
      
     }
     catch(_com_error &e)
     {
      dump_com_error(e);
     }
    }


© 2009 Microsoft Corporation. All rights reserved. Terms of Use  |  Trademarks  |  Privacy Statement
Microsoft
Page view tracker