Unable to enumerate Mailboxes in NON Cached Mode (if more than 2)

S

stefanom74

I don't know if it is a bug, but writing this code in a VBA Macro something
strange happens:
If I have mailboxes in my Outlook 2007 in Cached Mode everything works fine,
but if I'm not in Cached Mode I receive an "Automation Error", any idea?

Dim store As store

For Each store In Application.Session.Stores

MsgBox (store.DisplayName)

Next
 
K

Ken Slovak - [MVP - Outlook]

This is running in the Outlook VBA project? Does it help if you get a
NameSpace object and use that?

Dim oNS As Outlook.NameSpace
Set oNS = Application.GetNameSpace("MAPI")
For each store In oNS.Stores

Also, step your code and see where it's failing. Do you get a store object?
How many oNS.Stores are there?
 
S

stefanom74

Hi Ken,

Thanks for the reply.

I found the problem !

I tried your code but it returns the same Automation Error (on "Next"
statement), then i tried to change the code from "for each" to a simple (for
index=1 to oNS.Count) ... and here it is !!! The "real" error appeared
"Unable to connect Exchange...." while accessing to the DisplayName store's
property (not on "Next i" statement). The error was on the "Public Folders"
that is enumerated as store too!
An error handling inside the "For" will probably "solve" the problem.
(but why the "For Each" statement doesn't have the same behavior?)


This is the update code:

Sub TestBug()
Dim store As store
Dim oNS As Outlook.NameSpace
Set oNS = Application.GetNamespace("MAPI")
MsgBox (oNS.Stores.Count) '<- this returns 3
For i = 1 To oNS.Stores.Count
MsgBox (oNS.Stores(i).DisplayName) ' <- this returns Error on i = 2
Next i
End Sub

Regards,
Stefano
 
K

Ken Slovak - [MVP - Outlook]

I tested both code methods (with the For...Each and For loops) here on
Outlook 2007 in both online and cached modes and ran the code with no
errors. I got the display name for public folders with no errors.

Let's try a couple of tests.

First, when you iterate the stores get each one as a Store object. Make sure
you can do that with the public folders store and as a Store object try to
access DisplayName. Do that instead of using those compound dot operators
(oNS.Stores(i).DisplayName). They make it hard to see exactly where the
error is occurring.

Second, try getting the All Public Folders folder using
oNS.GetDefaultFolder(olPublicFoldersAllPublicFolders) and see if you get a
valid Folder object and if you can access its properties such as Name.

I'm amazed that this is happening in online mode, if anything I'd expect
some problem with cached mode rather than online mode.
 
S

stefanom74

Hi Ken,

Thanks a lot for you interest.

I tried to get All Pubilc Folders folder and i got the same Error:
"Microsoft Exchange is not available. Either there are network problems or
the Exchange computer is down for maintenance".

At this point I think this is a problem of my Exchange 2007 installation ...
I will try reinstalling the Dev environment and will let you know if got
fixed ...

.... but anyway ... since this "problem" may occur when Exchange is not
available (i know it is strange in NON Cached Mode) how can i solve the
foreach problem!?
Since everything is started developing a VSTO 3SP1 c# Outlook Addin while I
was trying to enumerates Stores ... and Application.Session.Stores is not an
array of Outlook.Store but it is IEnumerable and can be accessed just with
foreach (or equivalent) ... how can I enumerate all Stores with a for (int
i=0;....) in order to put error handling on each item ?!?

Thanks!
Regards,
Stefano
 
S

stefanom74

Hi Ken,

Forget my last post... about the Stores[] ... it is a collection of
object... but starting from index = 1 so just solved my problem with error
handling on each Store item index.

Thanks,
Regards,
Stefano
 
K

Ken Slovak - [MVP - Outlook]

Outlook.Stores stores = oNS.Stores;
int iCount = stores.Count;
Outlook.Store store = null;

for (int i = 1; i <= iCount; i++)
{
store = stores;
if (store != null)
{
// working code here
}
}

That way you avoid the multiple dot operator problem and explicitly
instantiate each object separately so it can be checked. With judicious use
of try...catch blocks you can then trap any exceptions and see what went
wrong where.

I often try to avoid foreach loops although they are easier to write. They
are slower than explicit for loops and in addition they create internal
object variables that cannot be released explicitly. That ends up causing
resource problems, especially in loops with Exchange. In Exchange you are by
default limited to under 256 RPC channels and each object variable counts as
one RPC channel. So lots of those internally created variables that can't be
released leads to running out of channels.

With limits on dot operators and careful use of where you declare objects
you can then release your objects explicitly in the loop if needed
(Marshal.ReleaseComObject() and GC.Collect()). Notice I declared the store
obejct outside the loop so only 1 instance is created.

That may not apply in this case with only a few stores, but it's good
practice to get into that habit. And the explicit instantiations make it
easier to debug since you don't have to guess which part of a multiple dot
operator line is causing the problem.
 
S

stefanom74

Hi Ken,

Thank you!!

It has been very helpful!!!!! I never thought about RCP channels !? I'll
take care of it and all the other tips !!!

Thanks
Regards,
Stefano






Ken Slovak - said:
Outlook.Stores stores = oNS.Stores;
int iCount = stores.Count;
Outlook.Store store = null;

for (int i = 1; i <= iCount; i++)
{
store = stores;
if (store != null)
{
// working code here
}
}

That way you avoid the multiple dot operator problem and explicitly
instantiate each object separately so it can be checked. With judicious use
of try...catch blocks you can then trap any exceptions and see what went
wrong where.

I often try to avoid foreach loops although they are easier to write. They
are slower than explicit for loops and in addition they create internal
object variables that cannot be released explicitly. That ends up causing
resource problems, especially in loops with Exchange. In Exchange you are by
default limited to under 256 RPC channels and each object variable counts as
one RPC channel. So lots of those internally created variables that can't be
released leads to running out of channels.

With limits on dot operators and careful use of where you declare objects
you can then release your objects explicitly in the loop if needed
(Marshal.ReleaseComObject() and GC.Collect()). Notice I declared the store
obejct outside the loop so only 1 instance is created.

That may not apply in this case with only a few stores, but it's good
practice to get into that habit. And the explicit instantiations make it
easier to debug since you don't have to guess which part of a multiple dot
operator line is causing the problem.




stefanom74 said:
Hi Ken,

Thanks a lot for you interest.

I tried to get All Pubilc Folders folder and i got the same Error:
"Microsoft Exchange is not available. Either there are network problems or
the Exchange computer is down for maintenance".

At this point I think this is a problem of my Exchange 2007 installation
...
I will try reinstalling the Dev environment and will let you know if got
fixed ...

... but anyway ... since this "problem" may occur when Exchange is not
available (i know it is strange in NON Cached Mode) how can i solve the
foreach problem!?
Since everything is started developing a VSTO 3SP1 c# Outlook Addin while
I
was trying to enumerates Stores ... and Application.Session.Stores is not
an
array of Outlook.Store but it is IEnumerable and can be accessed just with
foreach (or equivalent) ... how can I enumerate all Stores with a for (int
i=0;....) in order to put error handling on each item ?!?

Thanks!
Regards,
Stefano
 

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