Creating a new olAppointmentItem using C#

  • Thread starter Thread starter Jason James
  • Start date Start date
J

Jason James

Hi,

I am develing an app that is to create a series of appointments from a
list of tasks in a MS Project file. The Project Object Model is not
giving me any problems. I feel that the Outlook Object Model is...

When I run my program I can create a new appointment, but as the
creator of the appointment I assume the convenor role of the meeting.
If the meeting time needs to be changed then a request for a different
appointment time comes to me. However, I would prefer a single
(special) user to be the owner (convenor) of the appointment and any
change requests should go to that user. I then intend to have the
special user share their calendar so that it can be viewed and
potentially edited by several other editors of that shared calendar.

My question then is how (without loging in as this special user) do I
using C# to create a new appointment in the special persons calendar
without making myself the originator of the meeting?

Greatfully yours,

Jason.

Please find my sample function below:

using outlook = Microsoft.Office.Interop.Outlook;

outlook.AppointmentItem mtg =
(outlook.AppointmentItem)outApp.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olAppointmentItem);
mtg.MeetingStatus =
Microsoft.Office.Interop.Outlook.OlMeetingStatus.olMeeting;
mtg.Location = "Meeting Room";
outlook.Recipient rec = mtg.Recipients.Add("James,
Jason");
rec.Type = (int)outlook.OlMeetingRecipientType.olRequired;
mtg.Subject ="Test meeting";
mtg.Start = new DateTime(2007, 9, 19, 15, 0, 0);
mtg.Duration = 60;
mtg.Body = "This is just a test meeting from C#";
mtg.ReminderMinutesBeforeStart = 60;
mtg.ReminderSet = true;
((outlook._AppointmentItem)mtg).Send();
 
The Organizer property is read-only for the Outlook object model. You can't
set someone else as the organizer without logging into Outlook while
impersonating the desired user.
 
Ken,

Thanks for the information. That was the conclusion that I was coming
to. However, if I open a shared calendar from within Outlook I can
add an appointment to the shared calendar as those I was the owner of
that calendar and not as myself (I have editor permissions on the
shared calendar), thus, I am not the convenor of the meeting, the
owner of the shared calendar is. Is there really no way to replicate
this behaviour from within the OOM? If what I am looking to do is not
possible, can you recommend an alternative approach to achieve my
desired functionality?

Many thanks in advance,

Jason.
 
I don't do all that much with appointments, but try this. Use
NameSpace.GetSharedDefaultFolder(olFolderCalendar) using the Recipient
object for the owner of that other calendar folder. Then use the
folder.Items.Add method to add a new appointment there and see what the
organizer property says.




Ken,

Thanks for the information. That was the conclusion that I was coming
to. However, if I open a shared calendar from within Outlook I can
add an appointment to the shared calendar as those I was the owner of
that calendar and not as myself (I have editor permissions on the
shared calendar), thus, I am not the convenor of the meeting, the
owner of the shared calendar is. Is there really no way to replicate
this behaviour from within the OOM? If what I am looking to do is not
possible, can you recommend an alternative approach to achieve my
desired functionality?

Many thanks in advance,

Jason.
 
Ken,

thanks for your thoughts. I have implemented that I think you are
suggesting, although I have no real experience with namespaces.

Here is what I ended up with:

// Create a OOM reference
outlook.Application outApp = new
Microsoft.Office.Interop.Outlook.Application();
// Create a new meeting object
outlook._AppointmentItem mtg =
(outlook._AppointmentItem)outApp.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olAppointmentItem);

// Acquire the namespace
outlook.NameSpace ns = outApp.GetNamespace("MAPI");
// Logon to the namespace
ns.Logon("exchange", Missing.Value, false, true);

// Create a receipient object that is going to be the
organizer of the meeting
outlook.Recipient r = ns.CreateRecipient("Controller,
Project");
// Open the shared calendar for this receipient
outlook.MAPIFolder f = ns.GetSharedDefaultFolder(r,
Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderCalendar);

// Setup the requirements for the meeting
mtg.MeetingStatus =
Microsoft.Office.Interop.Outlook.OlMeetingStatus.olMeeting;
mtg.Location = "Meeting Room";
// Add the other meeting attendee(s)
outlook.Recipient rec1 = mtg.Recipients.Add("James,
Jason");
rec1.Type =
(int)outlook.OlMeetingRecipientType.olRequired;

mtg.Subject ="Test meeting";
mtg.Start = new DateTime(2007, 9, 20, 15, 0, 0);
mtg.Duration = 60;
mtg.Body = "This is just a test meeting from C#";
mtg.ReminderMinutesBeforeStart = 60;
mtg.ReminderSet = true;

try
{
System.Diagnostics.Debug.WriteLine("There are " +
f.Items.Count + " items in the calendar.");

// mtg.Organizer is null and an exception is raised
//System.Diagnostics.Debug.WriteLine("The meeting
organizer is : " + mtg.Organizer.ToString());
// Add the meeting item to the folder.
f.Items.Add(mtg);
}
catch (ArgumentException ex)
{

System.Diagnostics.Debug.WriteLine(ex.Message.ToString());
}
catch (Exception ex)
{

System.Diagnostics.Debug.WriteLine(ex.Message.ToString());
}


However, when I execute the code an exception is thrown when I try and
add the appointment to the shared calendar.

A first chance exception of type 'System.ArgumentException' occurred
in MS Project Automation.exe
Could not complete the operation. One or more parameter values are not
valid.

Is there anything wrong with my implementation of your suggestion or
anything else I should be trying?

Thanks for your help on this,

Jason.
 
You shouldn't need to use NameSpace.Logon. And you should create your
appointment in that folder using the Add method. You're able to log into
that mailbox using that Recipient object? That object should have
permissions at minimum allowing creation of new items in that folder. See if
something like this works:

// Create a OOM reference
outlook.Application outApp = new
Microsoft.Office.Interop.Outlook.Application();
// Create a new meeting object
//outlook._AppointmentItem mtg =
(outlook._AppointmentItem)outApp.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olAppointmentItem);

// Acquire the namespace
outlook.NameSpace ns = outApp.GetNamespace("MAPI");
// Logon to the namespace
// ns.Logon("exchange", Missing.Value, false, true);

// Create a receipient object that is going to be the
organizer of the meeting
outlook.Recipient r = ns.CreateRecipient("Controller,
Project");

r.Resolve();

// Open the shared calendar for this receipient
outlook.MAPIFolder f = ns.GetSharedDefaultFolder(r,
Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderCalendar);

outlook._AppointmentItem mtg = (outlook._AppointmentItem)
f.Items.Add(Microsoft.Office.Interop.Outlook.OlItemType.olAppointmentItem);

// Setup the requirements for the meeting
mtg.MeetingStatus =
Microsoft.Office.Interop.Outlook.OlMeetingStatus.olMeeting;
mtg.Location = "Meeting Room";
// Add the other meeting attendee(s)
outlook.Recipient rec1 = mtg.Recipients.Add("James,
Jason");
rec1.Type =
(int)outlook.OlMeetingRecipientType.olRequired;

mtg.Subject ="Test meeting";
mtg.Start = new DateTime(2007, 9, 20, 15, 0, 0);
mtg.Duration = 60;
mtg.Body = "This is just a test meeting from C#";
mtg.ReminderMinutesBeforeStart = 60;
mtg.ReminderSet = true;

try
{
System.Diagnostics.Debug.WriteLine("There are " +
f.Items.Count + " items in the calendar.");

mtg.Save();


// mtg.Organizer is null and an exception is raised
//System.Diagnostics.Debug.WriteLine("The meeting
organizer is : " + mtg.Organizer.ToString());
// Add the meeting item to the folder.
// f.Items.Add(mtg);
}
catch (ArgumentException ex)
{

System.Diagnostics.Debug.WriteLine(ex.Message.ToString());
}
catch (Exception ex)
{

System.Diagnostics.Debug.WriteLine(ex.Message.ToString());
}
 
Ken,

many thanks for your persistance with this one. Your final suggestion
worked great. My account has editor rights to the Project Controller
account and once I had opened that shared calendar and added the
appointment to it the rest was no problem. Just one addition I had to
make and that was executing the send() method of the AppointmentItem
to actually get it to send out invites to the other attendees.

Please find below 100% functioning code. Again, a big thanks for your
assistance with this.

Regards,

Jason.

// Create a OOM reference
outlook.Application outApp = new
Microsoft.Office.Interop.Outlook.Application();
// Acquire the namespace
outlook.NameSpace ns = outApp.GetNamespace("MAPI");
// Create a receipient object that is going to be the
organizer of the meeting
outlook.Recipient myOrganizer =
ns.CreateRecipient("Project Controller");
myOrganizer.Resolve();
// Open the shared calendar for this receipient
outlook.MAPIFolder sharedCalendar =
ns.GetSharedDefaultFolder(myOrganizer,
Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderCalendar);
outlook._AppointmentItem myAppointment =
(outlook._AppointmentItem)sharedCalendar.Items.Add(outlook.OlItemType.olAppointmentItem);
// Setup the requirements for the appointment
myAppointment.MeetingStatus =
Microsoft.Office.Interop.Outlook.OlMeetingStatus.olMeeting;
myAppointment.Location = "Meeting Room";
// Add the other appointment attendee(s)
outlook.Recipient recInvite =
myAppointment.Recipients.Add("James, Jason");
recInvite.Type =
(int)outlook.OlMeetingRecipientType.olRequired;
// Define the remainder of the appointment attributes
myAppointment.Subject ="Test meeting";
myAppointment.Start = new DateTime(2007, 9, 21, 15, 0, 0);
myAppointment.Duration = 60;
myAppointment.Body = "This is just a test meeting from
C#";
myAppointment.ReminderMinutesBeforeStart = 60;
myAppointment.ReminderSet = true;
try
{
// Save the appointment in the shared calendar
myAppointment.Save();
// Send out the invites
myAppointment.Send();
}
catch (ArgumentException ex)
{

System.Diagnostics.Debug.WriteLine(ex.Message.ToString());
}
catch (Exception ex)
{

System.Diagnostics.Debug.WriteLine(ex.Message.ToString());
}
 
Back
Top