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)) {
...
Related
I have a simple VSTO outlook addin that needs to move email messages into public folders. It works fine except when outlook is first launched. After a first launch of outlook (office 365 business) if I try and use the addin to move a message into a public folder using GetFolderFromID(IDValueStoredInMyAddin) I get an error "The operation failed. The messaging interfaces have returned an unknown error. If the problem persists, restart Outlook". If after starting outlook the user manually expands the public folders tree then the addin works without this error. Any ideas what is going on here? Is there a way from within a VSTO addin for expand public folders?
Outlook initializes stores on first access. Try to specify the store entry id (second parameter when calling GetFolderFromID) or open the store first using Namespacve.GetStorefromID followed by Store.GetFolderFromID
I just had the same problem and looks like it is working with this:
public string GetStoreID()
{
if (Properties.Settings.Default.SharedFolderEmail != "")
{
Outlook._NameSpace nSpace = Application.GetNamespace("MAPI");
Outlook.Recipient recip = nSpace.CreateRecipient(Properties.Settings.Default.SharedFolderEmail);
if (recip.Resolve())
{
Outlook.Folder root = nSpace.GetSharedDefaultFolder(recip, Outlook.OlDefaultFolders.olFolderInbox) as Outlook.Folder;
return root.StoreID;
}
else
{
return "";
}
}
else
{
Outlook.Folder root = Application.Session.DefaultStore.GetRootFolder() as Outlook.Folder;
return root.StoreID;
}
}
Outlook._NameSpace nSpace = Application.GetNamespace("MAPI");
_Archive = nSpace.GetFolderFromID(FolderToMonitor_EntryID, GetStoreID());
_Archive.Items.ItemAdd += new Outlook.ItemsEvents_ItemAddEventHandler(ItemAdded);
GC.KeepAlive(_Archive);
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.
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
I try this code :
Microsoft.Office.Interop.Outlook.Application myApp = new Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook.NameSpace mapiNameSpace = myApp.GetNamespace("MAPI");
mapiNameSpace.Logon(null, null, false, false);
mapiNameSpace.Logon("MyEmailID", "PasswordOfMyEmail", Missing.Value, true);
Microsoft.Office.Interop.Outlook.MAPIFolder myInbox = mapiNameSpace.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
MessageBox.Show(myInbox.Items.Count + "");
But the MessageBox display me 0 (myInbox.Items.Count).
So maybe I am not able to access my outlook account !!!
I use Visual Studio 2010.
Can someone help me please ?
Firstly, if you are in an add-in, you should never create a new instance of the Outlook.Application object - you already have it exposed to your addin through globals.
Secondly, do not call Logon - Outlook will do that for you. That method is really for the external applications, not addins.
Thirdly, you call Logon once with null for the profile name. If you do not want to pass an optional parameter, pass Missing.Value, not null. And the second call to Logon (why do you need it?) will do absolutely nothing. Passing any email will not work anyway - the parameter must be the profile name as seen in Control Panel | Mail | Show Profiles.
And most importantly, when do you make that call? Does your Inbox actually contain any messages? Or is it a brand new profile and Outlook did not yet have a chance to download the messages from the mailbox?
So you can use :
Explorer currentExplorer = Globals.ThisAddIn.Application.ActiveExplorer();
MAPIFolder myInbox = Globals.ThisAddIn.Application.ActiveExplorer().CurrentFolder;
try
{
if ( (currentExplorer != null) && (currentExplorer.Selection != null) && (currentExplorer.Selection.Count > 0) )
{
object item = currentExplorer.Selection[1];
if (item is MailItem)
{
MailItem mailItem = item as MailItem;
MessageBox.Show(myInbox.Items.Count + "");
}
}
}
Is there any way to get all mail from an specific Folder into my Application?
Check this link. Introduction to Outlook Programming will explain things more clearly.
You could loop through the mailitems. Sample code
using System.Runtime.InteropServices;
using OutLook = Microsoft.Office.Interop.Outlook;
using Office = Microsoft.Office.Core;
OutLook.Application oApp;
OutLook._NameSpace oNS;
OutLook.MAPIFolder oFolder;
OutLook._Explorer oExp;
oApp = new OutLook.Application();
oNS = (OutLook._NameSpace)oApp.GetNamespace("MAPI");
oFolder = oNS.GetDefaultFolder(OutLook.OlDefaultFolders.olFolderInbox);
oExp = oFolder.GetExplorer(false);
oNS.Logon(Missing.Value, Missing.Value, false, true);
OutLook.Items items = oFolder.Items;
foreach (OutLook.MailItem mail in items)
{
if (mail.UnRead == true)
{
}
}
Edit:
Reference other folders
oFolder.Folders["Foldername"]
OutLook Code
Common Outlook tasks
Looping through all items in a folder is a terrible idea, especially if you are working against an online Exchange store. Items.Find/FindNext or Items.Restrict is the way to go.
Find/FindNext:
OutLook.Items items = oFolder.Items;
OutLook.MailItem mail = items.Find("[Unread] = true");
while (mail != null)
{
MessageBox.Show(mail.Subject);
mail = items.FindNext();
}
Items.Restrict:
OutLook.Items items = oFolder.Items.Restict("[Unread] = true")
foreach (OutLook.MailItem mail in items)
{
MessageBox.Show(mail.Subject);
}
There's some examples of accessing Outlook folders here, one of which deals specifically with unread mail.
Edit: There's a KB article specifically about accessing folders from C#, Programming samples that can reference items and folders in Outlook by using Visual C# .NET
To open another user's folder, use GetSharedDefaultFolder
foreach (Object Unreadmail in folderItems)
{
if ((Unreadmail as Outlook.MailItem) != null && (Unreadmail as Outlook.MailItem).UnRead == true)
{
//DO Your action Here
}
}
I have experienced "COM_object" exception error with above solutions, More info please refer here