Using Outlook 2010, I get this error when debugging
Unable to cast COM object of type
'Microsoft.Office.Interop.Outlook.ApplicationClass' to interface type
'Microsoft.Office.Interop.Outlook._Application'. This operation failed
because the QueryInterface call on the COM component
public void sendEMailThroughOUTLOOK()
{
try
{
String address = "john.doe#contoso.com";
Outlook.Application oApp = new Outlook.Application();
Outlook._MailItem oMailItem = (Outlook._MailItem)oApp.CreateItem(Outlook.OlItemType.olMailItem); // CRASHING HERE
oMailItem.To = address;
oMailItem.Subject = "Status Update on " + DateTime.Now.ToString("M/d/yyyy");
oMailItem.BodyFormat = Outlook.OlBodyFormat.olFormatPlain;
oMailItem.Body = createEmailBody();
// body, bcc etc...
oMailItem.Display(true);
}//end of try block
catch (Exception ex)
{
Console.WriteLine(ex.InnerException.ToString());
}//end of catch
}
This code worked PERFECTLY on Outlook 2013. However it keeps crashing when using Outlook 2010.
I downgraded the Interop.Outlook from 15 to 14
I think you need to replace this:
Outlook._MailItem oMailItem = (Outlook._MailItem)oApp.CreateItem(Outlook.OlItemType.olMailItem);
with this:
Outlook.MailItem oMailItem = oApp.CreateItem(Outlook.OlItemType.olMailItem);
Also, if this code is in an add-in, you don't need to create a new instance of Outlook.Application - use the object passed to the OnConnection event.
Related
I`m trying to create outlook mails from templates, slightly edit them and then show to user so he can send that mail.
There is no problem in creation of the mail and displaying it. But when I`m trying to read (or edit) HTMLBody of the mail there is a error:
Operation aborted (Exception from HRESULT: 0x80004004 (E_ABORT))
Here is my code:
using Outlook = Microsoft.Office.Interop.Outlook;
...
try
{
var app = new Outlook.Application();
Outlook.MailItem mailItem = app.CreateItemFromTemplate("C:\\Test\\template.oft");
var body = mailItem.HTMLBody; //Here is the exception
mailItem.HTMLBody = body.Replace("#firstname", "Test Testy");
mailItem.To = message.EmailAddress;
mailItem.Display(mailItem);
}
catch (Exception ex)
{
...
}
Added example project on github.
var app = new Outlook.Application();
Before creating a new instance of the Outlook Application class I'd suggest checking whether it is already run and get the running instance then:
if (Process.GetProcessesByName("OUTLOOK").Any())
app = System.Runtime.InteropServices.Marshal.GetActiveObject("Outlook.Application");
Outlook is a singleton. You can't run multiple instances at the same time.
Also I'd suggest saving the newvly created item before accessing the HTMLBody property value:
Outlook.MailItem mailItem = app.CreateItemFromTemplate("C:\\Test\\template.oft");
mailIte.Save();
var body = mailItem.HTMLBody; //Here is the exception
Finally, the Display method doesn't take a MailItem instance. Instead, you can pass true to get the inspector shown as a modal window or just omit the parameter (false is used by default).
BTW Where and when do you run the code?
I have two mailboxes setup in Outlook.
I'll refer to them as "email1#mail.com" and "email2#mail.com".
I would like to use Interop to create and send an appointment to a specific email address calender, not just to the default outlook account.
using System;
using System.Diagnostics;
using System.Reflection;
using Outlook = Microsoft.Office.Interop.Outlook;
namespace Program
{
class Program
{
public static void Main(string[] args)
{
// Create the Outlook application.
Microsoft.Office.Interop.Outlook.Application oApp = new Microsoft.Office.Interop.Outlook.Application();
Outlook.Account account = oApp.Session.Accounts["email2#mail.com"];
// Get the NameSpace and Logon information.
Microsoft.Office.Interop.Outlook.NameSpace oNS = oApp.GetNamespace("mapi");
// Log on by using a dialog box to choose the profile.
oNS.Logon(Missing.Value, Missing.Value, true, true);
// Create a new mail item.
Microsoft.Office.Interop.Outlook.MailItem oMsg =(Microsoft.Office.Interop.Outlook.MailItem) oApp.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olMailItem);
// Set the subject.
oMsg.Subject = "test";
// Set HTMLBody.
oMsg.HTMLBody = "test";
oMsg.To = "test#gmail.com";
//oMsg.CC = _cc;
//oMsg.BCC = _bcc;
oMsg.Save();
oMsg.SendUsingAccount = account;
// Add a recipient.
//Microsoft.Office.Interop.Outlook.Recipients oRecips = (Microsoft.Office.Interop.Outlook.Recipients)oMsg.Recipients;
// TODO: Change the recipient in the next line if necessary.
//Microsoft.Office.Interop.Outlook.Recipient oRecip = (Microsoft.Office.Interop.Outlook.Recipient)oRecips.Add(_recipient);
//oRecip.Resolve();
// Send.
(oMsg as Microsoft.Office.Interop.Outlook._MailItem).Send();
// Log off.
oNS.Logoff();
// Clean up.
//oRecip = null;
//oRecips = null;
oMsg = null;
oNS = null;
oApp = null;
}
}
}
This code works flawlessly in sending an email automatically to "test#gmail.com" from my email "email2#mail.com".
However, I would like to automatically create an appointment/meeting for a specific email address.
This is my current attempt:
using System;
using System.Diagnostics;
using System.Reflection;
using Outlook = Microsoft.Office.Interop.Outlook;
namespace SendEventToOutlook
{
class Program
{
public static void Main(string[] args)
{
try
{
// Create the Outlook application.
Microsoft.Office.Interop.Outlook.Application oApp = new Microsoft.Office.Interop.Outlook.Application();
Outlook.Account account = oApp.Session.Accounts["email2#mail.com"];
// Get the nameSpace and logon information.
Microsoft.Office.Interop.Outlook.NameSpace oNS = oApp.GetNamespace("mapi");
// Log on by using a dialog box to choose the profile.
oNS.Logon(Missing.Value, Missing.Value, true, true);
// Create a new Appointment item.
Microsoft.Office.Interop.Outlook.AppointmentItem appt =
(Microsoft.Office.Interop.Outlook.AppointmentItem)
oApp.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olAppointmentItem);
appt.Start = DateTime.Now;
appt.End = DateTime.Now.AddDays(7);
appt.Location = "Test";
appt.Body = "Test";
appt.AllDayEvent = false;
appt.Subject = "Test";
appt.Save();
appt.SendUsingAccount = account;
// Log off.
oNS.Logoff();
appt = null;
oNS = null;
oApp = null;
}
catch (Exception ex)
{
Debug.WriteLine("The following error occurred: " + ex.Message);
}
}
}
}
This code does create an appointment successfully, but it keeps creating an appointment for "email1#mail.com" instead of "email2#mail.com", which shouldn't happen as I've specified the sending account to be "email2#mail.com" from the lines:
Outlook.Account account = oApp.Session.Accounts["email2#mail.com"];
and then
appt.SendUsingAccount = account;
This is how my two email addresses are set up in Outlook: http://i.imgur.com/0eopV8A.png
Both the email addresses have different user names and are from different domains/mail servers, as shown in that screenshot.
Would anyone be able to see the problem I'm making or if there's a different solution?
Thank you.
It is not clear whether you have got two accounts set up in the single Mail profile or separate profiles.
The SendUsingAccount property of the AppointmentItem class allows to set an Account object that represents the account under which the AppointmentItem is to be sent. So, The SendUsingAccount property can be used to specify the account that should be used to send the AppointmentItem when the Send method is called. It is not what you are looking for I suppose.
Anyway, you can use the GetDefaultFolder method of the Store class which returns a Folder object that represents the default folder in the store and that is of the type specified by the FolderType argument. This method is similar to the GetDefaultFolder method of the NameSpace object. The difference is that this method gets the default folder on the delivery store that is associated with the account, whereas NameSpace.GetDefaultFolder returns the default folder on the default store for the current profile.
Thus, you can get the Calendar folder for the required account and add a new appointment there.
You may find the following articles in MSDN helpful:
How to: Create a Sendable Item for a Specific Account Based on the Current Folder (Outlook)
Using Multiple Accounts for the Same Profile on Outlook
As an image below is my problem with the Application. I've tried to add
Outlook.Application Application = new Outlook.Application();
but nothing changes
I added namespace as using Outlook = Microsoft.Office.Interop.Outlook;
#region Send Email
private void SendEmail()
{
string subjectEmail = "Meeting has been rescheduled.";
string bodyEmail = "Meeting is one hour later.";
Outlook.MAPIFolder sentContacts = (Outlook.MAPIFolder)
this.Application.ActiveExplorer().Session.GetDefaultFolder
(Outlook.OlDefaultFolders.olFolderContacts);
foreach (Outlook.ContactItem contact in sentContacts.Items)
{
if (contact.Email1Address.Contains("example.com"))
{
this.CreateEmailItem(subjectEmail, contact
.Email1Address, bodyEmail);
}
}
}
private void CreateEmailItem(string subjectEmail, string toEmail, string bodyEmail)
{
Outlook.Application Application = new Outlook.Application();
Outlook.MailItem eMail = (Outlook.MailItem)
this.Application.CreateItem(Outlook.OlItemType.olMailItem);
eMail.Subject = subjectEmail;
eMail.To = toEmail;
eMail.Body = bodyEmail;
eMail.Importance = Outlook.OlImportance.olImportanceLow;
((Outlook._MailItem)eMail).Send();
}
#endregion
This line of code is looking for a class-level field called Application, which I assume doesn't exist:
Outlook.MAPIFolder sentContacts = (Outlook.MAPIFolder)
this.Application.ActiveExplorer().Session.GetDefaultFolder
(Outlook.OlDefaultFolders.olFolderContacts);
Create an instance of Application inside the method (like you said you did) and then remove the keyword this from the above code:
Outlook.Application Application = new Outlook.Application();
Outlook.MAPIFolder sentContacts = (Outlook.MAPIFolder)
Application.ActiveExplorer().Session.GetDefaultFolder
(Outlook.OlDefaultFolders.olFolderContacts);
If you need access to Application outside of that method, then create Application at the class level (outside of any methods) and instantiate it inside the constructor (if that's appropriate in your situation).
I use this code to check if the Outlook application is open and if not create a new process and logon.
try
{
Outlook.Application oApp = null;
if (System.Diagnostics.Process.GetProcessesByName("OUTLOOK").Count() > 0)
{
oApp = Marshal.GetActiveObject("Outlook.Application") as Outlook.Application;
}
else oApp = new Outlook.Application();
Outlook.NameSpace oNS = oApp.GetNamespace("mapi");
oNS.Logon(Type.Missing, Type.Missing, false, true);
return oNS.CurrentUser.Name;
}
catch (Exception exp)
{
Logger.AddMessage(exp.ToString());
}
If the program is open I have no issues but when try to start it in csharp I get this logon error:
"The server is not available. Contact your administrator if this condition persists."
Something missed or what is wrong here?
First set the third parameter to true to see the available profiles to select, then set the default profile name!
void Logon(
Object Profile,
Object Password,
Object ShowDialog,
Object NewSession
)
In my case:
oNS.Logon("Default Outlook Profile", "", false, true);
We just launched a new task to retrieve emails from exchange server for different accounts using asp.net web application. I don't have such experience in past, but after searching online I found a code snippet which could communicate with outlook and fetch emails from there. However, there is an exception occurs every time I test the code which is :
"Unable to cast COM object of type
'System.__ComObject' to interface type
'Microsoft.Office.Interop.Outlook.PostItem'.
This operation failed because the
QueryInterface call on the COM
component for the interface with IID
'{00063024-0000-0000-C000-000000000046}'
failed due to the following error: No
such interface supported (Exception
from HRESULT: 0x80004002
(E_NOINTERFACE)). "
Does anyone know the reason?
By the way, any suggestion helping on fetching emails from exchange server directly is highly appreciated!
My code:
Microsoft.Office.Interop.Outlook.Application app = null;
Microsoft.Office.Interop.Outlook._NameSpace ns = null;
Microsoft.Office.Interop.Outlook.PostItem item = null;
Microsoft.Office.Interop.Outlook.MAPIFolder inboxFolder = null;
Microsoft.Office.Interop.Outlook.MAPIFolder subFolder = null;
try
{
app = new Microsoft.Office.Interop.Outlook.Application();
ns = app.GetNamespace("MAPI");
ns.Logon("user", "password", false, false);
inboxFolder = ns.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
StringBuilder sb = new StringBuilder();
sb.AppendFormat("Folder Name:{0},EntryId:{1}", inboxFolder.Name, inboxFolder.EntryID);
sb.AppendFormat(" Num Items:{0}", inboxFolder.Items.Count.ToString());
Response.Write(sb);
for (int i = 1; i <= inboxFolder.Items.Count; i++)
{
item = (Microsoft.Office.Interop.Outlook.PostItem)inboxFolder.Items[i];//this is the exception happened line
Console.WriteLine("Item: {0}", i.ToString());
Console.WriteLine("Subject: {0}", item.Subject);
Console.WriteLine("Sent: {0} {1}" item.SentOn.ToLongDateString(), item.SentOn.ToLongTimeString());
Console.WriteLine("Categories: {0}", item.Categories);
Console.WriteLine("Body: {0}", item.Body);
Console.WriteLine("HTMLBody: {0}", item.HTMLBody);
}
}
catch (Exception)
{
throw;
}
finally
{
ns = null;
app = null;
inboxFolder = null;
}
Here goes:
With these lines...
Microsoft.Office.Interop.Outlook.MAPIFolder inboxFolder = null;
inboxFolder = ns.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
...you're creating a reference to the user's Inbox. So far so good.
But then here...
for (int i = 1; i <= inboxFolder.Items.Count; i++)
{
item = (Microsoft.Office.Interop.Outlook.PostItem)inboxFolder.Items[i];
//other stuff...
}
...you're saying, "for every Item in the Inbox, assume that the Item is a PostItem."
According to MSDN, a PostItem:
Represents a post in a public folder
that others may browse.
The user's inbox isn't going to be full of post items. It's going to contain MailItem objects representing the user's emails. That being the case, that line of code should probably be
item = (Microsoft.Office.Interop.Outlook.MailItem)inboxFolder.Items[i];
Caveat: I don't know enough about Outlook's API to understand whether it's possible for there to be Outlook Item Objects other than MailItem objects in the Inbox, but I'd wager not. For reference, the full list of Outlook Item Objects is here.
Use as shown below:
// not PostItem
item = (Microsoft.Office.Interop.Outlook.MailItem)inboxFolder.Items[i];