Reputation: 21
As the subject suggests, I am trying to determine if an Outlook item is a meeting request, while creating a new .ItemSend event handler. I have looked at ways of doing this with inspector and explorer.
I have reviewed this:
and this:
ActiveExplorer().Selection returns previously selected mail in Outlook C#
as well as a few of the 'similar questions'.
I have been successful with establishing a new inspector event handler as well as defining the event handler for Application.ItemSend and those are working great. But only when I send meeting requests. Regular emails respond to the event triggers, but restart Outlook, saving an email as a draft, without sending.
I am not sure of combining the use of inspector and explorer to prevent crashing Outlook? I am not sure if I can do this by only using inspector? By only using explorer?
I believe that if I can wrap all of this code with identification of an outlook item as a MailItem or a Meeting Request, I can get around this problem I am having with emails and the new event handler.
A point in the right direction is appreciated. Thanks - - chris
public partial class ThisAddIn
{
private Outlook.Inspectors inspectors = null;
private Outlook.UserProperty objUserPropertyEventId = null;
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
inspectors = this.Application.Inspectors;
inspectors.NewInspector += new Microsoft.Office.Interop.Outlook.InspectorsEvents_NewInspectorEventHandler(Inspectors_NewInspector);
// define event handler for ItemSend
Application.ItemSend += new Outlook.ApplicationEvents_11_ItemSendEventHandler(Application_ItemSend);
}
private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
{
// Note: Outlook no longer raises this event. If you have code that
// must run when Outlook shuts down, see https://go.microsoft.com/fwlink/?LinkId=506785
}
void Inspectors_NewInspector(Microsoft.Office.Interop.Outlook.Inspector Inspector)
{
// <testing this>
Outlook.Selection sel = Application.ActiveExplorer().Selection;
if (sel.Count == 1)
MessageBox.Show("One selected");
//Outlook.MailItem mail = sel[1] as Outlook.MailItem;
Object selObject = this.Application.ActiveExplorer().Selection[1];
//if (mail != null)
if (selObject is Outlook.MailItem)
MessageBox.Show("This is a mail item."/*\n\n" + mail.Subject*/);
else
MessageBox.Show("This is NOT a mail item."/*\n\n" + mail.Subject*/);
// </testing this>
// <this works, but not for email. Only meeting requests.>
#pragma warning disable IDE0019 // Use pattern matching
Outlook.AppointmentItem appt = Inspector.CurrentItem as Outlook.AppointmentItem;
#pragma warning restore IDE0019 // Use pattern matching
// is it an AppointmentItem
if (appt != null)
{
MessageBox.Show("appt != null");
// is it a meeting request
if (appt.MeetingStatus == Outlook.OlMeetingStatus.olMeeting)
{
// force time of initial meeting dialog to be 11:29pm
// to avoid immediate reminder of upcoming meeting
DateTime datDateTime = DateTime.Now;
string strYear = datDateTime.ToString().Substring(6, 4);
int intYear;
intYear = Int32.Parse(strYear);
string strMonth = datDateTime.ToString("MM/dd/yyyy").Substring(0, 2);
int intMonth;
intMonth = Int32.Parse(strMonth);
string strDay = datDateTime.ToString("MM/dd/yyyy").Substring(3, 2);
int intDay;
intDay = Int32.Parse(strDay);
string strReqAtt = appt.RequiredAttendees;
if (string.IsNullOrEmpty(strReqAtt))
appt.Start = new DateTime(intYear, intMonth, intDay, 23, 29, 00);
// save to generate EntryId for future reference
appt.Save();
// save EntryId as UserProperty
Outlook.AppointmentItem mtg;
mtg = (Outlook.AppointmentItem)Inspector.CurrentItem;
if (mtg != null)
{
if (mtg is Outlook.AppointmentItem)
{
mtg.MeetingStatus = Outlook.OlMeetingStatus.olMeeting;
string strEntryId = mtg.EntryID;
Outlook.UserProperties objUserProperties = mtg.UserProperties;
objUserPropertyEventId = objUserProperties.Add("MeetingEntryId", Outlook.OlUserPropertyType.olText, true, 1);
objUserPropertyEventId.Value = strEntryId;
}
}
if (mtg != null)
Marshal.ReleaseComObject(mtg);
}
if (appt != null)
Marshal.ReleaseComObject(appt);
}
}
public void Application_ItemSend(object Item, ref bool Cancel)
{
// use EventId to identify current meeting request
var app = new Microsoft.Office.Interop.Outlook.Application();
var ns = app.Session;
Outlook.AppointmentItem meeting = ns.GetItemFromID(objUserPropertyEventId.Value);
MessageBox.Show(meeting.Subject);
//if (meeting.MeetingStatus != Outlook.OlMeetingStatus.olNonMeeting)
if (meeting.MeetingStatus == Outlook.OlMeetingStatus.olMeeting)
{
// is ItemSend a request or a cancel
if (meeting.MeetingStatus != Outlook.OlMeetingStatus.olMeetingCanceled)
{
MessageBox.Show("MeetingStatus != olMeetingCanceled");
Outlook.Recipient recipConf = null;
try
{
// ItemSend is a request
if (meeting is Outlook.AppointmentItem)
{
//if (meeting.MeetingStatus == Outlook.OlMeetingStatus.olMeeting)
{
Outlook.Recipient recipRoomUser;
// if a location was provided
if (meeting.Location != null)
{
string strLocation = meeting.Location;
bool blnTorF = false;
string strConference = "|";
// Clears lazy room number typing
// Location resource:
// places meeting on 'JHP Conference ###' calendar
// and
// sends email to conference room user with link for Teams meeting
// conference room user is added to 'Location' by including email in 'Required'
if (!strLocation.Contains("Room - Conference"))
meeting.Location = "";
// Add calendar users (based on room location) to email
// sends email to conference room user with link for Teams meeting
// conference room user is added to previously cleared 'Location'
// by including email in 'Required'
if (strLocation.Contains("142"))
{
recipRoomUser = meeting.Recipients.Add("[email protected]");
recipRoomUser = meeting.Recipients.Add("[email protected]");
recipRoomUser.Type = (int)Outlook.OlMeetingRecipientType.olRequired;
if(meeting.Location == "")
meeting.Location = "[email protected]";
}
if (strLocation.Contains("150"))
{
recipRoomUser = meeting.Recipients.Add("[email protected]");
recipRoomUser = meeting.Recipients.Add("[email protected]");
recipRoomUser.Type = (int)Outlook.OlMeetingRecipientType.olRequired;
if (meeting.Location == "")
meeting.Location = "[email protected]";
}
if (strLocation.Contains("242"))
{
recipRoomUser = meeting.Recipients.Add("[email protected]");
recipRoomUser = meeting.Recipients.Add("[email protected]");
recipRoomUser.Type = (int)Outlook.OlMeetingRecipientType.olRequired;
if (meeting.Location == "")
meeting.Location = "[email protected]";
}
if (strLocation.Contains("248"))
{
recipRoomUser = meeting.Recipients.Add("[email protected]");
recipRoomUser = meeting.Recipients.Add("[email protected]");
recipRoomUser.Type = (int)Outlook.OlMeetingRecipientType.olRequired;
if (meeting.Location == "")
meeting.Location = "[email protected]";
}
MessageBox.Show("Location assigned");
// build string of recipients for .Split('|') to array
foreach (Outlook.Recipient objUser in meeting.Recipients)
{
// remove previous location prior to room change
if (!objUser.Name.Contains("JHP Conference") && !objUser.Name.Contains("Room - Conference"))
if (!strConference.Contains(objUser.Name)) // no duplicates
strConference = strConference + objUser.Name + "|";
}
if (strConference != "|")
{
// create array from string without duplicates
//MessageBox.Show("strConference != |\n\n" + strConference);
string[] arrConference = null;
strConference = strConference.TrimStart('|');
arrConference = strConference.Split('|');
// verify array contents
string strCheck = "";
string strReqdAtts = "";
for (int i = 0; i < arrConference.Length - 1; i++)
{
strCheck = strCheck + arrConference[i] + "\n";
strReqdAtts = strReqdAtts + ";" + arrConference[i];
}
//MessageBox.Show("Array contents\n\n" + strCheck);
strReqdAtts = strReqdAtts.TrimStart(';');
//MessageBox.Show("RequiredAttendees contents\n\n" + strReqdAtts);
meeting.RequiredAttendees = strReqdAtts;
//MessageBox.Show(".Add");
}
MessageBox.Show("Attendees assigned");
Cancel = true;
// has the user included "JHP - Room Reservations" for placement
// on the shared calendar for all conference room availability
foreach (Outlook.Recipient objUser in meeting.Recipients)
{
if (objUser.Name == "JHP - Room Reservations")
blnTorF = true;
}
// add "JHP - Room Reservations" if not already included
if (blnTorF == false)
{
recipConf = meeting.Recipients.Add("JHP - Room Reservations");
recipConf.Type = (int)Outlook.OlMeetingRecipientType.olRequired;
}
// resolve recipients
meeting.Recipients.ResolveAll();
meeting.Send();
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Calendar recipients were not added.");
}
finally
{
if (recipConf != null) Marshal.ReleaseComObject(recipConf);
}
}
else
//{
// ItemSend is a cancel
MessageBox.Show("Meeting is cancelled.");
//}
}
else
{
MessageBox.Show("Not a meeting");
}
}
#region VSTO generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InternalStartup()
{
this.Startup += new System.EventHandler(ThisAddIn_Startup);
this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
}
#endregion
}
Upvotes: 0
Views: 811
Reputation: 66286
AppointmentItem
object is never sent, and hence is never passed to the Application.ItemSend
event handler. What you get is the MeetingItem
object. If you need the parent appointment, call MeetingItem.GetAssociatedAppointment
.
Upvotes: 1
Reputation: 49455
There is no need to use the Explorer
window when the NewInspector
event is fired:
void Inspectors_NewInspector(Microsoft.Office.Interop.Outlook.Inspector Inspector)
{
// <testing this>
Outlook.Selection sel = Application.ActiveExplorer().Selection;
Use the Inspector
instance passed as a parameter to the event handler instead.
Also I've noticed the following code in the ItemSend
event handler:
public void Application_ItemSend(object Item, ref bool Cancel)
{
// use EventId to identify current meeting request
var app = new Microsoft.Office.Interop.Outlook.Application();
var ns = app.Session;
There is no need to create a new Outlook Application
instance each time the event is fired. Use the Application
property of your add-in class instead (available in the ThisAddIn
class).
Also you need to use the Item
object passed as a parameter to the ItemSend event handler, so instead of using the following code:
Outlook.AppointmentItem meeting = ns.GetItemFromID(objUserPropertyEventId.Value);
MessageBox.Show(meeting.Subject);
Check whether an object is of a specific type:
if (Item is Outlook.MeetingItem)
You may try to cast the Item
object to a specific type and then check for null
:
var obj = Item as Outlook.MeetingItem;
if (obj != null)
{
'do your work here
}
Upvotes: 0