(c) 2003 Visual Studio Magazine 
Fawcette Technical Publications

VB.NET#	Interact With Outlook
Listing 1	 Wrapping all the Outlook functionality in a separate class leaves the Windows form three simple tasks-Initialize, handle raised events, and Finalize. Option Strict remains on throughout the entire solution, and you take full advantage of type checking and IntelliSense. 

Public Class MainForm : Inherits _
	System.Windows.Forms.Form

Protected Shared m_exitEvent As New _
	ManualResetEvent(False)
'Outlook management class
	Protected m_om As COutlook
Public Sub New()
	MyBase.New()
	InitializeComponent()
	m_om = _
		COutlookManager.GetOutlookTool(m_exitEvent)

If m_om Is Nothing Then
'Error Handler
Else
AddHandler m_om.OutlookState, AddressOf _
	OutlookStateChanged
		End If
	End Sub

	Protected Overloads Overrides Sub _
		Dispose(ByVal disposing As Boolean)
'Signal that we are exiting
		m_exitEvent.Set()   
		If Not m_om Is Nothing Then m_om.Dispose()

		'...Usual stuff...
	End Sub

Protected Sub OutlookStateChanged(ByVal sender _
	As Object, ByVal nState As _
	COutlook.OutlookStates)

		Select Case nState
			Case COutlook.OutlookStates.NewMail
				Dim mailDetails As New _
					COutlook.MailDetails()
				m_om.GetNewMailDetails(mailDetails)
				Dim strSpeech As String = _
					"You have a new " & _
					mailDetails.m_strPriority & _
					"priority email from " & _
					mailDetails.m_strFrom & _
					". Subject reads: " _
					& mailDetails.m_strSubject
				
				MsgBox(strSpeech)
			Case COutlook.OutlookStates.Running
				Dim strSpeech As String = _
					"Outlook is active"
				MsgBox(strSpeech)
			Case COutlook.OutlookStates.Stopped
				Dim strSpeech As String = _
					"Outlook is inactive"
				MsgBox(strSpeech)
		End Select
	End Sub

VB.NET	Detect and Load the Correct Assembly
Listing 2	You detect the available version of the Outlook Object Model (OOM) using the Activator to create an instance, then call the Version member. You then use this information in conjunction with Reflection to load the appropriately bound assembly. Finally, you return a reference to the specific Outlook functionality by casting the derived class to the base class.

Public NotInheritable Class COutlookManager
Public Shared Function GetOutlookVersion() As Integer
		Dim obOutlook As Object = Nothing
		Dim nVersion As Integer = 0

		Try			
			' Get the type to use from the assembly.
			Dim appType As Type = _
				Type.GetTypeFromProgID( _
				"Outlook.Application")

			' Create an instance of the type.
			obOutlook = _
				Activator.CreateInstance(appType)

			'Get the value from the property, and cast 
			'object to string
			Dim strVersion As String = _
				CType(appType.InvokeMember("Version", _
				BindingFlags.GetProperty, Nothing, _
				obOutlook, Nothing), String)

			obOutlook = Nothing 
			Dim nIndex As Integer = _
				strVersion.IndexOf(".")

			If nIndex > -1 Then
				Dim strMainVersion As String = _
					strVersion.Substring(0, nIndex)
				nVersion = CType(strMainVersion, Integer)
			End If
		Catch ex As Exception
			obOutlook = Nothing
		End Try

		Return nVersion
	End Function

Public Shared Function GetOutlookTool(ByRef exitEvent As _
	ManualResetEvent) As COutlook

		'Detect version of outlook running
		Dim nVersion As Integer = GetOutlookVersion()

		Dim dll As Reflection.Assembly
		Dim type As Type

		Try

			Select Case nVersion
				Case 11 ' 2003
					Return Nothing
				Case 10 ' 2002/XP
					dll = _
						Reflection.Assembly.Load( _
						"Outlook2002")
					type = _
						dll.GetType( _
						"Outlook2002.COutlook2002")
				Case 9 ' 2000
					dll = _
						Reflection.Assembly.Load( _
						"Outlook2000")
					type = _
							dll.GetType( _
							"Outlook2000.COutlook2000")
				Case Else
					Return Nothing
			End Select
		Catch ex As Exception
			Return Nothing
		End Try

		Dim ob As Object

		Try
			ob = Activator.CreateInstance(type)
		Catch ex As Exception
			Return Nothing
		End Try

		Dim ot As COutlook = CType(ob, COutlook)
		ot.ExitEvent = exitEvent
		Return ot

	End Function

End Class


