P
Pazu
Application in .NET 2.0 tries to read out some information from Outlook
Contact folder. It uses simple iteration through the folder items collection.
Outlook is using Exchange 2003 mailbox. When Outlook 2003 is in "cached
mode", everything works always well, all items are correctly returned (being
either ContactItem or DistListItem). When Outlook 2003 is in "direct mode"
(or "non-cached mode"), some of returned items are of type System.__ComObject
and are never castable to ConatctItem nor DistListItem - their are
"defective". The count of "defective" items is varying for each run of
application, sometimes it is just few of them, some times 90%.
* Details
1. The problem happens both when IEnumarator is used or when
GetFirst/GetNext or GetLast/GetPrev methods are used for iteration through
the folder items collection (see commnted section) 2. The problem has been
reproduced on two different domains (customer's and ours) with their own
Exchange2003 deployment 3. The problem is 100% reproducible if trial set
consist some 5 trials and number of conatcts in a folder is greater then 200.
4. Station OS is WXP CZ Pro SP2, application is Outlook CZ 2003 SP2 form
Office CZ 2003 Pro, network is Ethernet 100baseT, domain is Windows 2003 CZ
server SP2 (tested on SP1 with the same result), Exchange 2003 ENG SP2
(tested on SP1 same result) 5. If "defective" object is returned, VS debugger
shows, that is is empty (all fields zero).
* Impression
The underlying COM object for ConatactItem is not populated either "in-time"
or "at all" and prematurely returned by PIA to .NET application or wrong
marshaling.
* Fundametal code example
Outlook.Application apl = new Outlook.Application();
Outlook.NameSpace olk = apl.GetNamespace("MAPI");
Outlook.MAPIFolder folder =
olk.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts);
Outlook.Items items = folder.Items;
int total = 0;
int read = 0;
foreach( object rawcontact in items ) {
total++;
Outlook.ContactItem contact = rawcontact as
Outlook.ContactItem;
if( contact == null ) {
Console.WriteLine("ITEM {0}, skipping: " +
Microsoft.VisualBasic.Information.TypeName(rawcontact), total);
}
else {
read++;
Console.WriteLine("ITEM {0}, reading: " +
Microsoft.VisualBasic.Information.TypeName(rawcontact) + " | " +
contact.FullName);
}
}
Console.WriteLine("Total {0}, read {1}", total, read);
Contact folder. It uses simple iteration through the folder items collection.
Outlook is using Exchange 2003 mailbox. When Outlook 2003 is in "cached
mode", everything works always well, all items are correctly returned (being
either ContactItem or DistListItem). When Outlook 2003 is in "direct mode"
(or "non-cached mode"), some of returned items are of type System.__ComObject
and are never castable to ConatctItem nor DistListItem - their are
"defective". The count of "defective" items is varying for each run of
application, sometimes it is just few of them, some times 90%.
* Details
1. The problem happens both when IEnumarator is used or when
GetFirst/GetNext or GetLast/GetPrev methods are used for iteration through
the folder items collection (see commnted section) 2. The problem has been
reproduced on two different domains (customer's and ours) with their own
Exchange2003 deployment 3. The problem is 100% reproducible if trial set
consist some 5 trials and number of conatcts in a folder is greater then 200.
4. Station OS is WXP CZ Pro SP2, application is Outlook CZ 2003 SP2 form
Office CZ 2003 Pro, network is Ethernet 100baseT, domain is Windows 2003 CZ
server SP2 (tested on SP1 with the same result), Exchange 2003 ENG SP2
(tested on SP1 same result) 5. If "defective" object is returned, VS debugger
shows, that is is empty (all fields zero).
* Impression
The underlying COM object for ConatactItem is not populated either "in-time"
or "at all" and prematurely returned by PIA to .NET application or wrong
marshaling.
* Fundametal code example
Outlook.Application apl = new Outlook.Application();
Outlook.NameSpace olk = apl.GetNamespace("MAPI");
Outlook.MAPIFolder folder =
olk.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts);
Outlook.Items items = folder.Items;
int total = 0;
int read = 0;
foreach( object rawcontact in items ) {
total++;
Outlook.ContactItem contact = rawcontact as
Outlook.ContactItem;
if( contact == null ) {
Console.WriteLine("ITEM {0}, skipping: " +
Microsoft.VisualBasic.Information.TypeName(rawcontact), total);
}
else {
read++;
Console.WriteLine("ITEM {0}, reading: " +
Microsoft.VisualBasic.Information.TypeName(rawcontact) + " | " +
contact.FullName);
}
}
Console.WriteLine("Total {0}, read {1}", total, read);