InfiniTec - Henning Krauses Blog

Don't adjust your mind - it's reality that is malfunctioning

Setting the Homepage of an Exchange folder using the EWS Managed API

A while ago, Glen posted an article on his blog on how to set homepage of a folder using ADO and later he posted a version of that script which uses the EWS managed API to do this in this MSDN forum thread. However, he wrote it for the first version of the API, and the EWS Managed API 1.1 has a slightly different object model. Since someone on the MSDN forums had difficulties to update the script to work with the EWS Managed API 1.1, I thought I just post an updated version here:

private static void SetFolderHomePage(IEnumerable<string> pathFragments, string url, ExchangeService service)
{
    var folderWebviewinfoProperty = new ExtendedPropertyDefinition(14047, MapiPropertyType.Binary);
    var root = Folder.Bind(service, WellKnownFolderName.MsgFolderRoot);
    var targetFolder = root;
    foreach (var fragment in pathFragments)
    {
        var result = service.FindFolders(targetFolder.Id, new SearchFilter.IsEqualTo(FolderSchema.DisplayName, fragment), new FolderView(1));
        if (result.TotalCount == 0)
        {
            throw new InvalidOperationException(string.Format("Folder fragment {0} was not found.", fragment));
        }
        targetFolder = result.Folders[0];
    }

    targetFolder.SetExtendedProperty(folderWebviewinfoProperty, EncodeUrl(url));
    targetFolder.Update();
}

private static byte[] EncodeUrl(string url)
{
    var writer = new StringWriter();
    var dataSize = ((ConvertToHex(url).Length / 2) + 2).ToString("X2");

    writer.Write("02"); // Version
    writer.Write("00000001"); // Type
    writer.Write("00000001"); // Flags
    writer.Write("00000000000000000000000000000000000000000000000000000000"); // unused
    writer.Write("000000");
    writer.Write(dataSize);
    writer.Write("000000");
    writer.Write(ConvertToHex(url));
    writer.Write("0000");
    
    var buffer = HexStringToByteArray(writer.ToString());
    return buffer;
}

private static string ConvertToHex(string input)
{
    return string.Join(string.Empty, input.Select(c => ((int) c).ToString("x2") + "00").ToArray());
}

private static byte[] HexStringToByteArray(string input)
{
    return Enumerable
        .Range(0, input.Length/2)
        .Select(index => byte.Parse(input.Substring(index*2, 2), NumberStyles.AllowHexSpecifier)).ToArray();
}

You can set the homepage of a folder by calling the SetFolderHomepage method:

SetFolderHomePage(service, new[] {"InfiniTec blog"}, http://www.infinitec.de);

Posted by Henning Krause on Wednesday, October 5, 2011 7:30 PM, last modified on Wednesday, October 5, 2011 7:34 PM
Permalink | Post RSSRSS comment feed

Saving custom data on Exchange elements with The Exchange WebServices

The database used by Exchange is quite a versatile one. A developer can save custom data on each item by creating additional properties.

Generally, there are two types of identification for a property: Either, a property id used (for example PR_ENTRYID which has an id of 0x0fff) or a name. Additionally, some properties live in so called property sets, like most of the task fields. There are some predefined property sets, but a developer can choose to create his own. Since property sets are identified by a GUID, it is rather unlikely that two developers select a property set which collide with each other. In addition to the property name, a property also has a data type. The valid types are defined in the MapiPropertyTypeType enumeration.

One property set is of particular interest, namely the one called PublicStrings. All custom properties created with Outlook are stored in this set. If a custom property is designed to be used by custom Outlook formulas, the developer must choose this property set. In any other case, it is better to create a random GUID and use that property set to prevent collisions with other applications.

So, how are these properties accessed? The answer can be found in the PathToExtendedFieldType. The following code reads the custom Outlook property “CustomOutlookProperty”, which has a data type of string from a given item:

   1: public void GetRequest(ItemIdType itemId)
   2: {
   3:     using (var binding = CreateEwsBinding())
   4:     {
   5:         var customOutlookPropertyPath = new PathToExtendedFieldType
   6:             {
   7:                 DistinguishedPropertySetId = DistinguishedPropertySetType.PublicStrings,
   8:                 DistinguishedPropertySetIdSpecified = true,
   9:                 PropertyName = "CustomOutlookProperty",
  10:                 PropertyType = MapiPropertyTypeType.String
  11:             };
  12:         var request = new GetItemType
  13:               {
  14:                   ItemIds = new[] {itemId},
  15:                   ItemShape = new ItemResponseShapeType
  16:                     {
  17:                         AdditionalProperties = new[]
  18:                                {
  19:                                    customOutlookPropertyPath
  20:                                }
  21:                     }
  22:               };
  23:  
  24:         var response = binding.GetItem(request);
  25:  
  26:         // Need to check response for errors. Ommited for clarity
  27:  
  28:         var item = ((ItemInfoResponseMessageType) response.ResponseMessages.Items[0]).Items.Items[0];
  29:         var customOutlookPropertyValue =
  30:             (from extendedProperty in item.ExtendedProperty
  31:              where
  32:                  extendedProperty.ExtendedFieldURI.DistinguishedPropertySetId == DistinguishedPropertySetType.PublicStrings &&
  33:                  extendedProperty.ExtendedFieldURI.PropertyName == "CustomOutlookProperty"
  34:              select (string) extendedProperty.Item).FirstOrDefault();
  35:     }
  36: }

The important thing happens in lines 5 through 11. Theses lines define the path to the custom outlook property.

If you want to access a custom property that should not be directly available via Outlook, create a custom GUID for your application. For this example, I use this code:

   1: private static readonly Guid PrivatePropertySetId = new Guid("9C24B417-DDC1-4F5F-974D-E35FCF6E9FE2");

Then, replace the lines 5 through 11 with this code:

   1: var customOutlookPropertyPath = new PathToExtendedFieldType
   2:     {
   3:         PropertySetId = PrivatePropertySetId.ToString(),
   4:         PropertyName = "CustomProperty",
   5:         PropertyType = MapiPropertyTypeType.String
   6:     };

To extract the property from the response, use this snippet:

   1: var item = ((ItemInfoResponseMessageType) response.ResponseMessages.Items[0]).Items.Items[0];
   2: var customPropertyValue =
   3:     (from extendedProperty in item.ExtendedProperty
   4:      where
   5:         PrivatePropertySetId.ToString().Equals(extendedProperty.ExtendedFieldURI.PropertySetId, StringComparison.OrdinalIgnoreCase) &&
   6:          extendedProperty.ExtendedFieldURI.PropertyName == "CustomProperty"))
   7:      select (string) extendedProperty.Item).FirstOrDefault();

Note, that I used the the Equals method along with the comparison mode OrdinalIgnoreCase to compare the two property set ids.


Posted by Henning Krause on Friday, March 27, 2009 6:12 PM, last modified on Monday, November 29, 2010 8:30 PM
Permalink | Post RSSRSS comment feed

100% CPU-Auslastung durch den CSRSS Prozess, und Untermenüs öffnen erst nach einigen Sekunden

Affected products

  • Windows 2003
  • Tweak UI for Windows XP/2003
Symptoms
The CSRSS process consumes about 100% of the cpu under certain circumstances, such as opening an Outlook mail folder. Additionally, cascading menus open only with a significant delay.

Solution

One possible cause for this is the Tweak UI tool from Microsoft. This tool exposes a bug in that it sets the MenuShowDelay to zero. In fact, the lowest valid value for this setting is one. To correct this, follow these steps:
  1. Open the registry editor.
  2. Navigate to the HKEY_CURRENT_USER\Control Panel\Desktop node.
  3. Double-Click the MenuShowDelay entry.
  4. Set the value of this entry to 1.
  5. Close the registry editor.
    The changes are loaded the next time you log on to your computer.

More informations

The Tweak-UI tool from Microsoft is a tool to configure several aspects of the user interface from Windows. One of these settings is the delay for cascading menus.

Status

The status of this problem is unknown.

Posted by Henning Krause on Friday, December 31, 2004 2:49 PM, last modified on Friday, December 31, 2004 2:49 PM
Permalink | Post RSSRSS comment feed

Regain access to blocked atachments in Outlook XP

Affected products

  • Microsoft Outlook XP
  • Microsoft Outlook 2003

Summary

This article describes how Outlook XP can be configured, so that it no longer blocks access to attachments certain file types such as .exe.

Description

Since Outlook 200 SP 2, outlook blocks access to attachment of certain file type such as executables or scripts.
There are two types of blocks: The level one files are completely blocked, so that no access is possible, albeit they are not deleted by Outlook. The level 2 files are blocked in that way, that the user can not open them directly. They must be saved to disk before an access is possible.
Outlook XP can now be configured so that level one filetypes can be transformed to level two files..

SOLUTION

To change the behavior of Outlook, the following steps are necessary:
  1. Open the registry editor.
  2. If you are using Outlook XP, navigate to the key HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\10.0\Outlook\Security.Under Outlook 2003, navigate to the key HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\11.0\Outlook\Security.
  3. Create a new value of type String named Level1Remove.
  4. Open the value and enter a semicolon separated list. For example:
    .exe;.ppt;.url;
    After Outlook has been restarted, the access to the attachments is no longer blocked.

Status

This behavior is by design.

Posted by Henning Krause on Friday, December 31, 2004 2:09 PM, last modified on Friday, December 31, 2004 2:27 PM
Permalink | Post RSSRSS comment feed

Render HTML emails as plain text in Outlook

Affected products

Summary

This article describes the products listed in the beginning of this article can be configured so that they render HTML emails as plain text.

Description

HTML email are simply complete web pages that are sent by mail. These mails can contain images (so called web bugs) that can be used to track who reads the sent mail. This way, spammer can verify if your email account is an active one, so they can send you more unsolicited mails. On the other hand, HTML emails can contain embedded script code that may be harmful to your computer.
The affected programmed can now be configured so that they render HTML emails as plain text.

Solution

  1. To change the behavior of Outlook, the following steps are necessary:
  2. Open the registry editor.
  3. If you are using Outlook XP, navigate to the key HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\10.0\Outlook\Options\Mail.
  4. Create a new value of type DWord called ReadAsPlain.
  5. Set the value to 1.
  6. After Outlook has been restarted, all HTML emails are now rendered as plain text.

Status

This behavior is by design.

Posted by Henning Krause on Friday, December 31, 2004 2:03 PM, last modified on Monday, November 29, 2010 9:31 PM
Permalink | Post RSSRSS comment feed