Outlook 2003 - recurring items showing the start and end dates of the first appearance

Background . I am writing a C # application (.NET 3.5) that scans multiple Outlook 2003 calendars (using COM objects), receives appointments, and inserts the data for these appointments into a database.

Problem: After the first user calendar, any duplicate elements in the following calendars will always have the beginning and end of the first occurrence of this element. I am releasing COM objects between users (and during, if the user has many elements), and the collection of elements is limited correctly (due to the fact that only a few repeated tasks are inserted into it (although the start / end is incorrect) instead of the endless task " without end "). The correct start / end time is part of the requirements, having the information available for this or another application to determine how much free time the user has for a given date range and working time.

Code: (variable declarations are not specified, they are at the top of the corresponding functions)

Quoting through users (in Main ()):

foreach (DataRow drUserCalendar in dtCalendars.Rows) { //for each calendar we're looking at, export their calendar data and put it in the database try { appOutlook = new Outlook.Application(); ExportCalendar(drUserCalendar); Marshal.FinalReleaseComObject(appOutlook); GC.Collect(); } catch (Exception ex) { //report error } } 

Retrieving Calendar Information

 static void ExportCalendar(DataRow drUser) { strDisplayName = drUser["DisplayName"].ToString(); strUserID = drUser["ID"].ToString(); int.TryParse(drUser["PreviousDays"].ToString(), out intPrevious); int.TryParse(drUser["FutureDays"].ToString(), out intFuture); dtmAllowedPreviousStart = DateTime.Now.AddDays(-intPrevious); dtmAllowedFutureStart = DateTime.Now.AddDays(intFuture); nsOne = appOutlook.GetNamespace("MAPI"); nsOne.Logon(null, null, false, false); rcpOne = nsOne.CreateRecipient(strDisplayName); intCount = 0; if (rcpOne.Resolve()) { fldOne = nsOne.GetSharedDefaultFolder(rcpOne, Outlook.OlDefaultFolders.olFolderCalendar); strRestrict = "[Start] > '" + MIN_START_DATE.ToString("g") + "' And [End] < '" + MAX_START_DATE.ToString("g") + "'"; itms = fldOne.Items; itms.Sort("[Start]", Type.Missing); itms.IncludeRecurrences = true; itmsRestricted = itms.Restrict(strRestrict); itmsRestricted.Sort("[Start]", Type.Missing); itmsRestricted.IncludeRecurrences = true; blnIsRecurring = false; dicRecurringTaskTracker = new Dictionary<string, int>(); foreach (object objOne in itmsRestricted) { if (intCount >= 100 || blnIsRecurring) { //release COM objects. Outlook doesn't like you having more than 250 ish items without cleaning up. Marshal.FinalReleaseComObject(appOutlook); appOutlook = new Outlook.Application(); GC.Collect(); intCount = 0; } if (objOne is Outlook.AppointmentItem) { appItem = (Outlook.AppointmentItem)objOne; blnException = false; //get data from the item strEntryID = appItem.EntryID; strSubject = appItem.Subject; strBody = appItem.Body; dtmStart = appItem.Start; dtmEnd = appItem.End; blnException = EXCEPTIONS.Contains(strSubject); //if the item is an exception we're done with it. if (!blnException) { strRecurrenceInterval = ""; strRecurrenceType = ""; strRecurrenceInfo = ""; //check if it a recurring task. blnIsRecurring = appItem.IsRecurring; if (blnIsRecurring) { //check to see if we've already had a task from this series if (!dicRecurringTaskTracker.Keys.Contains(strEntryID)) { //Start at 0 so the first (this) task //is number 1. dicRecurringTaskTracker.Add(strEntryID, 0); } //update number dicRecurringTaskTracker[strEntryID] += 1; //change the subject to add the count on the end strEntryID = strEntryID + '-' + dicRecurringTaskTracker[strEntryID].ToString(); //it a recurring task, so we need to find out when/how often. rpTaskRecurrence = appItem.GetRecurrencePattern(); rtTaskRecurrenceType = rpTaskRecurrence.RecurrenceType; strRecurrenceType = rtTaskRecurrenceType.ToString(); strRecurrenceInterval = rpTaskRecurrence.Interval.ToString(); switch (strRecurrenceType) { case "olRecursDaily": case "olRecursMonthNth": case "olRecursWeekly": strRecurrenceInfo = rpTaskRecurrence.DayOfWeekMask.ToString(); break; case "olRecursMonthly": strRecurrenceInfo = rpTaskRecurrence.DayOfMonth.ToString(); break; } } if (strEntryID != null && strSubject != null && dtmStart != null && dtmEnd != null && (intPrevious == 0 || (dtmStart > dtmAllowedPreviousStart)) && (intFuture == 0 || (dtmStart < dtmAllowedFutureStart))) { //build up the SQL strSQL = "EXEC UpdateCalendarEntry "; strSQL += "@EntryID='" + strEntryID + "', "; strSQL += "@Subject='" + strSubject.Replace("'", "''") + "', "; strSQL += "@Body='" + strSubject.Replace("'", "''") + "', "; strSQL += "@StartDate='" + dtmStart.ToString("dd-MMM-yyyy HH:mm:ss") + "', "; strSQL += "@EndDate='" + dtmEnd.ToString("dd-MMM-yyyy HH:mm:ss") + "', "; strSQL += "@UserCalendarID=" + strUserID + ","; strSQL += "@Recurring = " + blnIsRecurring.ToString() + ","; strSQL += "@RecurrenceType = '" + strRecurrenceType + "',"; strSQL += "@RecurrenceInterval = '" + strRecurrenceInterval + "',"; strSQL += "@RecurrenceInfo = '" + strRecurrenceInfo + "';"; try { //Execute SQL } catch (Exception ex) { //Print error message MessageBox.Show(ex.ToString()); } } } Marshal.FinalReleaseComObject(appItem); GC.Collect(); } strEntryID = null; strSubject = null; strBody = null; intCount++; } //finished looping, do some clean up. Marshal.FinalReleaseComObject(nsOne); Marshal.FinalReleaseComObject(rcpOne); Marshal.FinalReleaseComObject(fldOne); Marshal.FinalReleaseComObject(itms); Marshal.FinalReleaseComObject(itmsRestricted); GC.Collect(); } else { throw new Exception("Could not resolve name"); } } 
+4
source share
2 answers

After testing, I found that the problem is related to my (or someone who launches the application) permissions on the (shared) calendars viewed by the user.

He works for the first user, because he is in this case. After that, it does not work for users, because I do not have sufficient rights (this is confirmed by the fact that my colleague is changing it, so the default users are “owners” in their calendar and start the application again, and it works for their calendar),

Since then I have been trying to use GetOccurrence(DateTime) (surrounded by a while loop), however this leads to the same problem. The function would be a mistake if there were no occurrence (as expected), but when it detected the occurrence, it returned a null object.

However, due to the fact that I did not use the object for anything other than getting the start and end dates of the task, I worked with it manually (I had an original task, that is, I could get a duration, increasing every day until I get message that I get the start date of the repeated tasks, and using the duration of the task that I calculated, the end date).

This is not an ideal solution, but if you just want to get repetitive tasks, then it's quite simple to do (although the resource consumes if you have many repetitive tasks and the cycle lasts a long time)

0
source

I don't see an obvious problem with your code, I'm afraid, but since I expect you to understand well that there are probably some other things going on behind the scenes that cause your problem.

I looked at some of the things that I thought were the best when I worked with this material in a blog article - http://jynxeddevelopment.blogspot.com . Maybe it’s worth a read, if something looks like what you are doing, I think the section “Keep links to everything” might be useful.

I'm not sure that your COM objects will be compiled with a GC call, since you do not set them to null at first, however this should not matter in any case. I got this job without any GC calls.

What to see:

  • OBJOne should be released EVERY loop if it is a COM object (I expect it to be)
  • Closing the Outlook application before its release (appOutlook.Close ()), I am surprised that you are not getting a lot of them hanging around
  • Examine all the fields that you use on the COM object, if they are also COM objects. Finalization may also be required.

Sorry, this is nothing concrete, but working with this material is hard work: / Good luck!

-Jynx

0
source

Source: https://habr.com/ru/post/1384307/


All Articles