Direction/Help required for not to save MailItems in Sent Folder

  • Thread starter Thread starter PS
  • Start date Start date
P

PS

Hi

I am currently working on an Outlook addin devloped using C# and VSTO
2005. In the MailItem_ItemSend - all my custom logic takes place.

So the scenario i have is once i get the mailitem here - i do some
processing here (like based on the number of recicps) - I create copy
of orig emails (each having one recip) and then those emails actually
go out. The original email which the sender had clicked to send
does(should) not go out.

The problem(s) I am facing is are:

1. How do I move the original email to Sent Items folder of the Sender
(so that the sender can refer the email again in its entirity for
future purposes)

2. I dont want the copies of email generated programatically to be
seen in Sent Items folder of the sender. How do i stop that from
happening.

Please - any help/direcction in this regard would really be helpful.

Thanks
 
After cancelling the send you would have to save the item to make sure it
has an EntryID, then close the item after storing the EntryID and get the
item as a new item using NameSpace.GetItemFromID(), then use the Move method
to move it to Sent Items. Note that the item will not show up as sent, it
will be an unsent message.

Set the DeleteAfterSubmit property on each of the items that you don't want
put in Sent Items.
 
Thanks a lot Ken for the quick response.

Regarding the first part - is all this possible through Outlook Object
Model (not want to use Redemption).

Also will look into code samples doing the apporach you have
mentioned. Is doing this normal - meaning no side issues related to
doing this manually (setting EntryID etc).

Just wanted to see ur thoughts on that

Thanks once agian
 
You can use the Outlook object model for that. I have no idea what you mean
about setting the EntryID, Outlook creates the EntryID when you save the
item. Once it's saved and released you can re-open it and move it anywhere
you like.
 
Ken

Thanks for the response. I now understand the Entry ID part but have
some issues with the real code implementation:

1. I looked for cancelling the Send event on the original email. Cant
seem to find any code. Can you please point this to me. I am really
having a hard time finding this.

Also I see this - myItem.SavveSentMessageFolder --> which i believe i
can use to save the email directly into the sent message folder. This
may avoid the MyItem.Save and then moving?

What do you suggest.

Thanks
 
There are 2 possibilities for canceling a send. The first event is
item.Send, which fires initially when the user clicks send. That event is on
the MailItem and fires only in that item. The second event is the
Application.ItemSend event, which is an application-wide event.

In either event all you do is set Cancel = true to cancel the send
operation.

SaveSentMessageFolder takes a MAPIFolder as an argument and provides a way
of setting that one specific item to save in your folder of choice. The
property is only used after the after is sent out, so it's of no use when
cancelling a send. You could set that property to Drafts, My Old Outgoing
Mail, Sent Items, or wherever else you want.

DeleteAfterSubmit is a Boolean property that when set will delete the sent
item after it's sent out and leave no copies behind.
 
I looked into this more all of last night - but cant seem to find
(sorry for my ignorance) - how to stop/cancel the send event of an
email and then close it properly. Even if it stays in inblx it is fine
because using the .Move method is very easy or as I mentioned
myItem.SavveSentMessageFolder possibly.

But please Ken - can you please point me how to do that

Thanks
 
Ken

Thanks for the really quick response. I am actually doing that -
setting cancel = true (in MailItem_Send event) and that works fine. I
was thinking the implementation was something different. Beucase when
i do that - that ofcourse stops the email from going out - but the
actual email stays open.

Reading back your first post - it means that after doing that
(cancel=true) I need to call the MyItem.Save first (which I believe
will save it in inbox) and then MyItem.Close or something similar (do
i need to call that because i belive the save only saves the email but
does not close it)

Does that approach sound right?

Thanks a lot once again. really helping me
 
That's correct. You most likely will be best off in setting a timer to go
off maybe 1/2 second or so after you exit the item.Send event and then in
the timer event call item.Close. So the sequence would be:

In Item.Send:
Save item
Get item EntryID
Cancel Save event
Set timer

In timer event:
Close the item

Now at that point the item is closed so you need to find a way to get at it
to move it or whatever. So in the timer event set a flag to true to indicate
that the item was closed by you. Then in the close event set up an array of
the item EntryID and StoreID (item.Parent.StoreID) and set another timer to
fire later on. Release all of your objects so the object is completely
uninstantiated. In the later timer event read the global array or collection
or whatever and get the item and move it where you want or do whatever with
it.
 
Ken

I was implementing the above discussed content and am getting an error
(which I believe shouldnt be the case) when working with the Mail
Close logic

In the MailItem_Send event as discussed - after setting Cancel = true
- in the end I start a timer event which lets say gets called after 3
seconds

But still get this error on
Marshal.FinalReleaseComObject(myMailItem);:

Error Text:
RaceOnRCWCleanup was detected
Message: An attempt has been made to free an RCW that is in use. The
RCW is in use on the active thread or another thread. Attempting to
free an in-use RCW can cause corruption or data loss.

Code here:

private void MailItem_ItemSend(ref bool Cancel)
{
Business Logic here..

If certain business condition is true then.
Cancel = true
Then Timer Logic (which is below)
Timer delay = new Timer();
delay.Enabled = true;
delay.Interval = 10000;
delay.Tick += new EventHandler(delay_Tick);
}

void delay_Tick(object sender, EventArgs e)
{
myMailItem.Close(Ol.OlInspectorClose.olSave);
Or Even tried below:
myMailItem.Delete();
}

private void MailItem_ItemClose(ref bool Cancel)
{
try
{
//Execute cleanup only if the item has not changed, b'coz the
message box prompts users to save the message is displayed
//after this event. That message box also gives the user
the ability to cancel the event
//so we do not want to unwire the events here if the
message is "dirty"
if (this.isSent || myMailItem.Saved)
{
CleanMailItemEvents();
//Some more cleannup
}
}
}

public void CleanMailItemEvents()
{
Ol.ItemEvents_10_Event _myMailItemEvents = myMailItem as
Ol.ItemEvents_10_Event;
_myMailItemEvents.Close -= new
Ol.ItemEvents_10_CloseEventHandler(MailItem_ItemClose);
_myMailItemEvents.Send -= new
Ol.ItemEvents_10_SendEventHandler(MailItem_ItemSend);
_myMailItemEvents.Forward -= new
Ol.ItemEvents_10_ForwardEventHandler(MailItem_ItemForward);
_myMailItemEvents.Reply -= new
Ol.ItemEvents_10_ReplyEventHandler(MailItem_ItemForward);
_myMailItemEvents.ReplyAll -= new
Ol.ItemEvents_10_ReplyAllEventHandler(MailItem_ItemRelpyAll);
_myMailItemEvents = null;
Marshal.FinalReleaseComObject(myMailItem);
myMailItem = null;
}
 
See if Marshal.ReleaseComObject works any better. If not think about not
calling that function at all.
 
Ken

Sorry for the late reply on this.

I actually was able to do a Move on the email - when in the Item send
method and that actually worked (once i supply the folder name). That
moves the email and also closes the original after the move.

This saves the effort of maintaining those variables in global in the
close event.

Thanks
Pratik
 
Back
Top