Development Tip

비정상적인 동작을 표시하는 일정 항목 (Outlook API, WebDAV) 검색

yourdevel 2020. 10. 10. 12:09
반응형

비정상적인 동작을 표시하는 일정 항목 (Outlook API, WebDAV) 검색


우리는 MS Outlook 플러그인을 작성하고 있습니다. 비즈니스 로직을 만족 시키려면 일부 날짜 사이의 모든 약속을 확인해야합니다. 달력에서 모든 항목을 검색하는 데 몇 가지 문제가 발생했습니다. 두 가지 옵션을 시도했습니다.

  1. Outlook API. [시작]을 기준으로 정렬 항목, 세트 - 우리는 표준 MSDN에 설명되어있는 논리를 사용 IncludeRecurrencesTrue와 항목이 달력을 통해 쿼리 제한 \ 찾기를 실행 여기에 좋아 . 테스트 환경에서 잘 작동합니다. 그러나 고객 환경에서 : 되풀이 약속의 경우 시작 및 종료 날짜가 '마스터 약속'의 해당 날짜로 설정됩니다. 예를 들어, 어떤 방의 캘린더에는 1 월에 생성 된 주간 약속이 있고 8 월에 모든 항목을 찾으려고하면이 반복 약속의 4 개 항목이 있지만 시작 및 종료 날짜는 1 월로 설정됩니다. . 하지만 Outlook은 동일한 캘린더에 정확한 날짜를 표시합니다.

  2. 매우 나쁘지만 여전히 WebDAV가 있습니다! 간단한 테스트 응용 프로그램을 작성하고 WebDAV를 사용하여 달력의 모든 항목을 쿼리합니다. 물론 우리는 바퀴를 재발 명하지 않고 문서 에서 코드를 붙여 넣었습니다 . 이전 문제는 해결되었지만 다음 문제가 발생합니다. 약 6 개월 전에 생성 된 반복 항목을 반환하지 않습니다. 단서가 없습니다. '오래된'항목을 제한하는 매개 변수가 없습니다!

뭐가 잘못 되었 니? 중요한 것을 놓치고 있습니까?

기술 세부 정보 : Exchange 2003, Outlook 2003-2010. 솔직히 말해서 캐시 된 Exchange 모드를 켜면 첫 번째 오류가 사라지지만 그렇게 할 수 없습니다.

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를 사용한 추가 조사에 따르면 문제가 코드에없는 것으로 나타났습니다. 캐시 된 Exchange 모드가 꺼져있을 때 API 내에서 시작 / 종료 날짜가 올바르지 않습니다. 그러나 Outlook 개발자는이를 알고 있었고 어떻게 든 일정에 정확한 날짜를 표시합니다! 누구든지 방법을 알고 있습니까?

업데이트 2 :

Outlook 지원 에스컬레이션 엔지니어의 답변 :

이를 바탕으로 당사 제품에 문제가 있음을 확인할 수 있습니다.


가능한 원인 :

  • IncludeRecurrences를 설정 한 후 정렬합니다.

다음은 두 날짜 사이의 Outlook 항목을 검색하는 PowerShell 모듈의 코드입니다.

그리고 변경 사항을 확인하고 일정 업데이트가 포함 된 이메일을 보내는 작은 애플릿은 Exchange에 대한 모바일 액세스 권한이 없을 때 편리합니다.

경로 : Documents \ 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 함수를 호출하는 코드입니다.

Path: Documents\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

}

To run the PowerShell script, use powershell.exe. To run this on startup, a shortcut on "%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\":

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass "C:\Users\%USERNAME%\Documents\WindowsPowerShell\mono.ps1"

참고URL : https://stackoverflow.com/questions/12163932/retrieve-calendar-items-outlook-api-webdav-displaying-strange-behaviour

반응형