背景:我在C#(.NET 3.5)中編寫一個應用程序,該應用程序查看多個用戶Outlook 2003日曆(使用COM對象),獲取約會並將這些約會的數據插入數據庫。Outlook 2003 - 顯示首次出現的重複項目開始/結束日期
問題:在第一個用戶日曆之後,下列日曆中的任何重複項目始終會有該項目第一次出現的開始和結束時間。我發佈了用戶之間的COM對象(並且在用戶有很多項目的情況下),並且正在限制項目集合(由於只有少數插入的重複任務(儘管錯誤的開始/結束)而不是無限的「無盡」任務)。正確的開始/結束時間是需求的一部分,讓這個或另一個應用程序可用這些信息計算出用戶在給定的日期範圍和工作時間內有多少空閒時間。
代碼:(變量聲明省略,他們在相關功能上)
通過用戶循環(在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
}
}
從提取信息日曆
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's 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's 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");
}
}
也許試試Redemption(我相信那裏是一個試驗)。我遇到了與Exceptions集合類似的問題,但打開RDOAppointmentItem並使用RDO(而不是OOM)和問題「解決了」(當然,這也意味着我可能也會微妙地RCW泄漏)。也許有類似的真棒給你... – 2011-12-22 05:49:58