Coding against Out Of Office in Outlook 2007

B

Brian Hampson

I had originally posted in microsoft.public.outlook and it was
suggested that here might be a better place. So....

======

I recently upgraded to Outlook 2007 B2TR and have found that I can no
longer code against CDO.DLL It's gone :(

Using C#, I used to get the MAPI session, and from that I could change
the out of office. No longer. Does anyone know how to do this using
the new Microsoft.Office.Core and Microsoft.Office.Outlook DLL's that
are supposed to be the new replacements?


Here's what I had that worked until Outlook 2007 came around:


SessionClass session = new MAPI.SessionClass();
session.Logon(Missing.Value,Missing.Value,Missing.Value,Missing.Value,Missi­ng.Value,Missing.Value,servertxt.Text+"\n"+mailboxtxt.Text);

session.OutOfOffice= !this.checkBoxIn.Checked;
session.OutOfOfficeText = this.OOOtxt.Text;
session.Logoff();

Any suggestions? This is s standalone app, not an add-in or other.


1. It has been brought up that the CDO is now a separate download (that
didn't help - it won't install if I have Exchange Tools on the box)
1a. Apparently CDO isn't supported - I'm getting used to that. If I
can make it work, I don't really care if it isn't supported (It appears
that much of what people ACTUALLY want to do isn't supported <sigh>)

2. It has been mentioned that the OOstate is available through
Store.PropertyAccessor using the new object, but the text isn't

I want to be able to change state and text of the out of office
message.

Thanks in advance for any help.


Brian Hampson
System Administrator, North America
ALS Laboratory Group
 
K

Ken Slovak - [MVP - Outlook]

Ah, I found it. The text is stored in a hidden message in the Inbox with a
MessageClass of "IPM.Note.Rules.OofTemplate.Microsoft". The text is in the
Body of that hidden message.

An Outlook 2007 StorageItem would be the equivalent of a hidden item. So
you'd get a StorageItem with that MessageClass in the Inbox. Then you'd
change the Body property of that item and save it to change the OOF text.

I gave you the property to use with Store.PropertyAccessor for the OOF
state. Just make sure that Store is an Exchange store, the property won't
exist for a public folder or PST file store.

I surely would not want to use CDO 1.21 with .NET code. It's not that it's
unsupported, most of what I do is unsupported. It's that the code may blow
up at any time for any reason and usually at a client site and no one would
be able to support you or the code or fix it.

The Outlook CDO is only client side and the MAPI libraries it depends on are
different than the ones used when Exchange or Exchange admin tools are
installed. Not compatible at all. You also can't use the server side CDO
1.21 with Outlook code at all.




I had originally posted in microsoft.public.outlook and it was
suggested that here might be a better place. So....

======

I recently upgraded to Outlook 2007 B2TR and have found that I can no
longer code against CDO.DLL It's gone :(

Using C#, I used to get the MAPI session, and from that I could change
the out of office. No longer. Does anyone know how to do this using
the new Microsoft.Office.Core and Microsoft.Office.Outlook DLL's that
are supposed to be the new replacements?


Here's what I had that worked until Outlook 2007 came around:


SessionClass session = new MAPI.SessionClass();
session.Logon(Missing.Value,Missing.Value,Missing.Value,Missing.Value,Missi­ng.Value,Missing.Value,servertxt.Text+"\n"+mailboxtxt.Text);

session.OutOfOffice= !this.checkBoxIn.Checked;
session.OutOfOfficeText = this.OOOtxt.Text;
session.Logoff();

Any suggestions? This is s standalone app, not an add-in or other.


1. It has been brought up that the CDO is now a separate download (that
didn't help - it won't install if I have Exchange Tools on the box)
1a. Apparently CDO isn't supported - I'm getting used to that. If I
can make it work, I don't really care if it isn't supported (It appears
that much of what people ACTUALLY want to do isn't supported <sigh>)

2. It has been mentioned that the OOstate is available through
Store.PropertyAccessor using the new object, but the text isn't

I want to be able to change state and text of the out of office
message.

Thanks in advance for any help.


Brian Hampson
System Administrator, North America
ALS Laboratory Group
 
D

Dan Mitchell

Ken Slovak - said:
I surely would not want to use CDO 1.21 with .NET code. It's not that
it's unsupported, most of what I do is unsupported. It's that the code
may blow up at any time for any reason and usually at a client site
and no one would be able to support you or the code or fix it.

To quote from microsoft, talking about this a while ago:

"It's the sort of thing that'll mostly work. It'll work while you're
writing it. Then it'll work while you're testing it. It'll work while your
customer is evaluating it. Then as soon as the customer deploys it - BAM!
That's when it'll decide to start having problems. And Microsoft ain't
gonna help you with it, since we told you not to do it in the first place.
:)"

There are certainly lots of people using .Net with CDO1.21 and even
Extended MAPI, and I suspect most of them are having no problems because
of it -- but that doesn't mean they never will.

-- dan
 
B

Brian Hampson

Nice quote :)

Pleasantly I'm the customer, so it's OK, but now that I've got the
direction to head to get it done otherwise, I can dig into THAT
instead.

Thanks to Ken for his digging about.
 
K

Ken Slovak - [MVP - Outlook]

Dan, you really like that quote from Stephen Griffin, don't you? <g>
 
D

Dan Mitchell

Ken Slovak - said:
Dan, you really like that quote from Stephen Griffin, don't you? <g>

Yup.. :) Original link is:

http://groups.google.com/group/microsoft.public.win32.programmer.messagi
ng/msg/20149ae3de2f4920?hl=en&

It's unfortunate that they didn't get the manpower (or whatever it was)
to support CDO1.21/ExMAPI with .Net, certainly.

And it's a bit unfortunate that there's enough things out there to make
it look as if it'll work, and the only way to find out that it won't is
either to search googlegroups to see if someone has already asked the
same question (<fx: collapses in fit of laughter>) or to go hunting
around the KB.

Heck, _I_ don't search the KB before writing code just in case there's
an article in there that says "don't do X" -- partly because searching
the KB is generally a loss, and partly because I'll assume things work
until I find otherwise.

So explaining in great detail why mixing these things up isn't a good
plan seems like the best bet to make sure the message gets across -- the
KB article just says "this isn't supported", but not really why it's not
supported..

-- dan
 
K

Ken Slovak - [MVP - Outlook]

I usually assume if the KB says something isn't documented or supported that
it just means some extra detective work on my part <g>. So much of what I do
is completely undocumented anyway I'm used to it.

According to my conversations with the PM who owns CDO there was never any
intention of making CDO .NET compliant. It's being deprecated.

Remember Mindy's XSO and all the other "wunder-API's" we were going to have
instead of having to use CDO or MAPI? And EX was going to move to SQL
Server, so no need to ensure compliance for MAPI and .NET. That's my guess
for EX MAPI, plus all those years of the Exchange team saying "Exchange is
not a development platform".

Just one more reason to use Redemption...
 
B

Brian Hampson

Hi Ken. Thanks for all your directions so far. I seem to have my "Out
of Office Tool" working when I use my own mailbox presently... Not so
much when I choose another user. (Note, when I was using MAPI, this
was working fine.... now I seem to have some sort of Perm issue)

Here's my code:

Outlook.ApplicationClass app = new
Microsoft.Office.Interop.Outlook.ApplicationClass();
Outlook.NameSpaceClass ns =
(Outlook.NameSpaceClass)app.GetNamespace("MAPI");
Outlook.Recipient recipient =
ns.CreateRecipient(this.mailboxtxt.Text);

if (recipient.Resolve())

{
Outlook.MAPIFolder Inbox =
ns.GetSharedDefaultFolder(recipient,
Outlook.OlDefaultFolders.olFolderInbox);
Outlook.PropertyAccessor pa = Inbox.PropertyAccessor;
foreach (Outlook.Store store in ns.Stores)
{
if (store.ExchangeStoreType ==
Outlook.OlExchangeStoreType.olPrimaryExchangeMailbox)
OOFState =
(bool)store.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x661D000B");
}

Outlook.StorageItem OOFMessage;
OOFMessage =
Inbox.GetStorage("IPM.Note.Rules.OofTemplate.Microsoft",

Outlook.OlStorageIdentifierType.olIdentifyByMessageClass);
this.checkBoxIn.Checked = !OOFState;
this.OOOtxt.Text = OOFMessage.Body;
}

When I do the Inbox.GetStorage on another user's mailbox, I now get:

"An unhandled exception of type
'System.Runtime.InteropServices.COMException' occurred in
OutOfOffice.exe"

"Additional information: Cannot create StorageItem in this folder.
Either the folder is read-only, or a storage item is not allowed in
this folder. "

Any ideas? Thanks for your patience. I don't know HOW this is
supposed to be better than the old way :(
 
K

Ken Slovak - [MVP - Outlook]

Getting a folder using GetSharedDefaultFolder doesn't really give you all
the properties, permissions and so on that you need for a lot of things. If
the store is opened as part of your Outlook profile you should be able to
iterate the Stores collection and get the Inbox for each Exchange type
store. That might work.

Other than that? I'd be using Redemption code myself. There are a number of
limitations with PropertyAccessor such as memory errors if you exceed a
certain limit in retrieving data from a PT_STRING8, PT_BINARY and PT_Unicode
property. What those limits are is still open to discovery. They didn't
implement a fall-back to an IStream if getting the property normally fails.




Hi Ken. Thanks for all your directions so far. I seem to have my "Out
of Office Tool" working when I use my own mailbox presently... Not so
much when I choose another user. (Note, when I was using MAPI, this
was working fine.... now I seem to have some sort of Perm issue)

Here's my code:

Outlook.ApplicationClass app = new
Microsoft.Office.Interop.Outlook.ApplicationClass();
Outlook.NameSpaceClass ns =
(Outlook.NameSpaceClass)app.GetNamespace("MAPI");
Outlook.Recipient recipient =
ns.CreateRecipient(this.mailboxtxt.Text);

if (recipient.Resolve())

{
Outlook.MAPIFolder Inbox =
ns.GetSharedDefaultFolder(recipient,
Outlook.OlDefaultFolders.olFolderInbox);
Outlook.PropertyAccessor pa = Inbox.PropertyAccessor;
foreach (Outlook.Store store in ns.Stores)
{
if (store.ExchangeStoreType ==
Outlook.OlExchangeStoreType.olPrimaryExchangeMailbox)
OOFState =
(bool)store.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x661D000B");
}

Outlook.StorageItem OOFMessage;
OOFMessage =
Inbox.GetStorage("IPM.Note.Rules.OofTemplate.Microsoft",

Outlook.OlStorageIdentifierType.olIdentifyByMessageClass);
this.checkBoxIn.Checked = !OOFState;
this.OOOtxt.Text = OOFMessage.Body;
}

When I do the Inbox.GetStorage on another user's mailbox, I now get:

"An unhandled exception of type
'System.Runtime.InteropServices.COMException' occurred in
OutOfOffice.exe"

"Additional information: Cannot create StorageItem in this folder.
Either the folder is read-only, or a storage item is not allowed in
this folder. "

Any ideas? Thanks for your patience. I don't know HOW this is
supposed to be better than the old way :(
 
B

Brian Hampson

I went the Redemption route, and the registerless COM. It's all good I
suppose.

I was hoping to avoid 3rd party products.

It works, and since I'm the customer - I'll sign off on it :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top