RDO objects and C#

G

Guest

Hello Dmitry,

As of now I’m able to resolve the issue releasing COM objects without the
use of beta version. Anyhow many thanks for all your help.

I’m also able to resolve the issue of deleting emails. Thanks for your
invaluable support.

Regards
Amit Kathane

AK said:
Hi Dmitry,

I've emailed you the details, please send me the beta version at the earliest.

One more thing,

When I'm trying to traverse through a folder and deleting the emails it is
skipping some emails. I'll try to explain it using a example.

Say in folder Test there are 10 emails, out of which 3 emails (3rd, 5th and
7th) are qualified (older than say 2 months) to be deleted.

When i traverse for that folder using below code to delete it

=======================================
RDOMail rdoMail = rdoItems.GetFirst();
while (rdoMail != null)
{
try
{
// check if email can be deleted
if (DeleteEmail(rdoMail.UnRead, rdoMail.ReceivedTime,
rdoMail.Mileage))
{
if (DeleteMail)
rdoMail.Delete(0);
}
}
catch (Exception ex)
{
// in case of exception log the exception and process next email
Util.LogException(ex);
}
finally
{
Util.ReleaseComObject(rdoMail);
GC.Collect();
}
rdoMail = rdoItems.GetNext();
}
=============================================

it does not delete the 5th and 7th mail. I'm not sure but I guess the reason
for this is as soon as it deletes the 3rd mail the index of emails in folder
changes and hence it's not able to find the emails properly.

Is there any other way to traverse through folder and delete emails, so as
to find all emails. I tried storing index in array and then traversing folder
only for that array, but it didn't help. It would be helpful if there is any
direct method from RDO object library to do so.

Once again many thanks for your help.

Regards,
Amit Kathane

Dmitry Streblechenko said:
Marshal.ReleaseCOMObject releases a *particular* COM object. If you use
multiple dot notation, teh compiler creates an implicit variable to hodl the
intermediate resul(s). You cannot explicitly access and release these
implicit variables.
Senbd an e-mail to (e-mail address removed) , including the ShareIt reference
number of at least the name of the company woudl be helpful.

Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool

AK said:
Hi Dimitry,

Is it a limitation from .NET side that it's not able to release the COM
objects? It seems bit wired that it's not able to release the COM object
even
after calling Marshal.ReleaseCOMObject as well as using GC.Collect.

Anyhow, it surely will help if you can send me the beta version to try it
out. Do let me know what exactly I need to do for the same? Which account
I
should send an email to?

We have recently purchased the 4.4 version of Redemption library. Do you
want me to give any reference number for the same?

Many thanks for your help.
Regards,
Amit Kathane


:

The line
rdoFolder.Items;
evaluates to
rdoFolder.Items.Item(i)
So you are still using multiplee dot notation.

Do you want a beta version to see if it fixes this problem for you?

Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool

Hello Dmitry,

I'm using GC.Collect and modified my code to remove multiple dot
notations
(e.g. rdoFolder.Items.count) but still I'm getting an error for
"MAPI_E_CALL_FAILED".

This is happening especially for RDOMail object.

My code for it reads as

====================================================
Queue DeleteEMailQueue = new Queue();
RDOItems rdoItems = rdoFolder.Items;
for (int i = 0; i < rdoItems.Count; i++)
{
RDOMail rdoMail = rdoFolder.Items;
try
{
// check if email can be deleted
if (DeleteEmail(rdoMail.UnRead, rdoMail.ReceivedTime,
rdoMail.Mileage))
{
rdoMail.Delete(0);
}
}
catch (Exception ex)
{
Util.LogException(ex);
}
finally
{

System.Runtime.InteropServices.Marshal.ReleaseComObject(rdoMail);
rdoMail = null;
GC.Collect();
}
====================================================

The error occurs after reading say around 700/800 emails in one folder.

Can you please suggest any workaround for this?

Thanks and Regards,
Amit Kathane

:

You are most likely running out of the RPC channel limit
(http://support.microsoft.com/kb/830829) - since .Net does not release
COM
objects immediately, you can easily go over the limit even if you
explicitly
release COM objects using Marshal.ReleaseCOMObject.
Avoid using multiple dot notation (e.g. rdoFolder.Items.Count) to make
sure
the compiler does not create implicit variables that you cannot
reference
and release.
GC.Collect() might help.
Next version of Redemption (send me an e-mail if you want a beta
version)
will keep track of the open MAPI objeects and transparently release
oldest
unmodified MAPI objects that can be easily reopened on demand
(Redemption
objects will stay alive of course) when the number of open objects of
a
particular kind approaches the limit.

Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool

Hello Dmitry,

Thank you very much for your assistance.

I'm getting following error randomly.

"Error in IMAPIFolder.GetContentsTable: MAPI_E_CALL_FAILED"

Please find below my code

======================================
private static void ProcessUserMailbox(string userName)
{
RDOSession rdoSession = new RDOSessionClass();
try
{
// get the admin user name from the configuration
file
string systemUserName =
Properties.Settings.Default.userName;
string exchangeSrvrName =
Properties.Settings.Default.UserMailboxServer;

if (string.IsNullOrEmpty(systemUserName))
systemUserName =
WindowsIdentity.GetCurrent().Name.ToString();

rdoSession.LogonExchangeMailbox(systemUserName,
exchangeSrvrName);
IRDOFolder rootFolder =
rdoSession.GetSharedMailbox(userName).RootFolder;

// iterate through all folders and subfolders
RDOFolders rdoFolders = rootFolder.Folders;
if (rdoFolders != null)
{
RDOFolder rdoFolder = rdoFolders.GetFirst();
if (rdoFolder != null)
{
// iterate folder list
for (int i = 0; i < rdoFolders.Count; i++)
{
// process the individual folder to
search
for
emails that can be deleted
ProcessFolder(userName, rootFolder.Name +
"

",
rdoFolder);
rdoFolder = rdoFolders.GetNext();
}
}
}
// release the COM object for the root folder.

System.Runtime.InteropServices.Marshal.ReleaseComObject(rootFolder);
rootFolder = null;
}
catch (Exception ex)
{
StringBuilder strInfo = new
StringBuilder(string.Format("{0}, Failed to process mailbox for user
:
{0}",
userName));
Util.LogMessage(strInfo.ToString());
Util.LogException(ex);
strInfo.AppendFormat(ex.Message + Environment.NewLine
+
Util.GetInnerException(ex));
throw new ApplicationException(strInfo.ToString());
}
finally
{
rdoSession.Logoff();

System.Runtime.InteropServices.Marshal.ReleaseComObject(rdoSession);
rdoSession = null;
GC.Collect();
}
}

private static void ProcessFolder(string userName, string
folderPath, RDOFolder rdoFolder)
{
RDOFolders subFolders;
RDOFolder subFolder;

try
{
subFolders = rdoFolder.Folders;
if (subFolders != null)
{
subFolder = subFolders.GetFirst();
if (subFolder != null)
{
// iterate sub folder list
for (int i = 0; i < subFolders.Count;
i++)
{
// process the subfolder
ProcessFolder(userName,
rdoFolder.Name +
"

", subFolder);
subFolder = subFolders.GetNext();
}
}
}
// if found an individual folder (rdoFolder)
without
 
Top