The operation cannot be performed

  • Thread starter Thread starter ck
  • Start date Start date
C

ck

Hi all,

I encountered the following error message while try to move a contact from
one folder to another folder.

-> Cannot move the items. The operation cannot be performed because the
message has been changed.

For your information, i add event handler for Contact_ItemRemove event. The
error will occur when i try to update UserProperties for the particular
contact.

I am using VSTO SE and Outlook 2007.

thanks!
 
That usually means that you have the item referenced in some other objects
that are causing a conflict, or that you haven't released objects that have
a reference to the item in some other location.
 
Hi Ken,

Thanks for the reply. Do you know how to check what object is referencing to
a contact item? Fyi, i have set the contact item to nothing and as far as i
concern, there are no more object are referencing the contact item.

Thanks.
 
There's no way to tell other than close study of your code and monitoring
the locals.
 
Hi Ken,

I manage to find the source of the problem. In my function
oExplorer_FolderSwitch(), i assign contact entry id to a variable called
myEntryID.

Everything work fine until I started to move one of my contact (Contact A)
from one folder to another folder. I am able to move Contact A to the another
folder on the first 2 time. After that, I am not able to move it anymore.

When i click on Contact A, the contact screen pop up. If i tried to edit the
name, company or any other contact information and save my changes, it will
prompt the following message:

- The item cannot be saved because it was changed by another user or in
another window. Do you want to make a copy in the default folder for the
item?

The strange thing is if i commented out the line:

myEntryID = oContact.EntryID

then it will work fine. I tried to used Marshal.ReleaseComObject to release
the oContact object but i still get the same problem.

It is anything wrong with my Outlook or it is just my code?

Below is the code for my add-in

My code
----------
Private Sub ThisAddIn_Startup(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.Startup
oExplorer = Me.Application.ActiveExplorer
End Sub

Private Sub oExplorer_FolderSwitch() Handles oExplorer.FolderSwitch
Dim oContact As Object
Dim itemIndex As Integer = 1
Dim myEntryID As String = ""

If oExplorer.Selection.Count > 0 Then
For itemIndex = 1 To oExplorer.Selection.Count
oContact = oExplorer.Selection.Item(itemIndex)
If (TypeOf oContact Is Outlook.ContactItem) Then
myEntryID = oContact.EntryID
End If

System.Runtime.InteropServices.Marshal.ReleaseComObject(oContact)
Next
End If
End Sub

Thanks in advance....
 
That loop of yours doesn't save anything, it just overwrites oContact and
myEntryID each pass through the loop. Is that just for testing purposes?

I'm sort of leery about using ReleaseComObject in loops like that unless I
need to. I've found it can destroy any reference to underlying objects, not
just the referenced object. For example, I have an Inspector handler with a
mail item. I also reference the mail item elsewhere. If I call
ReleaseComObject on the item in the Inspector handler it causes any
reference to the mail item elsewhere to fire an exception.

I'd probably first try setting the oContact object to Nothing instead of
calling ReleaseComObject.

I see nothing in the code you show that would cause the problem you cite, is
that the actual code? How are you moving the items, is it using the UI or
using code? Don't forget that if you are doing it in the UI you might be
firing the Explorer.FolderSwitch event on that new folder object. I'd
probably be using BeforeFolderSwitch for whatever needed to be done for a
new folder view and then using Explorer.SelectionChange to handle items in
the Selection.

Also, don't assume that you will always have an ActiveExplorer object.
Outlook can be started using automation with no Explorers. Either use
Application.Explorers.Item(1) after checking Application.Explorers.Count or
wrap your use of ActiveExplorer in a Try...Catch block.
 
Ken,

Yes. This code is posted is just for testing purposes. I am using the UI to
move the contact item from one folder to another folder. After moving the
contact from one folder to another for few times, the contact will be
'locked'.

Try to open the contact, make some changes on the contact details and save
the contact. I will encounter this message:

- The item cannot be saved because it was changed by another user or in
another window. Do you want to make a copy in the default folder for the
item?

Well, i did follow your advise by removing:

System.Runtime.InteropServices.Marshal.ReleaseComObject(oContact)

and adding:

oContact = Nothing
GC.Collect()

Then the problem will go away. I think it has to do with the garbage
collection in .Net framework.

By setting oContact = Nothing will not really removed the oContact object
reference. I need to specify GC.Collect() keyword but this is a very
expensive operation. I am wondering if there is any other better method on
releasing resources...
 
It may be expensive in time but that's what you have to do. In managed code
there is no way to know when a COM object you dispose of will actually be
garbage collected unless you use GC.Collect() and even sometimes using
WaitForPendingFinalizers() after that.
 
Back
Top