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
}
CodePudding user response:
AppointmentItem
is never sent, and hence is never passed to the Application.ItemSend
event. What you get is the MeetingItem
object. If you need the parent appointment, call MeetingItem.GetAssociatedAppointment
.
CodePudding user response:
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
}