Outlook Addin: Moving Appointment in Calendar does not reflect new date/time in AppointmentItem (catch Calendar.ItemChange) - vsto

i am trying to develop an Outlook Addin which updates a web services whenevery the ser moves an appointment (with drag and drop) in his calendar.
In my VSTO based Outlook Addin (in Outlook 2016) my Item_Change gets fired when the user moves the calendar item around.
But when I inspect the AppointmentItem which I get as a parameter of the call to
public void Item_Change(Object item)
{
Outlook.AppointmentItem myAppointment = item as Outlook.AppointmentItem;
the myAppointment.StartUTC still shows the old value instead of the value (date/time) where the user has moved the item.
Does anyone know how to retrieve the new date/time of a moved AppointmentItem?
Thanks in advance

Not using the Outlook Objector Model - it likes caching old stale values. All items are affected, but appointments are the worst - sometimes you would also need to change the current folder and come back. You would need to release the item in question, open another item, and only then open this item by its entry id. The problem you cannot do that from the event handler of the item that raises the event.
Your only other options are Extended MAPI (C++ or Delphi only) or Redemption.

Related

Automatically Closing Outlook Windows via Script/Macro

I'm hoping someone on here can point me in the right direction with some expertise. I have a situation with a client's outlook where we need to close any open draft windows after a new message/draft is opened. Ideally after the 4th new window has opened.
Any "new message" window that opens after this we need the script to close 1st window that opened. Either killing the process, or something similar.
Recently have been looking into Outlook macros, but am unsure if they will help in this instance. (Maybe they are?). Being more familiar with Powershell, figured we could start there.
Looking to get help writing a powershell script, macro, etc to do this on the backend.
The Outlook object model provides all the required events, methods and properties for that. So, VBA macros is the right choice if you don't need to distribute the solution on multiple machines. Otherwise, you need to consider developing a COM add-in instead (for example, a VSTO based one should work for you). See Walkthrough: Create your first VSTO Add-in for Outlook for more information.
You can handle the NewInspector event which is fired whenever a new inspector window is opened, either as a result of user action or through program code. The event occurs after the new Inspector object is created but before the inspector window appears.
You can also check the number of opened inspector windows in Outlook by using the Inspectors.Count property which returns a long indicating the count of objects in the specified collection.
Finally, the Inspector.Close method closes the Inspector and optionally saves changes to the displayed Outlook item. For example, a VBA sample which closes the active inspector instance:
Sub CloseItem()
Dim myinspector As Outlook.Inspector
Dim myItem As Outlook.MailItem
Set myinspector = Application.ActiveInspector
Set myItem = myinspector.CurrentItem
myItem.Close olSave
End Sub

Outlook VSTO-AddIn: Prevent Outlook from deleting an appointment

I try to prohibit in certain cases that the user deletes an appointment. Something like this:
User clicks on appointment in calendar
User selects delete
VSTO-Addin checks whether this is allowed and shows a warning dialog in case if not. Outlook does NOT delete the appointment!
Currently I attached to Item_Delete_Add() and I think that one can only handle the deletion but you cannot prevent outlook from actually deleting the appointment. Correct?
You are on the right avenue... The Items.ItemRemove event is fired when an item is deleted from the specified collection. This event does not run when the last item in a Personal Folders file (.pst) is deleted, or if 16 or more items are deleted at once from a PST file, Microsoft Exchange mailbox, or an Exchange public folder. Moreover, you must keep the reference to the source object to know which item is being deleted from a folder. To get this working you must subscribe to the SelectionChange event of the Explorer class. It is fired when the user selects a different or additional Microsoft Outlook item programmatically or by interacting with the user interface. So, you could subscribe to every selected item and know which item exactly is removed.
Another possible way is to handle the AppointmentItem.BeforeDelete event which is fired before an item (which is an instance of the parent object) is deleted. An instance of the item being deleted is passed as a parameter. In order for this event to fire when an email message, distribution list, journal entry, task, contact, or post are deleted through an action, an inspector must be open. The event occurs each time an item is deleted. It also allows to cancel the actions by setting the second parameter - if the event procedure sets this argument to true, the operation is not completed and the item is not deleted.
Yet another approach is to repurpose ribbon controls, see Temporarily Repurpose Commands on the Office Fluent Ribbon for more information.

How to capture the tick event of the task checkbox on 'Outlook Today'? VSTO Add-in

I'm developing an Outlook Add-in, and currently I have no idea on how to capture the task's checkbox (mark complete) tick event -- particularly on the 'Outlook Today' view. I'd like to override it with my own function.
Refer to the attached image as reference to the checkbox being referred to.
Outlook Today Task
The Outlook Today page is not a typical area that can be integrated with. It is possible though, as it is basically an .html page; see: https://technet.microsoft.com/library/cc750169.aspx. However, this is 20 year-old technology...
If you are mainly interested in trapping changes to that task, then you can trap the Items.ItemAdd event for the Tasks folder and do whatever you like with the modified Task.
The Outlook object model doesn't provide anything for the Outlook Today page. It just lists items from your folders. So, you may consider handling the following events to get the job done:
The ItemChange event of the Items class which is fired when an item in the specified collection is changed.
The PropertyChange event of Outlook items which is fired when an explicit built-in property of an object is changed.
Both events are fired when you mark the task as completed. But in case of the PropertyChange event you need to subscribe to each task item individually which is not really convenient.

EWS update location field of an appointment item doesn't work

I used EWS API 2.0 to update the location and subject in an outlook meeting item. I can see both the location and subject reflects in the outlook calendar. However, when I pop open the appointment item, the location is blank, however, I can still see the updated subject.
Below is the code I used:
Appointment appointment = Appointment.Bind(_service, ConvertId(entryId));
appointment.Location = location;
appointment.Subject = "Server Update Subject";
appointment.Update(ConflictResolutionMode.AutoResolve, SendInvitationsOrCancellationsMode.SendToNone);
PS: I used outlook add-in (VSTO) to open my web application to find an available meeting room and update the meeting item.
As soon as the room (location) got updated on server side (via EWS), I can see the outlook calendar reflect the change immediately but the update does not show on the opened appointment item in outlook.
I need to close the appointment item in outlook and re-open the appointment item to see the update, but still, I can only see the updated subject, not location.
To see the updated location reflects there, I need to close Outlook and re-open it to see the location...
Any comments or direction for things to try will be great appreciated! Thank you :-)
Finally figured this out, after many hours of research.
It is a known issue that Outlook doesn't update the changes made through EWS (or change from the server side) until you re-open the application and release all references to the object (before re-opening). So the solution would be to add Marshal.ReleaseComObject as below:
Marshal.ReleaseComObject(apptItem);
to release the object (same as close outlook application), then re-open the object using EntryId.
string eid = item.EntryID;
--- release the app object ---
var ns = application.GetNamespace("MAPI");// application.Session;// application.GetNamespace("MAPI");
Outlook.AppointmentItem appoinment = ns.GetItemFromID(eid) as Outlook.AppointmentItem;
I hope this solution help anyone who ran into the same issue as I do.

Outlook 2013 customization and integration in exchange online

I want to customize the appointment window used in Outlook. I want add few custom fields. I am using VSTO (VS2013) to develop this addin.
So far I have added a button in ribbon of appointment tab. On click of which I am opening a new form with custom fields. Now when user completes the form and other appointment details and appointment is saved then along with all appointment data, custom data entered by user should also get emailed to recipients.
And also that custom data would be stored in Exchange, and later that data can be queries to generate report.
So my question is - how do override the save appointment event so that I can add additional data in appointment and also how do I save it to exchange online using office 365.
Please advise.
Thanks.
When you are using an Exchange account which is the case with Office 365. The UserProperties of an Outlook item is kept in Exchange.
You can persist the custom data in UserProperties
If you want to Save your custom data when the appoitment is saved. You should put an event handler in the AfterWrite event. See AppointmentItem event list.