Exceeds amount of items

M

Magnus

Hello,

I'm trying to go through all contacts, and compare them to all other contacts, to see if they are similar etc etc.
I seems to exceeds the limit of approx 255 open com objects, and I can't figure out how to get my code to work.
As you can see I try to delete the objects, but I can't succeed.

My error which I get after several loops:

Unable to cast COM object of type 'System.__ComObject' to interface type 'Microsoft.Office.Interop.Outlook.ContactItem'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{00063021-0000-0000-C000-000000000046}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

in the top I have: using ol = Microsoft.Office.Interop.Outlook;
and my procedure simplified:

ol.Application objOutlook = new ol.Application();

ol.MAPIFolder folder = objOutlook.Session.GetDefaultFolder(ol.OlDefaultFolders.olFolderContacts);

ol.Items items = (ol.Items) folder.Items;

int i = 1; int tot = items.Count; int dups = 0;

string dupindexes = "none";

ol.ContactItem[] RemoveItems = new Microsoft.Office.Interop.Outlook.ContactItem[10000];

foreach (ol.ContactItem itm in items)

{

int inclausecount = 0;

ol.MAPIFolder folder2 = objOutlook.Session.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderContacts );

ol.Items items2 = (ol.Items) folder2.Items;

foreach (ol.ContactItem itm2 in items2)

{

inclausecount++;

if (itm.CreationTime <= itm2.CreationTime) goto notmatch;

if (itm.Subject != itm2.Subject) goto notmatch;

dups++;

dupindexes += i.ToString() + ":" + itm.Subject + "\r\n";

itm2.Close(Microsoft.Office.Interop.Outlook.OlInspectorClose.olDiscard);

System.Runtime.InteropServices.Marshal.ReleaseComObject(itm2);

GC.Collect();

break;

notmatch:

System.Runtime.InteropServices.Marshal.ReleaseComObject(itm2);

GC.Collect();

}

label1.Text = i.ToString() + "/" + tot.ToString() + ": Dups found: " + dups + "\r\n" + dupindexes;

i++;

System.Runtime.InteropServices.Marshal.ReleaseComObject(itm);

GC.Collect();

}



Please help /Magnus
 
K

Ken Slovak - [MVP - Outlook]

Declare all objects explicitly and release them each pass through the loop
using Marshal.ReleaseComObject(). Try using a for() loop rather than a
foreach() loop, the foreach() is not only slower but also creates hidden
instance variables. Make sure no compound dot operators are being used.
Instantiate an explicit object for each dot operator, that way you can
release them explicitly.




Hello,

I'm trying to go through all contacts, and compare them to all other
contacts, to see if they are similar etc etc.
I seems to exceeds the limit of approx 255 open com objects, and I can't
figure out how to get my code to work.
As you can see I try to delete the objects, but I can't succeed.

My error which I get after several loops:

Unable to cast COM object of type 'System.__ComObject' to interface type
'Microsoft.Office.Interop.Outlook.ContactItem'. This operation failed
because the QueryInterface call on the COM component for the interface with
IID '{00063021-0000-0000-C000-000000000046}' failed due to the following
error: No such interface supported (Exception from HRESULT: 0x80004002
(E_NOINTERFACE)).

in the top I have: using ol = Microsoft.Office.Interop.Outlook;
and my procedure simplified:

ol.Application objOutlook = new ol.Application();

ol.MAPIFolder folder =
objOutlook.Session.GetDefaultFolder(ol.OlDefaultFolders.olFolderContacts);

ol.Items items = (ol.Items) folder.Items;

int i = 1; int tot = items.Count; int dups = 0;

string dupindexes = "none";

ol.ContactItem[] RemoveItems = new
Microsoft.Office.Interop.Outlook.ContactItem[10000];

foreach (ol.ContactItem itm in items)

{

int inclausecount = 0;

ol.MAPIFolder folder2 =
objOutlook.Session.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderContacts
);

ol.Items items2 = (ol.Items) folder2.Items;

foreach (ol.ContactItem itm2 in items2)

{

inclausecount++;

if (itm.CreationTime <= itm2.CreationTime) goto notmatch;

if (itm.Subject != itm2.Subject) goto notmatch;

dups++;

dupindexes += i.ToString() + ":" + itm.Subject + "\r\n";

itm2.Close(Microsoft.Office.Interop.Outlook.OlInspectorClose.olDiscard);

System.Runtime.InteropServices.Marshal.ReleaseComObject(itm2);

GC.Collect();

break;

notmatch:

System.Runtime.InteropServices.Marshal.ReleaseComObject(itm2);

GC.Collect();

}

label1.Text = i.ToString() + "/" + tot.ToString() + ": Dups found: " +
dups + "\r\n" + dupindexes;

i++;

System.Runtime.InteropServices.Marshal.ReleaseComObject(itm);

GC.Collect();

}



Please help /Magnus
 
M

Magnus

Thanks Ken,

I'm sure you're right, but unfortunately I didn't succeed. I still get the same error. j variable is 263 when this appears.
Could you please help me to see what's wrong with my code below?

Regards
/Magnus

ol.Application objOutlook = new ol.Application();

ol.MAPIFolder folder = objOutlook.Session.GetDefaultFolder(ol.OlDefaultFolders.olFolderContacts);

ol.Items items = (ol.Items) folder.Items;

string dups = "";

for (int j=1; j < items.Count;j++)

{

object obj = items[j];

ol.ContactItem itm = (ol.ContactItem) obj;

object obj2 = items.Find("[FullName] = '" + itm.FullName + "'");

ol.ContactItem itm2 = (ol.ContactItem) obj2;

if (itm2 != null)

{

if (itm.EntryID == itm2.EntryID) itm2 = (ol.ContactItem)items.FindNext();

if (itm2 != null)

{

dups += itm.FullName + "\r\n";

System.Runtime.InteropServices.Marshal.ReleaseComObject(itm2);

System.Runtime.InteropServices.Marshal.ReleaseComObject(obj2);

}

}

System.Runtime.InteropServices.Marshal.ReleaseComObject(itm);

System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);

}

MessageBox.Show(dups);


Ken Slovak - said:
Declare all objects explicitly and release them each pass through the loop
using Marshal.ReleaseComObject(). Try using a for() loop rather than a
foreach() loop, the foreach() is not only slower but also creates hidden
instance variables. Make sure no compound dot operators are being used.
Instantiate an explicit object for each dot operator, that way you can
release them explicitly.

--
Ken Slovak
[MVP - Outlook]
http://www.slovaktech.com
Author: Professional Programming Outlook 2007.
Reminder Manager, Extended Reminders, Attachment Options.
http://www.slovaktech.com/products.htm


Hello,

I'm trying to go through all contacts, and compare them to all other
contacts, to see if they are similar etc etc.
I seems to exceeds the limit of approx 255 open com objects, and I can't
figure out how to get my code to work.
As you can see I try to delete the objects, but I can't succeed.

My error which I get after several loops:

Unable to cast COM object of type 'System.__ComObject' to interface type
'Microsoft.Office.Interop.Outlook.ContactItem'. This operation failed
because the QueryInterface call on the COM component for the interface with
IID '{00063021-0000-0000-C000-000000000046}' failed due to the following
error: No such interface supported (Exception from HRESULT: 0x80004002
(E_NOINTERFACE)).

in the top I have: using ol = Microsoft.Office.Interop.Outlook;
and my procedure simplified:

ol.Application objOutlook = new ol.Application();

ol.MAPIFolder folder =
objOutlook.Session.GetDefaultFolder(ol.OlDefaultFolders.olFolderContacts);

ol.Items items = (ol.Items) folder.Items;

int i = 1; int tot = items.Count; int dups = 0;

string dupindexes = "none";

ol.ContactItem[] RemoveItems = new
Microsoft.Office.Interop.Outlook.ContactItem[10000];

foreach (ol.ContactItem itm in items)

{

int inclausecount = 0;

ol.MAPIFolder folder2 =
objOutlook.Session.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderContacts
);

ol.Items items2 = (ol.Items) folder2.Items;

foreach (ol.ContactItem itm2 in items2)

{

inclausecount++;

if (itm.CreationTime <= itm2.CreationTime) goto notmatch;

if (itm.Subject != itm2.Subject) goto notmatch;

dups++;

dupindexes += i.ToString() + ":" + itm.Subject + "\r\n";

itm2.Close(Microsoft.Office.Interop.Outlook.OlInspectorClose.olDiscard);

System.Runtime.InteropServices.Marshal.ReleaseComObject(itm2);

GC.Collect();

break;

notmatch:

System.Runtime.InteropServices.Marshal.ReleaseComObject(itm2);

GC.Collect();

}

label1.Text = i.ToString() + "/" + tot.ToString() + ": Dups found: " +
dups + "\r\n" + dupindexes;

i++;

System.Runtime.InteropServices.Marshal.ReleaseComObject(itm);

GC.Collect();

}



Please help /Magnus
 
K

Ken Slovak - [MVP - Outlook]

Make sure the release code for all of your objects is being executed each
pass through the loop. Call GC.Collect() each pass through the loop if
needed.

You also might want to test the Class of an object using reflection before
assigning it as a ContactItem to avoid an exception. Even in a contacts
folder you might run into DistListItems instead of ContactItems.




Thanks Ken,

I'm sure you're right, but unfortunately I didn't succeed. I still get the
same error. j variable is 263 when this appears.
Could you please help me to see what's wrong with my code below?

Regards
/Magnus

ol.Application objOutlook = new ol.Application();

ol.MAPIFolder folder =
objOutlook.Session.GetDefaultFolder(ol.OlDefaultFolders.olFolderContacts);

ol.Items items = (ol.Items) folder.Items;

string dups = "";

for (int j=1; j < items.Count;j++)

{

object obj = items[j];

ol.ContactItem itm = (ol.ContactItem) obj;

object obj2 = items.Find("[FullName] = '" + itm.FullName +
"'");

ol.ContactItem itm2 = (ol.ContactItem) obj2;

if (itm2 != null)

{

if (itm.EntryID == itm2.EntryID) itm2 =
(ol.ContactItem)items.FindNext();

if (itm2 != null)

{

dups += itm.FullName + "\r\n";

System.Runtime.InteropServices.Marshal.ReleaseComObject(itm2);

System.Runtime.InteropServices.Marshal.ReleaseComObject(obj2);

}

}

System.Runtime.InteropServices.Marshal.ReleaseComObject(itm);

System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);

}

MessageBox.Show(dups);
 
M

Magnus

Hi Ken,

I'm getting closer. Could you please send me an example of the reflection. I
can't get it work. I believe I try to read a non-contact item?

object obj = folder.Items[j];

ol.ContactItem itm = (ol.ContactItem)obj;

There goes wrong on the second row.

BR /Magnus
 
K

Ken Slovak - [MVP - Outlook]

I use something like this in the NewInspector() event handler. You need a
using statement for System.Reflection in the class:

Outlook.OlObjectClass _class = Outlook.OlObjectClass.olNote;

// set up to get the Class property of the item in the Inspector

object item = Inspector.CurrentItem;

Type _type;

_type = item.GetType();


object[] _args = new Object[] { }; // dummy argument array

try // try to get the Class using reflection

{

_class = (Outlook.OlObjectClass)_type.InvokeMember("Class",

BindingFlags.Public | BindingFlags.GetField |
BindingFlags.GetProperty,

null, item, _args);

}

catch (Exception ex)

{

MessageBox.Show(ex.Message);

}

You can then test the Class of the item to see if it's what you want to
handle.
 
M

Magnus

Thank you very much Ken,
Using error handling made my day:)
Regards
/Magnus

Ken Slovak - said:
I use something like this in the NewInspector() event handler. You need a
using statement for System.Reflection in the class:

Outlook.OlObjectClass _class = Outlook.OlObjectClass.olNote;

// set up to get the Class property of the item in the Inspector

object item = Inspector.CurrentItem;

Type _type;

_type = item.GetType();


object[] _args = new Object[] { }; // dummy argument array

try // try to get the Class using reflection

{

_class = (Outlook.OlObjectClass)_type.InvokeMember("Class",

BindingFlags.Public | BindingFlags.GetField |
BindingFlags.GetProperty,

null, item, _args);

}

catch (Exception ex)

{

MessageBox.Show(ex.Message);

}

You can then test the Class of the item to see if it's what you want to
handle.




Magnus said:
Hi Ken,

I'm getting closer. Could you please send me an example of the
reflection. I can't get it work. I believe I try to read a non-contact
item?

object obj = folder.Items[j];

ol.ContactItem itm = (ol.ContactItem)obj;

There goes wrong on the second row.

BR /Magnus
 
K

Ken Slovak - [MVP - Outlook]

The error handling is for failure to get the Class property. If you do get
it you should test it for the OlObjectClass member you want to deal with.
 
Top