I am getting an error with a C# windows app trying to read Outlook calendar info
This worked previously however I think a security related change happened on the server side that I can see nor will I be told about.
I am using Outlook 2010 (v14.0.3129.5000)
There error I get is:
System.Runtime.InteropServices.COMException (0x80004005): Unspecified error (Exception from HRESULT: 0x80004005 (E_FAIL))
The error occurs when trying to read the appointment body:
if (oAppt.Body != null)
I can ready other calendar properties with no issues
Microsoft.Office.Interop.Outlook.RecurrencePattern recurrencePattern;
Microsoft.Office.Interop.Outlook.NameSpace oNS;
Microsoft.Office.Interop.Outlook.MAPIFolder oCalendar;
Microsoft.Office.Interop.Outlook.Items oItems;
Microsoft.Office.Interop.Outlook.AppointmentItem oAppt;
Microsoft.Office.Interop.Outlook.Application _OutlookApplication;
try
{
_OutlookApplication = new Microsoft.Office.Interop.Outlook.Application();
oNS = _OutlookApplication.GetNamespace("MAPI");
// Get the Calendar folder.
oCalendar = oNS.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderCalendar);
oCalendar.Items.IncludeRecurrences = true;
// Get the Items (Appointments) collection from the Calendar folder.
oItems = oCalendar.Items;
for (Int32 x = 1; x <= oItems.Count; x++)
{
//Need to change how we are getting the appointment
//Apparently Outlook will return non-appointments in the calendar feed
try
{
oAppt = (Microsoft.Office.Interop.Outlook.AppointmentItem)oItems[x];
Console.WriteLine(oAppt.Subject);
}
catch (Exception)
{
continue;
}
if (oAppt.Body != null)
Console.WriteLine(" Calendar Body:" + oAppt.Body.ToString());
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message.ToString());
}
}
Digging through the stack trace I see the following error
at Microsoft.Office.Interop.Outlook._AppointmentItem.get_Body()
Can anyone help with why this error is occurring and if there is any work around I can perform?
I was able to touch base with one of our Admins and found out this particular issue was being caused by a Group Policy that was pushed to our computer.
The error does nothing to point you in that direction but that was the issue
Related
I'm trying to write a C# console app that can programmatically update an Outlook distribution list (DL) in the Global Address List (GAL). I have permission to update this DL. I can do it interactively on my PC using Outlook, and I can do it in Perl code using Win32::NetAdmin::GroupAddUsers.
After adding a reference to COM library "Microsoft Outlook 14.0 Object Library", and then accessed via:
using Outlook = Microsoft.Office.Interop.Outlook;
I can successfully read from a DL, even recursing through DL's inside the "main" DL being searched. Here's that working code (critiques not needed for this piece):
private static List<Outlook.AddressEntry> GetMembers(string dl, bool recursive)
{
try
{
List<Outlook.AddressEntry> memberList = new List<Outlook.AddressEntry>();
Outlook.Application oApp = new Outlook.Application();
Outlook.AddressEntry dlEntry = oApp.GetNamespace("MAPI").AddressLists["Global Address List"].AddressEntries[dl];
if (dlEntry.Name == dl)
{
Outlook.AddressEntries members = dlEntry.Members;
foreach (Outlook.AddressEntry member in members)
{
if (recursive && (member.AddressEntryUserType == Outlook.OlAddressEntryUserType.olExchangeDistributionListAddressEntry))
{
List<Outlook.AddressEntry> sublist = GetMembers(member.Name, true);
foreach (Outlook.AddressEntry submember in sublist)
{
memberList.Add(submember);
}
}
else {
memberList.Add(member);
}
}
}
else
{
Console.WriteLine("Could not find an exact match for '" + dl + "'.");
Console.WriteLine("Closest match was '" + dlEntry.Name +"'.");
}
return memberList;
}
catch
{
// This mostly fails if running on a PC without Outlook.
// Return a null, and require the calling code to handle it properl
// (or that code will get a null-reference excception).
return null;
}
}
I can use the output of that to examine the members closely, so I think I understand the DL/member objects a bit.
But, the following code will NOT add a member to a DL:
private static void AddMembers(string dl)
{
Outlook.Application oApp = new Outlook.Application();
Outlook.AddressEntry ae = oApp.GetNamespace("MAPI").AddressLists["Global Address List"].AddressEntries[dl];
try {
ae.Members.Add("EX", "Tuttle, James", "/o=EMC/ou=North America/cn=Recipients/cn=tuttlj");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
ae.Update();
}
The arguments to Members.Add() are defined here, and the values shown in my code come exactly from examining my own Member object from another DL.
The exception displayed is simply "The bookmark is not valid." A similar question was asked before, but the solution was to use P/Invoke or LDAP. I really have no idea how to use P/Invoke (strictly a C# and Perl programmer, not a Windows/C/C++ programmer), and I don't have access to the LDAP server, so I really want to get this working through the Microsoft.Office.Interop.Outlook objects.
Any help is GREATLY appreciated!
After experimenting with several different .NET objects, using System.DirectorServices.AccountManagement as posted in Adding and removing users from Active Directory groups in .NET is what finally code this working for me. Closing out my own question.
So I'm working on an app that will be able to read the outlook calendars for a set of individuals and build an itinerary for them. I've got it pretty much working except that when I scrape a user's calendar, I'm not getting any information on the events they have marked as private.
Let me make it clear that I'm not trying to peer into a user's calendar and read their darkest secret appointment titles, but I would still like to be able to show that this person is unavailable during that time. For example in Outlook proper it just shows as "Private Appointment" - which is exactly what I want to be able to do in my app.
Here's the code I've got for scraping the user's calendar:
private Calendar CreateCalendar(String User_Name, String Initials, DateTime Week)
{
string filter = "[Start] >= '"
+ Week.ToString("g")
+ "' AND [End] <= '"
+ Week.AddDays(7).ToString("g") + "'";
Microsoft.Office.Interop.Outlook.Application App = new Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook.NameSpace mapiNamespace = App.GetNamespace("MAPI");
//Resolve the person whose calendar We're trying to read.
Outlook.Recipient rm = App.Session.CreateRecipient(User_Name);
if (rm.Resolve())
{
try
{
Outlook.Folder calFolder = App.Session.GetSharedDefaultFolder(rm, Outlook.OlDefaultFolders.olFolderCalendar) as Outlook.Folder;
Outlook.Items CalItems = calFolder.Items;
CalItems.IncludeRecurrences = true;
CalItems.Sort("[Start]", Type.Missing);
//Search for Items within the pre-defined time range.
Outlook.Items restrictItems = CalItems.Restrict(filter);
if (restrictItems.Count == 0)
{
Debug.Print("No Items Found");
return new Calendar(User_Name, Initials);
}
else
{
//Create our internal representation of their calendar, for use elsewhere.
Calendar cal = new Calendar(User_Name, Initials);
Outlook.AppointmentItem i = (Outlook.AppointmentItem)restrictItems.GetFirst();
do
{
cal.AddAppointment(i.Subject, i.Start, i.End);
i = restrictItems.GetNext();
} while (i != null);
App = null;
mapiNamespace = null;
return cal;
}
}
catch (Exception ex)
{
App = null;
mapiNamespace = null;
throw new AccessViolationException(User_Name + " was resolved but could not access their calendar. Have they set you up as a delegate?", ex);
}
}
else
throw new AccessViolationException("The name " + User_Name + " was not resolved, make sure their name in the RM List is spelled correctly. If you can enter their name as a recipient in an outlook mail message and it resolves correctly when you click 'Check Names', then it should work!");
}
I'm not sure if private events are contained in the same "Folder" in outlook's data structures, so maybe I'm just not looking in the right spot?
I've been having trouble googling this because "private" is a reserved word in C# that basically hits on every single post with code and a function declaration in it. Hopefully you guys will be more helpful.
Thanks!
I am working on a simple C# Windows Service that listens to the EventLog via the "EntryWrittenEventHandler" handler and watch for logon logoff events and then write them to a DB.
The service was working as expected for a few days and then suddenly I am not seeing anything get written on logon and logoff events. I am seeing the EntryWrittenEventHandler handler be triggered on each new Security EventLog write...but within the EntryWrittenEventArgs class...I am seeing every entry be reported as "Event ID 0" and this message:
"
Message
"The description for Event ID '0' in Source '' cannot be found. The local computer may not have the necessary registry information or message DLL files to display the message, or you may not have permission to access them. The following information is part of the event:"
string
message
"The description for Event ID '0' in Source '' cannot be found. The local computer may not have the necessary registry information or message DLL files to display the message, or you may not have permission to access them. The following information is part of the event:"
string
+ owner
{System.Diagnostics.EventLogInternal}
System.Diagnostics.EventLogInternal
ReplacementStrings
{string[0]} string[]
Source
"" string
+ TimeGenerated
{12/31/1969 7:00:00 PM}
System.DateTime
+ TimeWritten
{12/31/1969 7:00:00 PM}
System.DateTime
UserName
null string"
Not sure whats going on. Opening the EventLog on the server in question...I can see all the entries as expected. The date is also from 1969...which is weird as well.
Here is my code of what is going on so far:
public Audit()
{
CanHandleSessionChangeEvent = true;
//Start the EventLog Watcher
startEventLogWatch();
}
private void startEventLogWatch()
{
EventLog eLog = new EventLog("Security");
eLog.EntryWritten += new EntryWrittenEventHandler(EventLog_OnEntryWritten);
eLog.EnableRaisingEvents = true;
}
private void EventLog_OnEntryWritten(object source, EntryWrittenEventArgs e)
{
try
{
if (e.Entry.InstanceId.ToString() == "4624")
{
EventAudit eventAuditEntry = new EventAudit();
eventAuditEntry = LogonEvent(e);
if (eventAuditEntry.ADUserName != null)
{
WriteDBEntry(eventAuditEntry);
}
}
else if (e.Entry.InstanceId.ToString() == "4647")
{
EventAudit eventAuditEntry = new EventAudit();
eventAuditEntry = LogoffEvent(e);
if (eventAuditEntry.ADUserName != null)
{
WriteDBEntry(eventAuditEntry);
}
}
}
catch (Exception ex)
{
eventLog1.WriteEntry("A general error has occured. The error message is as follows: " + ex.Message.ToString(), EventLogEntryType.Error, 2001);
}
}
I have Windows Store app which is actually a game and I'm trying to implement posting result on Facebook.
I'm using Facebook SDK for .Net from facebooksdk.net
Here's my code
FacebookSession session = await App.FacebookSessionClient.LoginAsync("publish_stream");
if (session == null)
{
MessageDialog dialog = new MessageDialog("Error while getting publishing permissions. Please try again.");
await dialog.ShowAsync();
return;
}
// refresh your access token to contain the publish permissions
App.AccessToken = session.AccessToken;
FacebookClient fb = new FacebookClient(App.AccessToken);
string message = "Your score is: " + points;
dynamic proba = message;
try
{
//The next line throws exception
dynamic fbPostTaskResult = await fb.PostTaskAsync("/me/feed?message='{0}", proba);
var result = (IDictionary<string, object>)fbPostTaskResult;
var successMessageDialog = new Windows.UI.Popups.MessageDialog("Posted Open Graph Action, id: " + (string)result["id"]);
await successMessageDialog.ShowAsync();
}
catch (Exception ex)
{
MessageDialog exceptionMessageDialog = new MessageDialog("Exception during post: " + ex.Message);
exceptionMessageDialog.ShowAsync();
}
And the Exception Message that I recieve is:
The API 'System.String.Get_FirstChar()' cannot be used on the current platform. See http://go.microsoft.com/fwlink/?LinkId=248273 for more information
I tried diffrent ways to send arguments to "PostTaskAsync()" method but I always got the same Exception. Searching Google and Stackoverflow wasn't much helpful.
I'm much grateful for any sort of help.
Cheers
Hi I am working on C# application in which i am trying to read the mails from the Outlook Inbox.
I am using VS2010 and MS-Office 2007, I have added the refernce in the visual studio, The application is working fine in my system, but when i run the same application in client system, its throwing COM exception,
The exception message is like this
Unable to cast COM object of type System_ComObject to InterfaceType "Microsoft.Office.Interop.Outlook.MailItem" . This operation failed because the QueryInterface Call on the Com Component for the Interface with ID'{00063034-0000-0000-C000-00000000046} failed due to the following error. No such interface supported (Exception from HRESULT: 0x80004002)
(E_NONINTERFACE)
I am getting exception while trying to access MailItem ex code :
subject = ((Microsoft.Office.Interop.Outlook.MailItem)myInbox.Items[i]).Subject;
I tested in 3 to 4 systems in which VS2010 is installed, and the client system in which its throwing exception doesnt contain vs2010 in it, but .net 4.0 framework,ms-office 2007 is installed in client system.
what may be the error ?
Any suggestions plz ..
Thanks in advance..
Well there are two errors here - not all items in Inbox are of type MailItem, secondly subject can be null; so the correct code should look like:
using Microsoft.Office.Interop.Outlook;
var myApp = new Application();
NameSpace mapiNameSpace = myApp.GetNamespace("MAPI");
MAPIFolder myInbox = mapiNameSpace.GetDefaultFolder(OlDefaultFolders.olFolderInbox);
mapiNameSpace.SendAndReceive(false);
if (myInbox.Items.Count > 0) {
for (var i = 1; i < myInbox.Items.Count; i++) {
string subject;
var mailItem = myInbox.Items[i] as MailItem;
if (mailItem != null) {
subject = mailItem.Subject;
if (!string.IsNullOrEmpty(subject)) {
subject = subject.Replace('\'', '\"');
}
}
}
}
where the most important line is
var mailItem = myInbox.Items[i] as MailItem;
if (mailItem != null) {
...
and
if (!string.IsNullOrEmpty(subject)) {
...