More Outlook Resource Sites

Microsoft Developer Network (MSDN)

FAQs and other general resources

share code 21-Jan-2017 10:09

Looking for help with Outlook programming projects — VSTO, add-ins, VBA, custom Outlook forms, etc.? You′ve come to the right place!

NEW! >> Subscribe to this site via RSS. For more RSS options, see the complete list of feeds on our main news page.

Code level: beginner    Code area: Outlook and .NET Printer Friendly Version
Title: Saving sent email Information to XML c#
Description: This is a sample c# AddIn, hooking the SentFolder Items Add Event, and saves Information from outgoing Emails to an XML file.
Date: 20-Feb-2005  03:48
Code level: beginner
Code area: Outlook and .NET
Posted by: Helmut Obertanner
This message is displayed as VB.NET
 namespace TestAddIn
{
	using System;
	using Off = Microsoft.Office.Core;
	using Ol = Microsoft.Office.Interop.Outlook ;  
	using Extensibility;
	using System.Runtime.InteropServices;
	using System.Data;
	using System.Xml;
	using System.IO;
	using System.Reflection;
	using System.Diagnostics ;

	#region Read me for Add-in installation and setup information.
	// When run, the Add-in wizard prepared the registry for the Add-in.
	// At a later time, if the Add-in becomes unavailable for reasons such as:
	//   1) You moved this project to a computer other than which is was originally created on.
	//   2) You chose 'Yes' when presented with a message asking if you wish to remove the Add-in.
	//   3) Registry corruption.
	// you will need to re-register the Add-in by building the MyAddin21Setup project 
	// by right clicking the project in the Solution Explorer, then choosing install.
	#endregion
	
	/// <summary>
	///   The object for implementing an Add-in.
	/// </summary>
	/// <seealso class='IDTExtensibility2' />
	[GuidAttribute("CFC4FD8C-6769-46C2-8B32-F3ACA3A14CF1"), ProgId("TestAddIn.Connect")]
	public class Connect : Object, Extensibility.IDTExtensibility2
	{

		// The Instance Object
		private object myInstance;
		
		// The Application Object
		private Ol.Application myApplication;

		// The Sent Folder
		private Ol.MAPIFolder mySentFolder;
		
		// My DataSet
		private DataSet myDataSet;
		
		// My DataTable
		private DataTable myDataTable;

		/// <summary>
		///		Implements the constructor for the Add-in object.
		///		Place your initialization code within this method.
		/// </summary>
		public Connect()
		{
		}

		/// <summary>
		///      Implements the OnConnection method of the IDTExtensibility2 interface.
		///      Receives notification that the Add-in is being loaded.
		/// </summary>
		/// <param term='application'>
		///      Root object of the host application.
		/// </param>
		/// <param term='connectMode'>
		///      Describes how the Add-in is being loaded.
		/// </param>
		/// <param term='addInInst'>
		///      Object representing this Add-in.
		/// </param>
		/// <seealso class='IDTExtensibility2' />
		public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode, object addInInst, ref System.Array custom)
		{
			try
			{
				myApplication = (Ol.Application) application;
				myInstance = addInInst;

				LoadXMLData();
				mySentFolder = myApplication.Session.GetDefaultFolder (Ol.OlDefaultFolders.olFolderSentMail );  
				mySentFolder.Items.ItemAdd +=new Microsoft.Office.Interop.Outlook.ItemsEvents_ItemAddEventHandler(Items_ItemAdd);
			}
			catch (System.Exception ex)
			{
				Debug.WriteLine(ex);
			}
		}

		/// <summary>
		///     Implements the OnDisconnection method of the IDTExtensibility2 interface.
		///     Receives notification that the Add-in is being unloaded.
		/// </summary>
		/// <param term='disconnectMode'>
		///      Describes how the Add-in is being unloaded.
		/// </param>
		/// <param term='custom'>
		///      Array of parameters that are host application specific.
		/// </param>
		/// <seealso class='IDTExtensibility2' />
		public void OnDisconnection(Extensibility.ext_DisconnectMode disconnectMode, ref System.Array custom)
		{
			myInstance = null;
			if (mySentFolder != null)
			{
				// DeRegister Event
				mySentFolder.Items.ItemAdd -=new Microsoft.Office.Interop.Outlook.ItemsEvents_ItemAddEventHandler(Items_ItemAdd);
				Marshal.ReleaseComObject(myApplication);
			}
			if (myApplication != null)
			{
				Marshal.ReleaseComObject(myApplication);
			}
			GC.Collect ();
		}

		/// <summary>
		///      Implements the OnAddInsUpdate method of the IDTExtensibility2 interface.
		///      Receives notification that the collection of Add-ins has changed.
		/// </summary>
		/// <param term='custom'>
		///      Array of parameters that are host application specific.
		/// </param>
		/// <seealso class='IDTExtensibility2' />
		public void OnAddInsUpdate(ref System.Array custom)
		{
		}

		/// <summary>
		///      Implements the OnStartupComplete method of the IDTExtensibility2 interface.
		///      Receives notification that the host application has completed loading.
		/// </summary>
		/// <param term='custom'>
		///      Array of parameters that are host application specific.
		/// </param>
		/// <seealso class='IDTExtensibility2' />
		public void OnStartupComplete(ref System.Array custom)
		{
		}

		/// <summary>
		///      Implements the OnBeginShutdown method of the IDTExtensibility2 interface.
		///      Receives notification that the host application is being unloaded.
		/// </summary>
		/// <param term='custom'>
		///      Array of parameters that are host application specific.
		/// </param>
		/// <seealso class='IDTExtensibility2' />
		public void OnBeginShutdown(ref System.Array custom)
		{
		}
		
		/// <summary>
		/// Loads the Data from XML File
		/// </summary>
		private void LoadXMLData()
		{
			// Create a new DataSet
			myDataSet = new DataSet ("SentData");
			
			// Check, if File exists
			if (File.Exists (@"C:\mydata.xml"))
			{
				// Yes, read the XML-Data into Dataset
				myDataSet.ReadXml (@"C:\mydata.xml");
				// Get the DataTable

				if (myDataSet.Tables.Count > 0)
				{
					myDataTable = myDataSet.Tables [0];
				}
			}

			if (myDataTable == null)
			{

				
				// Create a new DataTable
				myDataTable = new DataTable("DataTable");
				
				// Add Columns to DataTable (would be nicer with a SchemaFile)
				myDataTable.Columns.Add ("EntryID",Type.GetType ("System.String"));
				myDataTable.Columns.Add ("Subject",Type.GetType("System.String"));
				myDataTable.Columns.Add ("SentOn",Type.GetType("System.DateTime"));

				myDataSet.Tables.Add (myDataTable);

				SaveXMLData();

			}

		}

		/// <summary>
		/// Saves the Data to XML
		/// </summary>
		private void SaveXMLData()
		{
			// Accept Changes
			myDataSet.AcceptChanges ();
			
			// Save the XML Data
			myDataSet.WriteXml (@"C:\mydata.xml");
		}


		/// <summary>
		/// EventHandler for Items Add Event of Sent Folder
		/// </summary>
		/// <param name="Item">The Outlook Item</param>
		private void Items_ItemAdd(object Item)
		{
			Ol.MailItem myMail = null;
			try
			{
				// Check Item, could be a MeetingRequest also
				if (Item is Ol.MailItem)
				{
					// Cast Object to MailItem
					myMail = (Ol.MailItem) Item;

					// Create a new DataRow
					DataRow newRow = myDataTable.NewRow ();

					// Fill Data into Row
					newRow["EntryID"] = myMail.EntryID;
					newRow["Subject"] = myMail.Subject ;
					newRow["SentOn"] = myMail.SentOn ;

					// Add Row to DataTable
					myDataTable.Rows.Add (newRow);
					myDataTable.AcceptChanges ();
			
					// Save new Data
					SaveXMLData();
				}
			}
			catch (System.Exception ex)
			{
				Debug.WriteLine(ex.Message );
			}
			finally
			{
				// Release the Reference to MailObject
				if (myMail != null) { Marshal.ReleaseComObject (myMail); }
			}
		}
	}
}
All 21comments
Page [ 1 2 3 Next >>  
  17-Feb-2006  09:23   
Helmut, I'm curious about this statement:

mySentFolder.Items.ItemAdd +=new Microsoft.Office.Interop.Outlook.ItemsEvents_ItemAddEventHandler(Items_ItemAdd);

My understanding was that you'd need an explicit Items object variable, rather than using mySentFolder.Items to subcribe to the event with a handler. Or am I just confused (very likely when reading C# code)? Since mySentFolder is declared at the class level, it stays active (rather than being destroyed by the garbage collector) and thus its Items collection can still handle events?
  17-Feb-2006  09:25   
Ah, this discussion deals with the issue I had in mind -- http://www.pcreview.co.uk/forums/thread-1855913.php -- that the Items is a temporary implied object and so can't fire events for very long.
  09-Jun-2006  09:28   
Hi Sue

I would like to do exactly this but the project is written in VB. I cannot see how the line :

mySentFolder.Items.ItemAdd +=new Microsoft.Office.Interop.Outlook.ItemsEvents_ItemAddEventHandler(Items_ItemAdd);

could be converted to VB. I have tried many ways but cannot seem to get the syntax right.
Would you be able to help.

Thanks in advance

Colin
 
  09-Jun-2006  13:48   
Hello Sue,

you are right, you need an explicit Items vairable.
This sample was an early bird...

-

Hello Collin,

as I know you can declare your Items collection with:

WithEvents _Items as Outlook.Items

or use the AddHandler and RemoveHandler statement instead.
But I'n not so familiary with VB.Net

Hope this helps, greets, Helmut

 
  12-Jun-2006  03:38   
Hi Helmut

Thanks for the post.
I think I have narrowed the problem down to the version of Microsoft.Office.Tools.Outlook.dll.
I am using Ver 9.2.0.0. and the events you describe do not exist. I have checked Ver 8.0.0.0 and those events do exist. (are your using ver 8.0.0.0 ?)
The ItemsEvents_ItemAddEventHandler must have been replaced with a different event but i can't work it out. Maybe you have updated your code to use Ver 9.2.0.0 and have come accross this.

Thanks

Colin
  12-Jun-2006  15:03   
Hello Collin,

this sample doesn't use VSTO. Only Outlook COM events.
But I will recode this sample for VSTO and post it on my Homepage.

www.x4u.de
greets, Helmut
  13-Jun-2006  02:18   
Thanks Helmut

That would be great. Will you use Microsoft.Office.Tools.Outlook.dll Ver 9.2.0.0.
As the events in your example do not exist in that version.
I have a sample program that catches the events using the events you use but this is only in ver 8.0.0.0. So it's using the new events I'm having the trouble with.

if that makes sense !!!

Thanks

Colin
 
  17-Jun-2006  08:25   
Colin, did you build your PIA for Outlook 2000 using the method described at http://www.microeye.com/resources/res_tech_vsnet.htm#Rebuilding
  19-Jun-2006  02:50   
Hi Sue

Thanks for the reply.

No I didn't. But Ii'm using office 2003 and I see there is a 2003 PIA. Should I be using the 2003 PIA and do I have to follow the same set of instructions.
Also are you saying that if I build my PIA according to these instructions then private events as described above will be exposed to my addin.
It all seems so arbitary, I would have thought all of these things would have been included in VSTO for 2005.

Just to clarify - I'm using Office 2003 vs2005 and vsto2005 to create a com pluggin for outlook.

Thanks
  22-Jun-2006  17:16   
Colin, if you are using Outlook 2003, then you need to make sure the Office 2003 PIAs are installed. Either download the redistributable from Microsoft.com or run Office setup to make sure that .NET support is installed for all programs.

I don't understand your reference to earlier Outlook versions, which are not compatible with VSTO 2005 add-ins.
Page [ 1 2 3 Next >>