HOWTO: Delete Search Folders and Interop with CDO 1.21 from Managed (.NET) Code

The Outlook 2003 Object Model does not have anyway to delete Search Folders, although you can create them. The only way to delete them is to use CDO 1.21 code. However, it is not supported to run CDO 1.21 or MAPI code (yes, this includes Redemption any third party APIs or components you write that use MAPI/CDO 1.21 directly) *in-process* with managed .NET code. This means that simply wrapping the CDO 1.21 code below in a COM component is not enough, the code must live in its own process. The easiest way I know of to do that is hop back over to good ‘ole VB6 and create a very simple ActiveX EXE. This is a very simple way to run all CDO code in one process while the managed OOM code runs in another process (such as Outlook.EXE) without having to do too many configuration or deployment backflips.

In fact, the code below comes directly from an ActiveX EXE created to allow the deleting of Search Folders…

'-------------------------------------------------------

' DeleteSearchFolder

' mstehle, 07.27.07

'-------------------------------------------------------

' This CDO 1.21 code is hosted in an simple ActiveX EXE

' so that it can be called from a .NET application. The

' code runs in a seperate process which allows us to

' call it from the managed process without fear of memory

' issues.

'--------------------------------------------------------

Public Sub DeleteSearchFolder(ByVal strName As String)

    Dim oSession As MAPI.Session

    oSession = New MAPI.Session

    ' Assume we are already logged in to a session and

    ' piggy-back the session...

    oSession.Logon, , False, False

    Dim oFinderFolder As MAPI.Folder

    oFinderFolder = GetFinderFolder(oSession)

    ' Throw error if folder not found

    If oFinderFolder Is Nothing Then

        Err.Raise(MAPI.CdoE_NOT_FOUND, "DeleteSearchFolder", _

            "Finder folder not found.")

  End If

    Dim oSearchFolder As MAPI.Folder

    oSearchFolder = GetFolder(strName, oFinderFolder)

    ' Throw error if folder not found

    If oSearchFolder Is Nothing Then

        Err.Raise(MAPI.CdoE_NOT_FOUND, "DeleteSearchFolder", _

            "Search folder not found with name " & strName)

    End If

    ' If found, delete it

    oSearchFolder.Delete()

End Sub

Private Function GetFolder(ByVal strName As String, _

ByVal oParentFolder As MAPI.Folder) As Folder

    Dim oFolder As MAPI.Folder

    For Each oFolder In oParentFolder.Folders

        If oFolder.Name = strName Then

            GetFolder = oFolder

            Exit For

        End If

    Next

End Function

Private Function GetFinderFolder(ByVal oSession As MAPI.Session) _

    As MAPI.Folder

    If oSession Is Nothing Then

        Err.Raise(MAPI.CdoE_LOGON_FAILED, _

            "DeleteSearchFolder", "No session established.")

    End If

    ' Get root mailbox store folder

    Dim oInbox As MAPI.Folder

    oInbox = oSession.Inbox

    Dim oStore As MAPI.InfoStore

    oStore = oSession.GetInfoStore(oInbox.StoreID)

    Dim oRootFolder As MAPI.Folder

    oRootFolder = oSession.GetFolder("", oStore.ID)

    Dim oFolder As MAPI.Folder

    For Each oFolder In oRootFolder.Folders

        Debug.Print(oFolder.Name)

        ' In a PST the folder is called "Search Root", in an online

        ' profile it is called "Finder"

        If oFolder.Name = "Finder" Or oFolder.Name = "Search Root" Then

            GetFinderFolder = oFolder

            Exit For

        End If

    Next

End Function