|
|
Introduction to RDO
RDO (Redemption Data Objects) is Redemption's automation-friendly object model
for Outlook and Exchange data. Use it in addition to, or instead of, the Outlook
Object Model when your code needs direct access to stores, folders, messages,
MAPI properties, profiles, tables, rules, and Exchange mailbox data.
RDO is also useful when Extended MAPI
is the right API, but you want to use it from C#, VB.NET, VBA, Delphi, C++, or
script code through COM-friendly objects instead of writing unmanaged Extended
MAPI code directly.
Safe*Item Redemption objects are the
minimal-change option for existing Outlook Object Model code that needs to work
around security prompts. RDO is the broader object model for code that needs a
fuller Outlook, Exchange, and MAPI view of the mailbox.
RDO can share the MAPI session already used by Outlook through
RDOSession.MAPIOBJECT, or it can create its
own session through one of the RDOSession logon
methods. These two options are the usual starting point for code that extends
Outlook directly or works with mailbox data without automating every operation
through the Outlook Object Model.
RDO combines Extended MAPI-level access
with an Outlook-style object model. It can be used from any code: COM add-ins,
EXEs, scripts, Windows Services, etc. It can be used in any language that can
use COM automation objects, including C#, VB.NET, VBA, Delphi, C++, and scripting
languages.
Getting Started with RDO
The main creatable RDO object is
Redemption.RDOSession. All other RDO objects are
retrieved through the RDOSession object, either
directly or indirectly. Once you create an instance of the
Redemption.RDOSession object, you must log on or
connect to a MAPI session to be able to access other RDO objects, such as
RDOStore, RDOFolder,
RDOMail, etc. To differentiate
between various Redemption objects (such as Redemption.SafeMailItem), all RDO
object names are prefixed with "RDO": e.g. RDOMail object exposes attachments
through its Attachments collection, which in turn returns Redemption.RDOAttachments objects, etc.
If you already use the Outlook Object
Model, RDOSession corresponds fairly closely to the
Outlook Namespace object, but exposes lower-level MAPI access and additional
mailbox functionality. If you are maintaining legacy CDO 1.21 code, RDO can also
provide a path forward.
There are several ways to log on to a MAPI session in RDO:
-
set the RDOSession.MAPIOBJECT property to Outlook's current session, usually Application.Session.MAPIOBJECT. This is the preferred path for Outlook add-ins and macros because RDO uses the same profile and logged-on session as Outlook.
-
use RDOSession.LogonHostedExchangeMailbox or related Exchange mailbox methods for Exchange and Microsoft 365 mailbox scenarios where your code needs to create its own session.
-
use RDOSession.LogonPstStore for PST-only work. It creates a temporary MAPI profile with the specified PST store as the only service.
-
use RDOSession.Logon to log on to an existing MAPI profile. Legacy code can also pass an IMAPISession retrieved through Extended MAPI or CDO 1.21 to MAPIOBJECT, but new Outlook code normally shares Outlook's Application.Session.MAPIOBJECT instead.
Once you are logged on to a MAPI session, you can start accessing various
MAPI objects exposed by RDO. The example below logs to the default MAPI session
and prints out the subject of all messages in the Inbox folder:
|
set Session =
CreateObject("Redemption.RDOSession")
Session.Logon
set Inbox = Session.GetDefaultFolder(olFolderInbox)
for each Msg in Inbox.Items
Debug.Print(Msg.Subject)
next |
Of course you can mix RDO with
the Outlook Object Model. The example below reads the SenderName property
blocked by Outlook from an Outlook MailItem object using RDO.
|
set Session =
CreateObject("Redemption.RDOSession")
'make sure RDO uses the same
MAPI session as Outlook. Outlook 2002 and up only!
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
Msg = Session.GetItemFromID(MailItem.EntryID)
MsgBox Msg.SenderName |
The same functionality can of course
be implemented using the old SafeMailItem Redemption object:
|
set SafeItem = CreateObject("Redemption.SafeMailItem")
SafeItem.Item = MailItem
MsgBox SafeItem.SenderName |
Important RDO distinctions from the Outlook Object Model
-
RDOSession gives explicit control over the MAPI session. It can connect to
Outlook's session by setting the MAPIOBJECT property, or it can create its
own session through Logon, LogonExchangeMailbox, or LogonPstStore.
-
RDO objects can be used from multiple threads, both inside and outside of
outlook.exe. Outlook Object Model access is effectively tied to
Outlook's main thread: Outlook add-ins can fail when Outlook detects OOM
access from a secondary thread, and external automation calls are marshaled
back to Outlook's main thread. RDO does not have that object model limitation;
initialize MAPI on each worker thread by creating an RDOSession
or another creatable Redemption object there, and share the same MAPI session
by assigning RDOSession.MAPIOBJECT. See
Using Redemption objects on multiple threads.
-
Message import and export are first-class RDO operations. RDOMail.Import
can import data into an existing item, RDOMail.SaveAs
can export messages to formats such as MSG, EML/RFC822, HTML/MHTML, and Fast
Transfer Stream, and RDOFolder2.Import can create
one or more items in a folder from a file, stream, or byte array. Outlook has
MailItem.SaveAs for supported export formats, but it does not have a
comparable general import API.
-
MAPITable exposes Extended MAPI tables wherever the underlying MAPI API provides
an IMAPITable, including folders, attachments, recipients, stores, address
book containers, ACLs, and other collections. Outlook has Folder.GetTable
for folder and search-result rowsets, but RDO provides broader table coverage,
SQL-style ExecSQL, explicit restriction objects, and lower-level table access.
-
Extended MAPI properties are available through the Fields() collection on
RDO objects derived from _MAPIProp. Properties can be
addressed by property tag, such as PR_SUBJECT = 0x0037001E, or by DASL
name, such as http://schemas.microsoft.com/mapi/proptag/0x0037001E.
Outlook's PropertyAccessor can read many properties, but the Outlook
Object Model can block writes to protected or provider-owned properties. RDO
stays closer to Extended MAPI: it sends the write to the provider and returns
the provider's result if the operation is rejected. See
RDOFolder, RDOStore,
RDOMail, RDOAttachment,
RDOAddressEntry, and
RDOAddressList.
-
RDO has dedicated entry points for shared, cached, delegate, archive, and PST
stores, including RDOSession.GetSharedMailbox,
GetCachedSharedMailbox, GetArchiveMailbox,
AddDelegateExchangeStore, and AddPstStore. AddPstStore
returns the newly opened RDOStore, and
RDOPstStore exposes the PST path.
-
Address book resolution can be scoped to a particular address list, such as the
Global Address List or a Contacts folder, instead of resolving against the
whole address book. RDOAddressBook.ResolveNameEx and
RDOAddressList.ResolveNameEx can also return
and inspect ambiguous matches instead of forcing a single resolved recipient,
and RDOAddressBook.SearchPath exposes the
address book search path used by automatic name resolution.
-
Recoverable items and deletion modes are exposed directly. RDOFolder
exposes DeletedItems and DeletedFolders for Exchange recoverable
content, while RDOMail.Delete and
RDOItems.Remove support move-to-Deleted-Items,
soft-delete, and hard-delete behavior.
-
Exchange rules and client-side rules are exposed beyond the standard Outlook
rules surface. RDO can work with store and folder rules, public-folder rules,
and Outlook client rules, including RWZ rule files through
RDOClientRules.
-
RDO exposes Exchange and Outlook data areas that are missing or limited in the
Outlook Object Model, including RDOFolder.ACL,
RDOSearchFolder,
RDOStore.Reminders,
RDOQuickSteps,
RDOFavorites, and
RDOTemplates.
-
Bulk item operations can be performed without opening each item one by one.
RDOItems exposes CopyMultiple,
MoveMultiple, RemoveMultiple, and progress events for long-running
operations.
|