In case you have FIPS compliance enabled and you are building VSTO/Windows applications using Visual Studio 2010 then you will get exception as mentioned below:
Error 1 Source file 'c:\users\brijs\documents\visual studio 2010\Projects\OutlookAddInFIPS\OutlookAddInFPIS\ThisAddIn.cs' could not be opened ('This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms.') OutlookAddInFIPS
Error 1 Source file 'c:\users\brijs\documents\visual studio 2010\Projects\WindowsFormsApplicationFIPS\WindowsFormsApplicationFIPS\Form1.cs' could not be opened ('This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms.') WindowsFormsApplicationFIPS To know more about FIPS refer The effects of enabling the "System cryptography: Use FIPS compliant algorithms for encryption, hashing, and signing" security setting in Windows XP and in later versions of Windows
In order to enable FIPS you need to follow steps mentioned below
After you enable or disable the System cryptography: Use FIPS compliant algorithms for encryption, hashing, and signing security setting, you must restart your application, such as Internet Explorer, for the new setting to take effect.
To workaround the above issue you can either opt out of FIPS compliance by changing the registry as mentioned above.
Or In order to just avoid the issue with Visual Studio 2010 one can follow the steps mentioned below:
enforceFIPSPolicy is a .Net 2.0 SP1 config file switch which helps the application to opt out FIPS checking.
Hope this helps!!!
On Outlook 2007 or previous version for the Outlook we can refer to the public folder as below:
Set olns =Item. Application.GetNamespace("MAPI")
Set pub = olns.Folders("Public Folders")
However, the above given code snippet would fail on Outlook 2010 by throwing exception "Run-time error -2147221233 (8004010f) The attempted operation failed. An object could not be found" because with Outlook 2010.
We have an option to configure multiple exchange account in the same profile and Outlook appends the user's SMTP address used to configure the account to the mailbox/public folder store name to identify each of the account and Outlook would show/refer to the mailbox/public folder as shown in image below.
Here is the sample code snippet in VBA to get reference to Public Folder Store using Outlook Object Model for Outlook 2010:
'NOTE: Following programming examples is for illustration only, without warranty either expressed or implied, including, but not limited to, the implied warranties of merchantability and/or fitness for a particular purpose.
'This sample code assumes that you are familiar with the programming language being demonstrated and the tools used to create and debug procedures. This sample code is provided for the purpose of illustration only and is not intended to be used in a production environment.
<SAMPLE CODE>
If InStr(Item.Application.Version, "14") Then
Set accs = olns.Accounts
For Each Account In accs
If Account.AccountType = olExchange And Account.SmtpAddress = olns.Session.DefaultStore Then
Set pub = olns.Folders("Public Folders" & " - " & Account.SmtpAddress)
MsgBox "Got the Pub folders"
End If
Next
If pub Is Nothing Then
MsgBox "No Public Folder store found for the default exchange mailbox"
</SAMPLE CODE>
Hope this helps!!! Feel free to ask questions related to Outlook/Exchange development.
If you are getting "There was an error during installation. Value does not fall within the expected range." error along with following exception:
************** Exception Text **************System.ArgumentException: Value does not fall within the expected range.at Microsoft.VisualStudio.Tools.Applications.Deployment.ClickOnceAddInDeploymentManager.GetManifests(TimeSpan timeout)at Microsoft.VisualStudio.Tools.Applications.Deployment.ClickOnceAddInDeploymentManager.InstallAddIn()
and getting prompt as displayed below:
Please make sure that, We are not using special character like "&" in the manufacturer property of the VSTO 3.0 Add-in MSI setup project.
In the above scenario we have Manufacturer Property value as “ABC & XYZ Inc” and we are getting exception as mentioned above when we start Outlook 2007 after installing add-in.
We can easily see from the snapshot that VSTO runtime is escaping "&" from the file path.
However, if we remove “&” from the Manufacturer Property value as “ABC XYZ Inc” add-in get installed and loaded as expected.
So, We should not use special character in the Manufacturer Property for VSTO 3.0 Add-ins MSI setup to workaround this bug.
One of my customer requested for some guidance for How to convert Exchange Item’s EntryID to EWS unique ItemId via EWS Managed API’s ConvertId call?
Here is the sample code snippet for converting Exchange Item’s EntryID to EWS unique ItemId via Exchange Web Services Managed API’s ConvertId call:
/*NOTE: Following programming examples is for illustration only, without warranty either expressed or implied, including, but not limited to, the implied warranties of merchantability and/or fitness for a particular purpose. This sample code assumes that you are familiar with the programming language being demonstrated and the tools used to create and debug procedures. This sample code is provided for the purpose of illustration only and is not intended to be used in a production environment.*/ //Call the GetConvertedEWSID to convert Item’s EntryID to EWSID String sEntryID = "AAAAN0ybz+zO+JOhV4pGimkcYQHAAtH+9AAFtlUAAA=="; String sEWSID = GetConvertedEWSID(service,sEntryID, "TestEx2010@BrijEx2010.com"); MessageBox.Show(sEWSID); //Pass ExchaneService, ItemEntryID and SMTP address of parent Mailbox of Item as Parameters private String GetConvertedEWSID(ExchangeService esb,String sID,String strSMTPAdd) { // Create a request to convert identifiers. AlternateId objAltID = new AlternateId(); objAltID.Format = IdFormat.EntryId; objAltID.Mailbox = strSMTPAdd; objAltID.UniqueId = sID; //Convert PR_ENTRYID identifier format to an EWS identifier. AlternateIdBase objAltIDBase = esb.ConvertId(objAltID , IdFormat.EwsId); AlternateId objAltIDResp = (AlternateId)objAltIDBase; return objAltIDResp.UniqueId; }
Here is EWS SOAP Request and Response for the ConvertId call:
EwsRequest --- <EwsLogEntry EntryKind="EwsRequest" ThreadId="8" Timestamp="9/10/2010 4:26:22 AM"> <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Header> <t:RequestServerVersion Version="Exchange2010" /> </soap:Header> <soap:Body> <m:ConvertId DestinationFormat="EwsId"> <m:SourceIds> <t:AlternateId Format="EntryId" Id="AAAAN0ybz+zO+JOhV4pGimkcYQHAAtH+9AAFtlUAAA==" Mailbox="TestEx2010@BrijEx2010.com" /> </m:SourceIds> </m:ConvertId> </soap:Body> </soap:Envelope> </EwsLogEntry>
EwsResponseHttpHeaders --- <EwsLogEntry EntryKind="EwsResponseHttpHeaders" ThreadId="8" Timestamp="9/10/2010 4:26:32 AM">200 OK Transfer-Encoding: chunked Content-Encoding: gzip Vary: Accept-Encoding X-EwsPerformanceData: RpcC=0;RpcL=0;LdapC=0;LdapL=0; Persistent-Auth: true Cache-Control: private Content-Type: text/xml; charset=utf-8 Date: Thu, 09 Sep 2010 22:56:32 GMT Server: Microsoft-IIS/7.5 X-AspNet-Version: 2.0.50727 X-Powered-By: ASP.NET
</EwsLogEntry>
EwsResponse --- <EwsLogEntry EntryKind="EwsResponse" ThreadId="8" Timestamp="9/10/2010 4:26:32 AM"> <?xml version="1.0" encoding="utf-8"?> <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Header> <h:ServerVersionInfo MajorVersion="14" MinorVersion="0" MajorBuildNumber="639" MinorBuildNumber="21" Version="Exchange2010" xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types" xmlns="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" /> </s:Header> <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <m:ConvertIdResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"> <m:ResponseMessages> <m:ConvertIdResponseMessage ResponseClass="Success"> <m:ResponseCode>NoError</m:ResponseCode> <m:AlternateId xsi:type="t:AlternateIdType" Format="EwsId" Id="AAMkADM0MDhiYjI5LTY1YjktNGNjOS04ZjdmLWZhZTlmNzdiNjllOQBGAAAAAADdMVg7cuSIleOBbZVAAA=" Mailbox="TestEx2010@brijex2010.com" /> </m:ConvertIdResponseMessage> </m:ResponseMessages> </m:ConvertIdResponse> </s:Body> </s:Envelope> </EwsLogEntry>
For reference:
We are getting following exception after migrating Outlook 2007 VSTO add-in project to Visual Studio 2010 and targeting it to .Net 4.0 Framework for Outlook 2010: Inheritance security rules violated by type: 'VS2008_FR_OLAddIn.ThisAddIn'. Derived types must either match the security accessibility of the base type or be less accessible.
************** Exception Text **************
System.TypeLoadException: Inheritance security rules violated by type: 'VS2008_FR_OLAddIn.ThisAddIn'. Derived types must either match the security accessibility of the base type or be less accessible.
at System.Reflection.RuntimeAssembly.GetType(RuntimeAssembly assembly, String name, Boolean throwOnError, Boolean ignoreCase, ObjectHandleOnStack type)
at System.Reflection.RuntimeAssembly.GetType(String name, Boolean throwOnError, Boolean ignoreCase)
at Microsoft.VisualStudio.Tools.Office.Runtime.DomainCreator.ExecuteCustomization.CreateEntryPoint(String entryPointTypeName)
at Microsoft.VisualStudio.Tools.Office.Runtime.DomainCreator.ExecuteCustomization.Microsoft.VisualStudio.Tools.Office.Runtime.Interop.IExecuteCustomization2.LoadEntryPoints(IntPtr serviceProvider)
The above issue is happening in case if we upgrade an Office project from Visual Studio 2008. In this case, you must remove the SecurityTransparentAttribute.
Visual Studio does not automatically remove these attributes when the target framework is changed.
StepsTo remove the SecurityTransparentAttribute
For more detail refer @ Removing Obsolete Attributes from Office Projects that You Migrate to the .NET Framework 4.
We would also need to keep in consideration Required Changes to Run Office Projects that You Migrate to the .NET Framework 4 to avoid other issue.
If you are doing devolvement for Exchange Server 2007 using Exchange Web Services(EWS) then here’s news for you:
The Microsoft Exchange Web Services (EWS) Managed API 1.0 Beta is available to download @ Exchange Web Services Managed API Beta
The Microsoft Exchange Web Services (EWS) Managed API 1.0 Beta provides a managed interface for developing client applications that use Exchange Web Services. The EWS Managed API simplifies the implementation of applications that communicate with Microsoft Exchange Server 2007 Service Pack 1 (SP1) and later versions of Microsoft Exchange. Built on the Exchange Web Services SOAP protocol and Autodiscover, the EWS Managed API provides a .NET interface to EWS that is easy to learn, use, and maintain.
If you would like to know more about EWS Managed API then have look @ Exchange Web Services Managed API video.
You can also refer to Introducing the Exchange Web Services Managed API 1.0 and Microsoft Exchange Web Services Managed API 1.0 Beta SDK April 2009 which contains:
We encourage you to download Exchange Web Services Managed API and use it for Exchange Server 2007 related development.
Microsoft Office 2010 RTM is announced @ Office 2010 Reaches RTM! and now available for download by MSDN, Technet subscribers. While you won't get it on retail shelves just yet, Microsoft has made available the Office 2010 switch on MSDN and Technet. Both 32 and 64-bit downloads are now available to download. If you're a subscriber, Go on to your downloads page and grab the final builds! Microsoft will officially launch Office 2010 to our business customers on May 12 with Stephen Elop, President of Microsoft’s Business Division, delivering a keynote as part of our virtual launch. Our virtual launch will allow people from around the globe to participate in our launch by going to http://www.the2010event.com. The virtual launch site will showcase product demos, customer and partner testimonials, and interviews with product managers and executives, and we hope this will give you another great way to explore, learn, and get excited about the 2010 releases. But if you are not a subscriber, than Office 2010 will first become available in retail stores in June in the US, and customers can pre-order these retail versions of Office 2010 at http://store.microsoft.com/OfficePreorder today to receive Office when it becomes available. So, What are you waiting for? Go ahead and enjoy Office 2010!!!
Microsoft Office 2010 RTM is announced @ Office 2010 Reaches RTM! and now available for download by MSDN, Technet subscribers.
While you won't get it on retail shelves just yet, Microsoft has made available the Office 2010 switch on MSDN and Technet.
Both 32 and 64-bit downloads are now available to download.
If you're a subscriber, Go on to your downloads page and grab the final builds!
Microsoft will officially launch Office 2010 to our business customers on May 12 with Stephen Elop, President of Microsoft’s Business Division, delivering a keynote as part of our virtual launch. Our virtual launch will allow people from around the globe to participate in our launch by going to http://www.the2010event.com. The virtual launch site will showcase product demos, customer and partner testimonials, and interviews with product managers and executives, and we hope this will give you another great way to explore, learn, and get excited about the 2010 releases.
But if you are not a subscriber, than Office 2010 will first become available in retail stores in June in the US, and customers can pre-order these retail versions of Office 2010 at http://store.microsoft.com/OfficePreorder today to receive Office when it becomes available.
So, What are you waiting for? Go ahead and enjoy Office 2010!!!
Update Rollup 4 for Exchange Server 2010 RTM (KB 982639) is now available to download and install.
KB 982639 lists all the fixes included in this rollup. Here are some of the product improvements and critical bug fixes.
Here are the few of fixes, I would like to highlight as Exchange Developer perspective:
KB 982639 has more details about this release and a complete list of all fixes included in this worthwhile rollup.
To download and to install Update Rollup 4 for Exchange Server 2010 RTM, visit the following Microsoft Update Website: http://update.microsoft.com
Note Microsoft Update does not detect Update rollups on Exchange Server 2010 Mailbox servers that are part of a database availability group (DAG). You may want to deploy Update Rollup 4 for Exchange Server 2010 RTM to multiple computers that are running Exchange Server 2010 RTM. Or, you may want to deploy Update Rollup 4 for Exchange Server 2010 RTM to Mailbox servers that are part of a database availability group (DAG). The update rollup is also available from the Microsoft Download Center. The following file is available for download from the Microsoft Download Center: Download the Exchange2010-KB982639-EN-x64 package now.
It does seem to be a bit of a dearth of VB.net samples for Exchange Web Service. So here is a sample Vb.net code which demonstrates:
NOTE: Following programming examples is for illustration only, without warranty either expressed or implied, including, but not limited to, the implied warranties of merchantability and/or fitness for a particular purpose. This sample code assumes that you are familiar with the programming language being demonstrated and the tools used to create and debug procedures. This sample code is provided for the purpose of illustration only and is not intended to be used in a production environment.
'List all the items from the inbox folder
Private Function ListFolderItems(ByRef esb As ExchangeServiceBinding) As List(Of MessageType)
Dim Messages As New List(Of MessageType)
Messages = Nothing
' Form the FindItem request
Dim findRequest As FindItemType = New FindItemType()
findRequest.Traversal = ItemQueryTraversalType.Shallow
' Define which item properties are returned in the response
Dim itemProperties As ItemResponseShapeType = New ItemResponseShapeType()
itemProperties.BaseShape = DefaultShapeNamesType.AllProperties
' Add properties shape to request
findRequest.ItemShape = itemProperties
' Identify which folders to search to find items
Dim folderIDArray() As DistinguishedFolderIdType = New DistinguishedFolderIdType(1) {}
folderIDArray(0) = New DistinguishedFolderIdType()
folderIDArray(0).Id = DistinguishedFolderIdNameType.inbox
' Add folders to request
findRequest.ParentFolderIds = folderIDArray
'Send the listing (find) request and get the response
Dim findResp As New FindItemResponseType
findResp = esb.FindItem(findRequest)
' Get the response messages
Dim responseMessage As ResponseMessageType
For Each responseMessage In findResp.ResponseMessages.Items
' Cast to the correct response message type
Dim findItemResponseMessage As FindItemResponseMessageType = responseMessage
If findItemResponseMessage.ResponseClass = ResponseClassType.Success Then
' Get the actual payload of items
Dim realItems As ArrayOfRealItemsType = findItemResponseMessage.RootFolder.Item
If Not realItems.Items Is Nothing Then
' Initialize list of messages and fill
Messages = New List(Of MessageType)(realItems.Items.Length)
Dim message As MessageType = Nothing
Dim item As ItemType = Nothing
For Each item In realItems.Items
If TypeOf item Is MessageType Then
message = item
Messages.Add(message)
Return Messages
End Function
'To get a specific item based on ItemId
Public Shared Function GetItem(ByVal serviceBinding As ExchangeServiceBinding, ByVal itemID As String) As ItemType
' Form the GetItem request
Dim getRequest As GetItemType = New GetItemType()
getRequest.ItemShape = itemProperties
' Set the itemID of the desired item to retrieve
Dim id As ItemIdType = New ItemIdType()
id.Id = itemID
getRequest.ItemIds = New ItemIdType() {id}
' Send the listing (find) request and get the response
Dim getResp As New GetItemResponseType
getResp = serviceBinding.GetItem(getRequest)
' Get the response message
If getResp.ResponseMessages.Items(0).ResponseClass = ResponseClassType.Success Then
Dim iirmt As ItemInfoResponseMessageType = getResp.ResponseMessages.Items(0)
If iirmt.Items.Items.Length > 0 Then
Return iirmt.Items.Items(0)
Else
Return Nothing
Here are the few link related to EWS for basis understanding :
Please share you comments or questions with me related to subjects on my blog. I would like to explore the messaging world further with you...
To determine the current installed version of PowerShell; in PowerShell type the following built in variable : $PSVersionTable.
If we use Get-Host it will just shows you the version of the host (i.e. of Console.Exe) as below:
The only available recurrence patterns to set from OOM are as below:
olRecursDaily = 0,
olRecursWeekly = 1,
olRecursMonthly = 2,
olRecursMonthNth = 3,
olRecursYearly = 5,
and olRecursYearNth = 6.
Though we can set every weekday recurrence pattern using UI, Outlook object model does not expose any method to create the pattern as Every Weekday.
So, We could use "DayOfWeekMask" to workaround the issue; We found that the mask value is set to 62 on item when we set the recurrence pattern as Every Weekday through Outlook UI [Daily] -> [Every weekday].
Here is the sample code snippet in VBA and C# to workaround the issue:
NOTE: Following programming examples is for illustration only, without warranty either expressed or implied, including, but not limited to, the implied warranties of merchantability and/or fitness for a particular purpose. This sample code assumes that you are familiar with the programming language being demonstrated and the tools used to create and debug procedures.
SAMPLE CODE I (VBA):
1: Sub CreateTestAppointment()
2: Dim myOlApp As Outlook.Application
3: Dim myItem As Outlook.AppointmentItem
4: Dim myPattern As Outlook.RecurrencePattern
5: Set myOlApp = CreateObject("Outlook.Application")
6: Set myItem = myOlApp.CreateItem(olAppointmentItem)
7: Set myPattern = myItem.GetRecurrencePattern
8: myPattern.RecurrenceType = 1
9: myPattern.DayOfWeekMask = 62
10: myPattern.StartTime = "12:00 pm" 'Time each appointment begins
11: myPattern.EndTime = "1:00 pm" 'Time each appointment ends
12: myPattern.PatternStartDate = #7/1/2009# 'Earliest date appt can Occur
13: myPattern.PatternEndDate = #9/2/2009# 'Latest date appt can occur
14:
15: myItem.Subject = "TestAppointment"
16: myItem.Save
17: myItem.Display
18: End Sub
SAMPLE CODE II (C#):
1: try
2: {
3: Outlook.Application oApp =(Outlook.Application) new Outlook.Application();
4: Outlook.AppointmentItem newAppointment =(Outlook.AppointmentItem) oApp.CreateItem(Outlook.OlItemType.olAppointmentItem);
5: Outlook.RecurrencePattern oRecurr = newAppointment.GetRecurrencePattern() ;
6:
7: oRecurr.RecurrenceType = Outlook.OlRecurrenceType.olRecursWeekly;
8: oRecurr.DayOfWeekMask = (Outlook.OlDaysOfWeek)62;
9: oRecurr.StartTime = DateTime.Now.AddHours(2);
10: oRecurr.EndTime = DateTime.Now.AddHours(3);
11: oRecurr.PatternStartDate = DateTime.Now.Date;
12: oRecurr.PatternEndDate = DateTime.Now.Date.AddDays(3);
13:
14: newAppointment.Body = "Test Appointment";
15: newAppointment.AllDayEvent = false;
16: newAppointment.Subject = "Test Appointment";
17: newAppointment.Save();
18: newAppointment.Display(true);
19: }
20: catch (Exception ex)
21: {
22: MessageBox.Show("The following error occurred: " + ex.Message);
23: }
References:
Hope this helps.
We can enable error logging and displaying of error message for the VSTO add-in by setting environment variables VSTO_SUPPRESSDISPLAYALERTS and VSTO_LOGALERTS.
To display each error in a message box, set the VSTO_SUPPRESSDISPLAYALERTS variable to 0 (zero). You can suppress the messages by setting the variable to 1 (one). To write the errors to a log file, set the VSTO_LOGALERTS variable to 1 (one). Visual Studio Tools for Office creates the log file in the folder that contains the application manifest. The default name is <Manifestname>.manifest.log.
We can refer to the article mentioned below:
Visual Studio Tools for the Microsoft Office System : Debugging in Application-Level Projects http://msdn.microsoft.com/en-us/library/ms269003(VS.80).aspx
Starting in Visual Studio 2008 Service Pack 1 (SP1), you can use the event viewer in Windows to see error messages that are captured by the Visual Studio Tools for Office runtime when you install or uninstall Visual Studio Tools for Office solutions. You can use these messages from the event logger to resolve installation and deployment problems.
You can enable the event logger by setting the VSTO_EVENTLOGDISABLED environment variable to "0".
Microsoft Visual Studio Tools for the Microsoft Office system (version 3.0): Event Logging (2007 System)http://msdn.microsoft.com/en-us/library/cc442816.aspx
We can also use AddinSpy to gather information for troubleshooting
Using AddinSpy and AS Diagnostic Tools for Microsoft Office Add-inshttp://msdn.microsoft.com/en-us/library/cc984533.aspx
We can also use VSTO Troubleshooter which is part of VSTO Power Tools. It is a diagnostic tool that examines a computer looking for the necessary prerequisites for running Visual Studio Tools for Office solutions.
Microsoft Visual Studio Tools for the Office System Power Tools v1.0.0.0http://www.microsoft.com/downloads/details.aspx?FamilyId=46B6BF86-E35D-4870-B214-4D7B72B02BF9&displaylang=en
We can also have look at some troubleshooting techniques posted by my colleagues:
Dave @ http://blogs.msdn.com/dvespa/archive/2008/09/30/troubleshooting-outlook-com-addins-introduction.aspx
Praveen @ http://blogs.msdn.com/vsod/archive/2008/04/22/Troubleshooting-com-add-in-load-failures.aspx
How to capture whether user has checked to send Outlook Mail with digital signature or encrypted from VSTO Add-in in C# ?
We can use the following code snippet with VSTO SE Outlook Skeleton project to build sample add-in:
IMPORTANT NOTE: This add-in will only work if we are NOT using Word as default email editor.
/*NOTE: Following programming examples is for illustration only, without warranty either expressed or implied, including, but not limited to, the implied warranties of merchantability and/or fitness for a particular purpose. This sample code assumes that you are familiar with the programming language being demonstrated and the tools usedto create and debug procedures.*/
1: using System;
2: using System.Windows.Forms;
3: using Microsoft.VisualStudio.Tools.Applications.Runtime;
4: using Outlook = Microsoft.Office.Interop.Outlook;
5: using Office = Microsoft.Office.Core;
7: namespace OutlookAddin1
8: {
9: public partial class ThisApplication
10: {
11: private void ThisApplication_Startup(object sender, System.EventArgs e)
12: {
13: this.ItemSend +=new Microsoft.Office.Interop.Outlook.ApplicationEvents_11_ItemSendEventHandler(ThisApplication_ItemSend);
14: }
15:
16: private void ThisApplication_Shutdown(object sender, System.EventArgs e)
17: {
18: }
19: private Office.CommandBarButton EncButton = null;
20: private Office.CommandBarButton DigButton = null;
21: private void ThisApplication_ItemSend(object Item, ref bool Cancel)
22: {
23: Outlook.MailItem mItem = null;
24:
25: try
26: {
27: mItem = Item as Outlook.MailItem;
28:
29: EncButton = (Office.CommandBarButton) mItem.GetInspector.CommandBars.FindControl(Office.MsoControlType.msoControlButton , 718, Type.Missing, true);
30: if (EncButton.State == Office.MsoButtonState.msoButtonDown )
31: {
32: MessageBox.Show ("Mail will be Encrypted");
33: }
34:
35: DigButton = (Office.CommandBarButton)mItem.GetInspector.CommandBars.FindControl(Office.MsoControlType.msoControlButton, 719, Type.Missing, true);
36: if (DigButton.State == Office.MsoButtonState.msoButtonDown)
37: {
38: MessageBox.Show ("Mail will be Digitally signed");
39: }
40:
41: }
42: catch (Exception ex)
43: {
44: System.Windows.Forms.MessageBox.Show(ex.Message);
45: Cancel = true;
46: }
47:
48: }
49: #region VSTO generated code
50:
51: /// <summary>
52: /// Required method for Designer support - do not modify
53: /// the contents of this method with the code editor.
54: /// </summary>
55: private void InternalStartup()
56: {
57: this.Startup += new System.EventHandler(ThisApplication_Startup);
58: this.Shutdown += new System.EventHandler(ThisApplication_Shutdown);
59: }
60:
61: #endregion
62: }
63: }
Please refer to following article related to working with CommandBars in Outlook Solution:
How to Use CommandBars in Outlook Solutions http://support.microsoft.com/kb/201095
The above article also have a Microsoft Excel Macro to generate a list of Outlook 2000/2003 CommandBar control IDs.
One of my customer would like to send Excel 2007 worksheet contents as email using CDOSYS. We are facing issues regarding formatting of the contents in the resultant emails on the different email clients. Then we decided to send contents as PDF attachment to avoid such issues.
Here is the sample code VBA snippet used:
Sub SendMail()
Dim filepath As String
filepath = "\\server\test\Excel 2007 Chart.pdf" 'TODO:change filepath for the temp pdf file
'Exporting range of the excel contents which need to sent out
Range("A1:I22").Select
Selection.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
filepath, _
Quality:=xlQualityStandard, IncludeDocProperties:=False, IgnorePrintAreas _
:=False, OpenAfterPublish:=False
'Setting up CDOSYS configuration to send out the email
Set iMsg = CreateObject("CDO.Message")
Set iConf = CreateObject("CDO.Configuration")
Set Flds = iConf.Fields
With Flds
.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2 'send via port
.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "ServerName" 'TODO:update the SMTP server name here
.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
.Update
End With
With iMsg
Set .Configuration = iConf
.From = "xyz@domain.com" 'TODO:change email address here
.To = "abc@domain.com" 'TODO:change email address here
.Subject = "Test message with PDF Attachment"
.HTMLBody = "Please find the attache excel pdf contents report"
.AddAttachment (filepath)
.Send
Set iMsg = Nothing
Set iConf = Nothing
End Sub
Please feel free to write me if you have question related to Microsoft Messaging APIs.
“What is the best way to deploy VSTO add-ins for Outlook?” This is one of the most common question asked by our customers who are developing add-ins using Visual Studio Tools for Office(VSTO) for Outlook and other Office Applications. Simple answer is that it’s all depend on you requirements and environment. We can opt for either ClickOnce Deployment or Windows Installer.
We can refer to Choosing a Deployment Strategy and the following table compares the features of ClickOnce deployment with Windows Installer deployment to make informed decision:
ClickOnce
Windows Installer
Automatic update1
Yes
Post-installation rollback2
No
Update from Web
Does not affect shared components or other applications
Security permissions granted
Grants only permissions necessary for the application (more safe)
Grants Full Trust by default (less safe)
Security permissions required
Internet or Intranet Zone (Full Trust for CD-ROM installation)
Administrator
Application and deployment manifest signing
Installation-time user interface
Single prompt
Multipart Wizard
Installation of assemblies on demand
Installation of shared files
Installation of drivers
Yes (with custom actions)
Installation to Global Assembly Cache
Installation for multiple users
Add application to Start menu
Add application to Startup group
Add application to Favorites menu
Register file types
Install time registry access3
Limited
Binary file patching
Application installation location
ClickOnce application cache
Program Files folder
Notes:
1. With Windows Installer, you must implement programmatic updates in the application code.
2. With ClickOnce, rollback is available in Add or Remove Programs.
3. ClickOnce deployment can access HKEY_LOCAL_MACHINE (HKLM) only with Full Trust permission.
Feel free to put questions related to ClickOnce or Windows Installer deployment for Office Add-ins to me.
We can get/set Extended MAPI Properties using Exchange Web Services for Exchange Server 2007/2010.
Here is sample code snippet to get value for CleanGlobalObjectID via GetItem call of Exchange Web Services:
private void fnGetCalItem()
{
// Form the GetItem request
GetItemType getRequest = new GetItemType();
// Define which item properties are returned in the response
ItemResponseShapeType itemProperties = new ItemResponseShapeType();
itemProperties.BaseShape = DefaultShapeNamesType.AllProperties;
// Add properties shape to request
getRequest.ItemShape = itemProperties;
// Set the itemID of the desired item to retrieve
ItemIdType id = new ItemIdType();
id.Id = itemID;
getRequest.ItemIds = new ItemIdType[] { id };
PathToExtendedFieldType[] pteft = new PathToExtendedFieldType[1];
pteft[0] = new PathToExtendedFieldType();
//Add CleanGlobalObjectID extended property
pteft[0].PropertyId = 35;
pteft[0].PropertyIdSpecified = true;
pteft[0].PropertySetId = "6ED8DA90-450B-101B-98DA-00AA003F1305" ;
pteft[0].PropertyType = MapiPropertyTypeType.Binary;
itemProperties.AdditionalProperties = pteft;
// Send the listing (find) request and get the response
GetItemResponseType getResp = binding.GetItem(getRequest);
// Get the response message
if (getResp.ResponseMessages.Items[0].ResponseClass == ResponseClassType.Success)
ItemInfoResponseMessageType iirmt = getResp.ResponseMessages.Items[0] as ItemInfoResponseMessageType;
itemGCOID = iirmt.Items.Items[0].ExtendedProperty[0].Item.ToString() ;
}
else
Console.WriteLine(getResp.ResponseMessages.Items[0]);
Articles referenced for the above sample code:
Hope this helps!
We can perform GetItem Exchange Web Service call to get Extended MAPI Properties refer my previous post How to get Extended MAPI Properties in the GetItem Exchange Web Service call? and can also perform FindItem based on the Extended MAPI Properties.
In the sample code given below we would use CleanGlobalObjectId to perform FindItem for Calendar Items:
private void SelectRecordByCGOID()
//prepare the find item request: we have to use FindItem because
//this is the only way to search by CleanGlobalObjectID; GetItem does not allow us
//to search with Restrictions
FindItemType findItemRequest = new FindItemType();
DistinguishedFolderIdType[] folderIDArray = new DistinguishedFolderIdType[1];
folderIDArray[0] = new DistinguishedFolderIdType();
folderIDArray[0].Id = DistinguishedFolderIdNameType.calendar;
folderIDArray[0].Mailbox = new EmailAddressType();
folderIDArray[0].Mailbox.EmailAddress = "brijs@msglab.com";
// Add folders to the request.
findItemRequest.ParentFolderIds = folderIDArray;
findItemRequest.Traversal = ItemQueryTraversalType.Shallow;
//Prepare an Item shape type that defines how the items in view will be returned.
ItemResponseShapeType itemShapeDefinition = new ItemResponseShapeType();
itemShapeDefinition.BaseShape = DefaultShapeNamesType.AllProperties ;
//filter the results by the CleanGlobalObjectID passed in
PathToExtendedFieldType path = new PathToExtendedFieldType();
path.PropertyId = 35;
path.PropertyIdSpecified = true;
path.PropertySetId = "6ED8DA90-450B-101B-98DA-00AA003F1305";
path.PropertyType = MapiPropertyTypeType.Binary;
FieldURIOrConstantType constant = new FieldURIOrConstantType();
ConstantValueType constantValue = new ConstantValueType();
constantValue.Value = itemGCOID ;
constant.Item = constantValue;
RestrictionType restriction = new RestrictionType();
IsEqualToType equal = new IsEqualToType();
equal.Item = path;
equal.FieldURIOrConstant = constant;
restriction.Item = equal;
//Add the itemShape definition and restriction to the FindItem request
findItemRequest.ItemShape = itemShapeDefinition;
findItemRequest.Restriction = restriction;
FindItemResponseType findItemResponse = binding.FindItem(findItemRequest);
for (int i = 0; i < findItemResponse.ResponseMessages.Items.Length; i++)
//verify the FindItem request was successfull
if (findItemResponse.ResponseMessages.Items[i].ResponseClass != ResponseClassType.Success)
throw new Exception(string.Format(
"Unable to find calendar view by CleanGlobalObjectID \r\n{0}\r\n{1}",
findItemResponse.ResponseMessages.Items[i].ResponseCode,
findItemResponse.ResponseMessages.Items[i].MessageText));
//Success
//get the calendar items contained in the response
FindItemResponseMessageType findItemResponseMessage = (FindItemResponseMessageType)findItemResponse.ResponseMessages.Items[i];
ArrayOfRealItemsType findItemResponseItems = (ArrayOfRealItemsType)findItemResponseMessage.RootFolder.Item;
for (int x = 0; x < findItemResponseMessage.RootFolder.TotalItemsInView; x++)
if (findItemResponseItems.Items[x] is CalendarItemType)
CalendarItemType calendar = (CalendarItemType)findItemResponseItems.Items[x];
Console.WriteLine( "Item found ");
Console.WriteLine( calendar.Subject);
In continuations of my previous post How to do FindItem and GetItem Operations of Exchange Web Services using VB.net ; Here is the Exchange Web Services sample in VB.net to perform following task:
Private Sub cmdMove_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdMove.Click
Try
If lstMails.SelectedItems.Count = 1 Then
Dim itemID As New ItemIdType
itemID.Id = lstMails.SelectedItems(0).SubItems(3).Text
'Find the folderId to which we want to move item
Dim parentFolder As New DistinguishedFolderIdType
parentFolder.Id = DistinguishedFolderIdNameType.root
Dim tfTargetFolder As New FolderIdType
'Change the name of the folder we are searching for FolderID
tfTargetFolder = FindFolder(ServiceBinding, parentFolder, "Test")
Dim newItemID As New ItemIdType
'Move am Item based on ItemId and FolderID
newItemID = MoveItemtoTest(ServiceBinding, itemID.Id, tfTargetFolder)
Dim strId As String
strId = "New ItemID " + newItemID.Id.ToString
MessageBox.Show(strId, "Item Moved", MessageBoxButtons.OK, MessageBoxIcon.Information)
MessageBox.Show("Please select a item in list to move", "Item to Move", MessageBoxButtons.OK, MessageBoxIcon.Information)
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
Public Shared Function FindFolder(ByVal serviceBinding As ExchangeServiceBinding, ByVal fiFolderID As DistinguishedFolderIdType, ByVal fnFldName As String) As FolderIdType
Dim rvFolderID As New FolderIdType
' Create the request and specify the travesal type
Dim findFolderRequest As FindFolderType = New FindFolderType()
findFolderRequest.Traversal = FolderQueryTraversalType.Deep
' Define the properties returned in the response
Dim responseShape As FolderResponseShapeType = New FolderResponseShapeType()
responseShape.BaseShape = DefaultShapeNamesType.Default
findFolderRequest.FolderShape = responseShape
' Identify which folders to search
folderIDArray(0).Id = fiFolderID.Id
'Add Restriction for DisplayName
Dim ffRestriction As New RestrictionType
Dim ieToType As New IsEqualToType
Dim diDisplayName As New PathToUnindexedFieldType
diDisplayName.FieldURI = UnindexedFieldURIType.folderDisplayName
Dim ciConstantType As New FieldURIOrConstantType
Dim cvConstantValueType As New ConstantValueType
cvConstantValueType.Value = fnFldName
ciConstantType.Item = cvConstantValueType
ieToType.Item = diDisplayName
ieToType.FieldURIOrConstant = ciConstantType
ffRestriction.Item = ieToType
findFolderRequest.Restriction = ffRestriction
' Add the folders to search to the request
findFolderRequest.ParentFolderIds = folderIDArray
' Send the request and get the response
Dim findFolderResponse As FindFolderResponseType = serviceBinding.FindFolder(findFolderRequest)
If findFolderResponse.ResponseMessages.Items(0).ResponseClass = ResponseClassType.Error Then
MessageBox.Show("Error Occured")
MessageBox.Show(findFolderResponse.ResponseMessages.Items(0).MessageText)
Dim rmta() As ResponseMessageType = findFolderResponse.ResponseMessages.Items
Dim rmt As ResponseMessageType
For Each rmt In rmta
Dim ffResponse As FindFolderResponseMessageType = rmt
Dim fFoundFolder As FolderType
For Each fFoundFolder In ffResponse.RootFolder.Folders
rvFolderID = fFoundFolder.FolderId
'MessageBox.Show(fFoundFolder.DisplayName)
'Return the FolderID of the last folder found
Return (rvFolderID)
Catch e As Exception
MessageBox.Show(e.Message)
Public Shared Function MoveItemtoTest(ByVal serviceBinding As ExchangeServiceBinding, ByVal itemID As String, ByVal trgfldID As FolderIdType) As ItemIdType
'Setup FolderId and ItemId to be passed to MoveItem
Dim tfTargetFolder As TargetFolderIdType = New TargetFolderIdType()
tfTargetFolder.Item = trgfldID
Dim iiItemId As ItemIdType = New ItemIdType()
iiItemId.Id = itemID
'Create request to move Item and specify properties
Dim miMoveItemRequest As MoveItemType = New MoveItemType()
miMoveItemRequest.ItemIds = New ItemIdType(1) {}
miMoveItemRequest.ItemIds(0) = iiItemId
miMoveItemRequest.ToFolderId = tfTargetFolder
Dim nID As New ItemIdType
Dim miResponse As MoveItemResponseType = serviceBinding.MoveItem(miMoveItemRequest)
If miResponse.ResponseMessages.Items(0).ResponseClass = ResponseClassType.Error Then
MessageBox.Show(miResponse.ResponseMessages.Items(0).MessageText)
Dim iirmt As ItemInfoResponseMessageType = miResponse.ResponseMessages.Items(0)
'Get updated ItemId from the Response Message
nID = iirmt.Items.Items(0).ItemId
MessageBox.Show("Item Moved")
'Return updated ItemID
Return nID
We can refer to the following articles related to the EWS:
While we can workout more with Exchange Web Service auto generated proxies but don’t forget to have look at Microsoft Exchange Web Services (EWS) Managed API 1.0 to do stuff with less sweat. :)
Office 2007 SP2 is available for download.
The 2007 Microsoft Office Suite Service Pack 2 (SP2) provides customers with the latest updates to the 2007 Office suite (the products that are affected by this update are listed below). This download includes two types of fixes:
Before installing this service pack, you are strongly encouraged to read 953195, which describes some big improvements introduced by SP2, and also calls out some important information that you should be aware of before installing.
For the Outlook 2007 Specific changes in SP2 please refer to the Outlook 2007 improvements in the 2007 Office suite Service Pack 2 article.
You can also download a workbook that contains a list of issues that are fixed by this service pack from the link mentioned below:
Download the 2007 Office Service Pack 2 Changes.xlsx package
Please let us know if you face any Outlook development related issues after upgrading to Office 2007 SP2.
I have recently worked out a VBScript to list delegate of the Outlook Mailbox using CDO 1.2.1 via VBScript and thought of share it with you all, here is the sample code:
Dim objSession
Dim strProfileInfo
Dim strServer
Dim strMailbox
Dim objFolder
Dim objMessages
Dim objMessage
Dim oFields
Dim oField1
Dim oField2
Dim oFBFolder
'TODO:Change Server and Mailbox info
strServer="Server"
strMailbox="User"
strProfileInfo = strServer & vbLf & strMailbox
Set objSession = CreateObject("MAPI.Session")
objSession.Logon , , False, False, , True, strProfileInfo
writelog( "Mailbox")
writelog( " ==> ")
writelog( objSession.CurrentUser)
writelog( vbCrLf)
Msgbox "Logged On!!!"
' Reference the root folder by passing ID of ""
Set oRoot = objSession.GetFolder("")
'Connect to the Freebusy folder
Set oFBFolder = oRoot.Folders.Item("Freebusy Data")
Set objMessages = oFBFolder.Messages
For Each objMessage In objMessages
If objMessage.subject = "LocalFreebusy" Then
'Get the message fields
Set oFields = objMessage.Fields
On Error Resume Next
For i = 0 to UBound(oFields.Item(&H6844101E).Value(0))
Set oField1 = oFields.Item(&H6844101E) ' PR_SCHDINFO_DELEGATE_NAMES
writelog "DELEGATE NAMES ==> " & oField1.Value(0)(i)
Set oField2 = oFields.Item(&H686B1003) ' PR_DELEGATE_FLAGS
writelog "Delegate can see private ==> " & oField2.Value(0)(i)
End iF
objSession.Logoff
Set objSession =Nothing
Set oField1 = Nothing
Set oField2 = Nothing
Set oFBFolder = Nothing
Set oRoot = Nothing
Msgbox "Done!!!"
Sub WriteLog(ByVal strMessage)
Dim fs
Set fs = CreateObject("Scripting.FileSystemObject")
Dim file
Dim sScriptPath
sScriptPath = Left(WScript.ScriptFullName, InstrRev(WScript.ScriptFullName, "\"))
Set file = fs.opentextfile(sScriptPath & "DelegateListLog.txt", 8, True)
file.Write strMessage
file.Close
Please refer to the following MAPI properties used in the above sample to list delegates of the mailbox:
If you interested in exploring further details regarding how delegate settings works in Outlook then refer to:
However, if you just targeting Exchange Server 2007, I would highly recommend you to use EWS(Exchange Web Services)
Delegate Access and Delegate Access Management with Exchange Web Services
One of the common request from our customers is to provide interface to work programmatically with Delegate Settings for Outlook.
Microsoft Exchange Server 2007 Service Pack 1 (SP1) introduces delegate access and delegate access management through Exchange Web Services. The following delegate access functionality is available starting with Exchange 2007 SP1:
Here are the few links related to it:
And if you would like to do deep dive about how delegate access works with Outlook then explore it:
So, there is lot to explore in the Messaging World… Feel free to drop me your question related to Microsoft Messaging APIs
If you would like to remove all of the Personal Folders file .PSTs attached to the Outlook Mailbox profile then we can use RemoveStore Method.
Here is a sample VBScript to perform the job for us:
'Sample script to remove Personal Folders files (.pst) from the current MAPI profile or session
RemoveAllPST
Sub RemoveAllPST()
Dim objOL 'As New Outlook.Application
Dim objFolders 'As Outlook.MAPIFolders
Dim objFolder 'As Outlook.MAPIFolder
Dim i 'As Interger
Dim strPrompt 'As String
Set objOL = CreateObject("Outlook.Application")
Set objFolders = objOL.Session.Folders
For i = objFolders.Count To 1 Step -1
Set objFolder = objFolders.Item(i)
'Prompt the user for confirmation
If (InStr(1, objFolder.Name, "Mailbox") = 0) And (InStr(1, objFolder.Name, "Public Folders") = 0) Then
strPrompt = ""
strPrompt = "Are you sure you want to remove " & objFolder.Name
If MsgBox(strPrompt, vbYesNo + vbQuestion) = vbYes Then
objOL.Session.RemoveStore objFolder
We can also refer to the article mentioned below related to RemoveStore Method:
NameSpace.RemoveStore Method http://msdn.microsoft.com/en-us/library/bb219923.aspx
Outlook 2003 and Exchange Server 2003 goes into extended Support from 4/14/2009
What is the difference between Mainstream Support, Extended Support, and online self-help support?
Support provided
Mainstream Support phase
Extended Support phase
Paid support (per-incident, per hour, and others)
X
Security update support
Non-security hotfix support
Requires extended hotfix agreement, purchased within 90 days of mainstream support ending.
No-charge incident support
NA
Warranty claims
Design changes and feature requests
Product-specific information that is available by using the online Microsoft Knowledge Base
Product-specific information that is available by using the Support site at Microsoft Help and Support to find answers to technical questions
IMP: Microsoft will NOT accept requests for warranty support, design changes, or new features during the Extended Support phase.
To understand Support Lifecycle policy we can refer to Microsoft Support Lifecycle Policy FAQ
To find the support timelines for other Microsoft products, visit the Select a Product for Lifecycle Information site (products listed by Product Family) or the Support Lifecycle Index site.
If you are looking for resources to test your development projects then read on...
Run IT on a Virtual Hard Disk http://www.microsoft.com/vhd
You can now access the entire catalog of pre-configured Microsoft and partner products and solutions in the VHD format and start evaluating and testing today from www.microsoft.com/vhd.
Using the power of virtualization, you can now use a series of pre-configured Virtual Hard Disks (VHDs). You can download the VHDs and evaluate them for free in your own environment without the need for dedicated servers or complex installations.
A virtualization product that supports the VHD format is required to use this virtual machine. Microsoft Virtual PC or Microsoft Virtual Server are provided for free and can be used with these VHD based virtual machines.
Few of the VHD avalilables:
And if you are looking for some hands-on experience with Microsoft's programming tools and technologies then refer to the links below:
Welcome to TechNet Virtual Labs http://www.microsoft.com/technet/traincert/virtuallab/default.mspx Quickly evaluate and test Microsoft's newest server products through a series of guided, hands-on labs you can complete in 90 minutes or less.
MSDN Virtual Labs http://msdn2.microsoft.com/virtuallabs/ These Virtual Labs for developers give you hands-on experience with Microsoft's programming tools and technologies.
We can send deferred delivery mail using Exchange Web Services by setting PR_DEFERRED_SEND_TIME and PR_DEFERRED_DELIVERY_TIME MAPI properties as extended properties on the EWS request.
Here is the sample code in C#:
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Text;
5: using SendMailWithDeferredDelivery.msgex07;
6: using System.Net;
7: using System.Net.Security;
8: using System.Security.Cryptography.X509Certificates;
9:
10: namespace SendMailWithDeferredDelivery
11: {
12: class Program
13: {
14: static void Main(string[] args)
15: {
16: //Please change the server, domain, username, password
17: ExchangeServiceBinding esb = new ExchangeServiceBinding();
18: esb.Credentials = new NetworkCredential("user", "pass!", "domain");
19: esb.Url = @"https://<FQDN Server>/EWS/Exchange.asmx";
20:
21:
22: System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate(Object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
23: {
24: // Replace this line with code to validate server certificate.
25: return true;
26: };
27:
29: esb.RequestServerVersionValue = new RequestServerVersion();
30: esb.RequestServerVersionValue.Version = ExchangeVersionType.Exchange2007_SP1;
31:
32: // Create a new message.
33: MessageType message = new MessageType();
35: // Define the e-mail address of the recipient of the message.
36: EmailAddressType singleRecip = new EmailAddressType();
37: singleRecip.EmailAddress = "user@msglab.com";
38:
39: message.ToRecipients = new EmailAddressType[2];
40: message.ToRecipients[0] = singleRecip;
41:
42: // Set the subject and sensitivity properties.
43: message.Subject = "Siberian Tigers";
44: message.Sensitivity = SensitivityChoicesType.Personal;
45:
46: message.ExtendedProperty = new ExtendedPropertyType[2];
48: message.ExtendedProperty[0] = new ExtendedPropertyType();
49:
50: message.ExtendedProperty[0].ExtendedFieldURI = new PathToExtendedFieldType();
51:
52: //NOTE: This PropertyID is equal to PropertyTag "0x3FEF" but you have to use PropertyID and not PropertyTag
53: //otherwise it will NOT work as expected and this will not be visible via OOM or WebDAV,
54: //you have to specify it as Integer value in PropertyTag field
55: //PR_DEFERRED_SEND_TIME
56: message.ExtendedProperty[0].ExtendedFieldURI.PropertyTag = "16367";
57:
58: message.ExtendedProperty[0].ExtendedFieldURI.PropertyType = MapiPropertyTypeType.SystemTime;
59:
60: //Sending mail in another 5 Mins
61: DateTime deliverydatetime;
62: System.DateTime today = System.DateTime.Now;
63: System.TimeSpan duration = new System.TimeSpan(0,5, 0);
64: deliverydatetime = today.Add(duration);
65:
66: message.ExtendedProperty[0].Item = deliverydatetime.ToUniversalTime().ToString();
67:
68: //NOTE: This PropertyID is equal to PropertyTag "0x000F" but you have to use PropertyID and not PropertyTag
69: //otherwise it will NOT work as expected and this will not be visible via OOM or WebDAV,
70: //you have to specify it as Integer value in PropertyTag field
71: //PR_DEFERRED_DELIVERY_TIME
72:
73: message.ExtendedProperty[1] = new ExtendedPropertyType();
74:
75: message.ExtendedProperty[1].ExtendedFieldURI = new PathToExtendedFieldType();
76:
77: message.ExtendedProperty[1].ExtendedFieldURI.PropertyTag = "15";
78:
79: //message.ExtendedProperty[1].ExtendedFieldURI.PropertyTag= "0x000F";
80:
81: message.ExtendedProperty[1].ExtendedFieldURI.PropertyType = MapiPropertyTypeType.SystemTime;
82:
83: message.ExtendedProperty[1].Item = deliverydatetime.ToUniversalTime().ToString();
84:
85:
86: // Set the body property.
87: message.Body = new BodyType();
88: message.Body.BodyType1 = BodyTypeType.HTML;
89: message.Body.Value = "Did you know there are estimated to be only about 400 " +
90: "of these magnificent creatures left in the wild?";
91:
92: // Create a CreateItem request.
93: CreateItemType createItem = new CreateItemType();
94:
95: // Specify that the CreateItem operation should directly send the message
96: // and save a copy in the Sent Items folder.
97: createItem.MessageDisposition = MessageDispositionType.SendAndSaveCopy;
98: createItem.MessageDispositionSpecified = true;
99:
100: DistinguishedFolderIdType folder = new DistinguishedFolderIdType();
101: folder.Id = DistinguishedFolderIdNameType.outbox;
102:
103: TargetFolderIdType targetFolder = new TargetFolderIdType();
104: targetFolder.Item = folder;
105: createItem.SavedItemFolderId = targetFolder;
106:
107: createItem.Items = new NonEmptyArrayOfAllItemsType();
108: createItem.Items.Items = new ItemType[1] { message };
109:
110: // Call the CreateItem method and get its response.
111: CreateItemResponseType response = esb.CreateItem(createItem);
112:
113: // Get the items returned by CreateItem.
114: ResponseMessageType[] itemsResp = response.ResponseMessages.Items;
115:
116: }
117: }
118: }
EWS Rocks!!!