कैलेंडर आइटम्स (Outlook API, WebDAV) को अजीब व्यवहार प्रदर्शित करें


79

हम एक एमएस आउटलुक प्लगइन लिख रहे हैं। हमारे व्यापार-तर्क को संतुष्ट करने के लिए, इसे कुछ तिथियों के बीच सभी नियुक्तियों की जांच करनी चाहिए। हम कैलेंडर से सभी आइटम पुनर्प्राप्त करने के साथ कई समस्याओं का सामना कर रहे हैं। हमने दो विकल्प आज़माए:

  1. आउटलुक एपीआई। हम MSDN में वर्णित मानक तर्क का उपयोग करते हैं - जैसे आइटमों को [स्टार्ट] द्वारा सेट करें , यहाँ जैसे कैलेंडर आइटम्स पर Find \ Restrict क्वेरी IncludeRecurrencesको सेट करें Trueऔर चलाएं । यह हमारे परीक्षण वातावरण में ठीक काम करता है। हालांकि, हमारे ग्राहक के वातावरण में: आवर्ती नियुक्तियों के लिए, प्रारंभ और समाप्ति तिथियां 'मास्टर अपॉइंटमेंट' की संबंधित तिथियों पर निर्धारित होती हैं। उदाहरण के लिए, किसी कमरे के कैलेंडर में हमारी साप्ताहिक नियुक्ति है जो जनवरी में बनाई गई थी, और अगर हम अगस्त में सभी वस्तुओं को खोजने की कोशिश करते हैं, तो हम दूसरों के बीच इस आवर्ती नियुक्ति के चार आइटम प्राप्त करते हैं, लेकिन उनकी शुरुआत और अंतिम तिथियां जनवरी में निर्धारित होती हैं । लेकिन आउटलुक उसी कैलेंडर में सही तिथियां प्रदर्शित करता है ...

  2. बहुत बुरा है, लेकिन हम अभी भी WebDAV है! हम एक साधारण परीक्षण एप्लिकेशन लिखते हैं और WebDAV का उपयोग करते हुए कैलेंडर से सभी वस्तुओं को क्वेरी करने का प्रयास करते हैं। बेशक, हमने पहिया को सुदृढ़ नहीं किया और सिर्फ प्रलेखन से कोड चिपकाया । पिछली समस्या हल हो गई है, लेकिन अगला उठता है: यह आवर्ती आइटम वापस नहीं करता है जो लगभग छह महीने पहले बनाए गए थे। मुझे कोई सुराग नहीं है - 'पुराने' आइटम को प्रतिबंधित करने वाले कोई पैरामीटर नहीं हैं!

गलत क्या है? क्या हम कुछ महत्वपूर्ण याद कर रहे हैं?

तकनीकी विवरण: एक्सचेंज 2003, आउटलुक 2003-2010। स्पष्ट रूप से, यदि हम कैश्ड एक्सचेंज मोड को चालू करते हैं, तो पहली त्रुटि गायब हो जाती है, लेकिन हम ऐसा नहीं कर सकते।

var nameSpace = application.GetNamespace("MAPI");
var recepient = nameSpace.CreateRecipient(roomEMail);
recepient.Resolve();
var calendar = nameSpace.GetSharedDefaultFolder(recepient, OlDefaultFolders.olFolderCalendar);
var filter = string.Format("[Start]<'{1}' AND [End]>'{0}'",
  dateFrom.ToString("dd/MM/yyyy HH:mm", CultureInfo.InvariantCulture), dateTo.ToString("dd/MM/yyyy HH:mm", CultureInfo.InvariantCulture)
);
var allItems = calendar.Items;
allItems.Sort("[Start]");
allItems.IncludeRecurrences = true;
var _item = allItems.Find(filter);
while (_item != null) {
  AppointmentItem item = _item as AppointmentItem;
  if (item != null) {
    if (item.Subject != "some const")
      && (item.ResponseStatus != OlResponseStatus.olResponseDeclined)
      && (item.MeetingStatus != OlMeetingStatus.olMeetingReceivedAndCanceled 
      && item.MeetingStatus != OlMeetingStatus.olMeetingCanceled))
    {
      /* Here we copy item to our internal class.
       * We need: Subject, Start, End, Organizer, Recipients, MeetingStatus,
       * AllDayEvent, IsRecurring, RecurrentState, ResponseStatus,
       * GlobalAppointmentID */
    }
  }
  _item = allItems.FindNext();
}

अद्यतन 1:

OutlookSpy का उपयोग करते हुए अतिरिक्त शोध से पता चलता है कि समस्या हमारे कोड में नहीं है - कैश्ड एक्सचेंज मोड बंद होने पर एपीआई के अंदर स्टार्ट एंड एंड डेट गलत हैं। लेकिन आउटलुक डेवलपर्स को इसके बारे में पता था, और वे किसी भी तरह कैलेंडर में सही तारीखों को प्रदर्शित करते हैं! क्या किसी को पता है कैसे?

अद्यतन 2:

आउटलुक समर्थन वृद्धि इंजीनियर से जवाब:

इसके आधार पर, मैं पुष्टि कर सकता हूं कि यह हमारे उत्पाद में एक समस्या है।


3
1. आपका कोड क्या है? 2. WebDAV का उपयोग न करें; यह पदावनत है।
दिमित्री स्ट्रेबलेंको

बिल्कुल ठीक लगता है ... आपका कोड क्या है जो अपॉइंटमेंट तक पहुँचता है? क्या आप कभी भी AppointmentItem.Parent का उपयोग करते हैं (जो आपको आवर्ती गतिविधि के उदाहरण के लिए मास्टर अपॉइंटमेंट देगा)?
दिमित्री स्ट्रेबलचेंको

मैंने ऊपर कोड अपडेट किया है। नहीं, हम AppointmentItem.Parent का उपयोग नहीं करते हैं। वैसे भी, प्रारंभ और समाप्ति तिथियों तक पहुँचने से पहले, हम केवल अपॉइंटमेंट इटेम के विषय, रिस्पांसस्टैटस और मीटिंगस्टैटस गुणों को ही एक्सेस करते हैं।
बोलिक

एक चीज़ के लिए, Outlook कैलेंडर फ़ोल्डर सामग्री को प्रदर्शित करने के लिए OOM का उपयोग नहीं करता है, दूसरी बात, आपको क्यों लगता है कि प्रारंभ / समाप्ति दिनांक गलत हैं? क्या गलत है?
दिमित्री स्ट्रेबलचेंको

सटीक रूप से: OutlookSpy हमें एक ही StartTime के साथ कई नियुक्तियों को दिखाता है, हमारे मामले में = 11/01/2012, और यह निश्चित रूप से आवर्ती साप्ताहिक गतिविधि (एक ही आयोजक, एक ही विषय, आदि) की मास्टर नियुक्ति है। लेकिन कैलेंडर में हम सही तस्वीर देख सकते हैं - प्रत्येक सप्ताह में एक आइटम। मैं बहुत सराहना करता हूं यदि आप बता सकते हैं कि आउटलुक कैसे काम करता है, कैलेंडर प्रदर्शित करने के लिए यह किस तकनीक का उपयोग करता है, किसी भी विचार का हमें ओओएम में गलत परिणाम क्यों मिलता है और इन त्रुटियों को कैसे ठीक किया जाए?
बोलिक

जवाबों:


1

संभावित कारण:

  • इन्क्लियरेंस सेट करने के बाद सॉर्ट करें।

यहां मेरा कोड एक PowerShell मॉड्यूल है जो दो तिथियों के बीच आउटलुक आइटम को पुनर्प्राप्त करता है।

और परिवर्तनों की जांच करने और एजेंडा अपडेट सहित एक ईमेल भेजने के लिए एक छोटा सा एपलेट, जो एक्सचेंज में मोबाइल एक्सेस नहीं होने पर काम आता है।

पथ: दस्तावेज़ \ WindowsPowerShell \ Modules \ Outlook \ expcal.ps1

Function Get-OutlookCalendar
{
  <#
   .Synopsis
    This function returns appointment items from default Outlook profile
   .Description
    This function returns appointment items from the default Outlook profile. It uses the Outlook interop assembly to use the olFolderCalendar enumeration.
    It creates a custom object consisting of Subject, Start, Duration, Location
    for each appointment item.
   .Example
    Get-OutlookCalendar |
    where-object { $_.start -gt [datetime]"5/10/2011" -AND $_.start -lt `
    [datetime]"5/17/2011" } | sort-object Duration
    Displays subject, start, duration and location for all appointments that
    occur between 5/10/11 and 5/17/11 and sorts by duration of the appointment.
    The sort is the shortest appointment on top.
   .Notes
    NAME:  Get-OutlookCalendar
    AUTHOR: ed wilson, msft
    LASTEDIT: 05/10/2011 08:36:42
    KEYWORDS: Microsoft Outlook, Office
    HSG: HSG-05-24-2011
   .Link
     Http://www.ScriptingGuys.com/blog
 #Requires -Version 2.0
 #>

 echo Starting... Initialize variables

 Add-type -assembly "Microsoft.Office.Interop.Outlook" | out-null
 $olFolders = "Microsoft.Office.Interop.Outlook.OlDefaultFolders" -as [type]
 $olCalendarDetail = "Microsoft.Office.Interop.Outlook.OlCalendarDetail" -as [type]

 echo ... Getting ref to Outlook and Calendar ...

 $outlook = new-object -comobject outlook.application
 $namespace = $outlook.GetNameSpace("MAPI")
 $folder = $namespace.getDefaultFolder($olFolders::olFolderCalendar)

 echo ... Calculating dates ...

 $now = Get-Date -Hour 0 -Minute 00 -Second 00

 echo From $a To $b

 echo ... Getting appointments ...

 $Appointments = $folder.Items
 $Appointments.IncludeRecurrences = $true
 $Appointments.Sort("[Start]")

 echo ... Setting file names ...

 $oldfile = "$env:USERPROFILE\outlook-calendar.bak"
 echo oldfile: $oldfile
 $newfile = "$env:USERPROFILE\outlook-calendar.txt"
 echo newfile: $newfile
 $calfile = "$env:USERPROFILE\outlook-calendar.ics"
 echo calfile: $calfile

 echo ... Exporting calendar to $calfile ...

 $calendarSharing = $folder.GetCalendarExporter()
 $calendarSharing.CalendarDetail = $olCalendarDetail::olFullDetails
 $calendarSharing.IncludeWholeCalendar = $false
 $calendarSharing.IncludeAttachments = $false
 $calendarSharing.IncludePrivateDetails = $true
 $calendarSharing.RestrictToWorkingHours = $false
 $calendarSharing.StartDate = $now.AddDays(-30)
 $calendarSharing.EndDate = $now.AddDays(30)
 echo $calendarSharing
 $calendarSharing.SaveAsICal($calfile)

 echo ... Backing up $newfile into $oldfile ...

 if (!(Test-Path $newfile)) {
  echo "" |Out-File $newfile
 }

 # Backup old export into $oldfile
 if (Test-Path $oldfile) {
  echo "Deleting old backup file $oldfile"
  del $oldfile 
 }
 echo " ... moving $newfile into $oldfile ... "
 move $newfile $oldfile

 echo "... Generating text report to file $newfile ..."

 $Appointments | Where-object { $_.start -gt $now -AND $_.start -lt $now.AddDays(+7) } | 
  Select-Object -Property Subject, Start, Duration, Location, IsRecurring, RecurrenceState  |
  Sort-object Start |
  Out-File $newfile -Width 100

 echo "... Comparing with previous export for changes ..."

 $oldsize = (Get-Item $oldfile).length
 $newsize = (Get-Item $newfile).length

 if ($oldsize -ne $newsize ) {
  echo "!!! Detected calendar change. Sending email..."
  $mail = $outlook.CreateItem(0)

  #2 = high importance email header
  $mail.importance = 2

  $mail.subject = $env:computername + “ Outlook Calendar“

  $mail.Attachments.Add($newfile)
  $mail.Attachments.Add($calfile)
  $text = Get-Content $newfile | Out-String
  $mail.body = “See attached file...“ + $text

  #for multiple email, use semi-colon ; to separate
  $mail.To = “your-email@your-mail-domain.com“

  $mail.Send()

 }
 else {
  echo "No changes detected in Calendar!"
 }


} #end function Get-OutlookCalendar

Function Get-OutlookCalendarTest
{
 echo starting...
 Add-type -assembly "Microsoft.Office.Interop.Outlook" | out-null
 $olFolders = "Microsoft.Office.Interop.Outlook.OlDefaultFolders" -as [type]
 $outlook = new-object -comobject outlook.application
 $namespace = $outlook.GetNameSpace("MAPI")
 $folder = $namespace.getDefaultFolder($olFolders::olFolderCalendar)

 $a = Get-Date -Hour 0 -Minute 00 -Second 00
 $b = (Get-Date -Hour 0 -Minute 00 -Second 00).AddDays(7)
 echo From $a To $b

 $Appointments = $folder.Items
 $Appointments.IncludeRecurrences = $true
 $Appointments.Sort("[Start]")

 $Appointments | Where-object { $_.start -gt $a -AND $_.start -lt $b } | Select-Object -Property IsRecurring, RecurrenceState, Subject, Start, Location

} #end function Get-OutlookCalendarTest

यह मॉड्यूल में PowerShell फ़ंक्शन को लागू करने के लिए कोड है:

पथ: दस्तावेज़ \ WindowsPowerShell \ mono.ps1

Import-Module -Name Outlook\expcal.psm1 -Force

$i=0

#infinite loop for calling connect function   
while(1)
{
   $i = $i +1
   Write-Output "Running task Get-OutlookCalendar ($i)"
   Get-OutlookCalendar

   start-sleep -seconds 300

}

PowerShell स्क्रिप्ट को चलाने के लिए, powerhell.exe का उपयोग करें। स्टार्टअप पर इसे चलाने के लिए, "% APPDATA% \ Microsoft \ Windows \ Start Menu \ Programs \ Startup \" पर एक शॉर्टकट: "

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass "C:\Users\%USERNAME%\Documents\WindowsPowerShell\mono.ps1"
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.