问题
I'm developing an Office VSTO add-in in C# which looks up calendar appointments in Outlook, and reads/writes some data in them.
Recently, one of the clients had issues with the add-in, namely they can't read/write the calendar appointment, and it throws an exception :
The operation failed.
There's not much info from the exception log, but I suspect they have synchronization problems with Exchange.
I asked the client, and they said, that they also have a random popup in Outlook as well, which sometimes happens when there's a mishap while syncing with Exchange. I told them to 'repair' the Outlook data files, but that didn't fix the problem.
The outlook items are basically looked up based on their Outlook EntryIDs OR a Subject (the subjects are unique, and for the sake of simplicity I translated the code a little bit)
...main alghorythm...
Outlook.AppointmentItem calAppointment = null;
calAppointment = SearchforCalendarMatch(EntryID, Subject); //we try to find either by EntryID or by Subject
if (calAppointment != null)
{
calAppointment.Start = StartDate;
calAppointment.End = FinishDate;
calAppointment.Body = Notes;
calAppointment.Save(); //we're changing the found calendar appointment here
}
...
public Outlook.AppointmentItem SearchforCalendarMatch(String EntryID, String Subject)
{
Outlook.NameSpace ns = null;
Outlook.MAPIFolder calendarFolder = null;
Outlook.Items calendarFolderItems = null;
Outlook.Items filteredcalendarFolderItems = null;
Outlook.AppointmentItem calAppointment = null;
Outlook.Application OutlookApp = new Outlook.Application();
outlookversion = OutlookApp.Version;
ns = OutlookApp.Session;
//Try to find the calendar appointment by the EntryID
dynamic OutlookItem = ns.GetItemFromID(t.Text28);
if (OutlookItem != null)
{
if (OutlookItem is Outlook.AppointmentItem)
{
Outlook.AppointmentItem foundItem = (Outlook.AppointmentItem)OutlookItem;
return foundItem;
}
}
//If the EntryID was missing, we try to find the calendar appointment by the Subject.
//(original code is very long, and there are multiple things here, but let's just assume that 100% sure that the subject is unique, so it will find it)
String SubjectMatch = "[Subject] = '" + Subject + "'";
filteredcalendarFolderItems = calendarFolderItems.Restrict(SubjectMatch);
for (int i = 1; i <= filteredcalendarFolderItems.Count; i++)
{
//appointment has to be one of these
calAppointment = (Microsoft.Office.Interop.Outlook.AppointmentItem)filteredcalendarFolderItems[i];
if (!calAppointment.IsConflict) //conflict check here, not sure if it helps at all
{
return calAppointment; //this is not the complete code, but this is the basic idea of it.
}
}
}
Any ideas how I could make the application recognize these failed Exchange syncs, and handle them differently?
I would still like to sync in these cases, if it's possible... (change the 'local data' in Outlook, then let Outlook handle everything from that on)
回答1:
You need to release underlying COM objects instantly. Use System.Runtime.InteropServices.Marshal.ReleaseComObject to release an Outlook object when you have finished using it. This is particularly important if your add-in attempts to enumerate more than 256 Outlook items in a collection that is stored on a Microsoft Exchange Server. If you do not release these objects in a timely manner, you can reach the limit imposed by Exchange on the maximum number of items opened at any one time. Then set a variable to Nothing in Visual Basic (null in C#) to release the reference to the object. Read more about that in the Systematically Releasing Objects article.
来源:https://stackoverflow.com/questions/43782786/c-sharp-outlook-vsto-add-in-error-while-trying-to-get-item-in-an-exchange-setup