I am trying to create outlook .msg format file using my C# code.
I have used below 2 code:
Method 1 :
Microsoft.Office.Interop.Outlook.Application objOutlook = new Microsoft.Office.Interop.Outlook.Application();
// Creating a new Outlook message from the Outlook Application instance
Microsoft.Office.Interop.Outlook.MailItem msgInterop = (Microsoft.Office.Interop.Outlook.MailItem)(objOutlook.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olMailItem));
// Set recipient information
msgInterop.To = "neha1#gmail.com";
msgInterop.CC = "neha#gmail.com";
// Set the message subject
msgInterop.Subject = "Subject";
// Set some HTML text in the HTML body
msgInterop.HTMLBody = "<h3>HTML Heading 3</h3> <u>This is underlined text</u>";
// Save the MSG file in local disk
string strMsg = #"c:\\temp\TestInterop.msg";
msgInterop.SaveAs(strMsg, Microsoft.Office.Interop.Outlook.OlSaveAsType.olMSG);
Second method :
Redemption.RDOSession Session = new RDOSession();
Redemption.RDOMail Msg = Session.CreateMessageFromMsgFile(#"c:\temp\YourMsgFile.msg");
Msg.Sent = true;
Msg.Subject = "test";
Msg.Body = "test body";
Msg.Recipients.AddEx("the user", "user#domain.demo", "SMTP", rdoMailRecipientType.olTo);
Msg.Save();
Both method gives error on executing as below :
System.Runtime.InteropServices.COMException (0x8004010F): Creating an
instance of the COM component with CLSID
{29AB7A12-B531-450E-8F7A-EA94C2F3C05F} from the IClassFactory failed
due to the following error: 8004010f Exception from HRESULT:
0x8004010F.
I have researched and found some compatibility issue with platform. I tried to change the platform from 32-bit to x64. Still it did not resolve my problem.
Is outlook installed and in a runnable state on the machine you are doing this from? The error is that the com component isn't registered, which usually would mean you just copied dlls from another machine which didn't register the com ones.
So either install outlook, or install this
https://www.microsoft.com/en-us/download/details.aspx?id=1004
I installed Outlook on my system. And the code I had posted above (Microsoft.Office.Interop.Outlook.Application) works like a charm :) .
Related
Using .NET C# i want to load an Outlook html message from *.msg file, add a recipient and save it to standard draft folder.
I cannot do it properly with Outlook 2019 (not 2016 or 2013), because after saved, it turns the message body format to plain text. This happen with 2019 version only.
In the code example i first create the email and save it to draft. Until the COM Application object is instantiated the format remain html. Right after i had manually opened Outlook.exe the message has been turned to plain text. I check this with the function PrintBodyFormat. Please note this happen with Office 2019 only.
using Debug = System.Diagnostics.Debug;
using Outlook = Microsoft.Office.Interop.Outlook;
static void CreateMail()
{
Outlook.Application app = new Outlook.Application();
Outlook.MailItem mail = app.CreateItemFromTemplate(#"C:\html_message.msg");
mail.Recipients.Add("johndoe#foobar.com");
Debug.WriteLine(mail.BodyFormat.ToString());
//OUTPUT WITH ALL OUTLOOK VERSION: "olFormatHTML"
mail.Save();
mail.Close(Outlook.OlInspectorClose.olDiscard);
System.Runtime.InteropServices.Marshal.ReleaseComObject(mail);
mail = null;
Outlook.NameSpace nms = app.GetNamespace("MAPI");
Outlook.MAPIFolder DraftFolder = nms.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderDrafts);
mail = DraftFolder.Items[1];
Debug.WriteLine(mail.BodyFormat.ToString());
//OUTPUT WITH ALL OUTLOOK VERSION: "olFormatHTML"
mail.Close(Outlook.OlInspectorClose.olDiscard);
System.Runtime.InteropServices.Marshal.ReleaseComObject(mail);
mail = null;
app.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(DraftFolder);
System.Runtime.InteropServices.Marshal.ReleaseComObject(nms);
System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
}
//Run this after manually opened Outlook.exe
static void PrintBodyFormat()
{
Outlook.Application app = new Outlook.Application();
Outlook.NameSpace nms = app.GetNamespace("MAPI");
Outlook.MAPIFolder DraftFolder = nms.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderDrafts);
Outlook.MailItem mail = DraftFolder.Items[1];
Debug.WriteLine(mail.BodyFormat.ToString());
//OUTPUT WITH OUTLOOK 2016 OR EARLIER: "olFormatHTML"
//OUTPUT WITH OUTLOOK 2019: "olFormatPlain"
app.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(mail);
System.Runtime.InteropServices.Marshal.ReleaseComObject(DraftFolder);
System.Runtime.InteropServices.Marshal.ReleaseComObject(nms);
System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
}
Do not use mail.Close(Outlook.OlInspectorClose.olDiscard); - you never showed the inspector, so there is no reason to close it.
Also, Marshal.ReleaseComObject won't do much since you never release the Recipients collection and the Recipient object returned by Recipients.Add - both of them keep a reference to the parent message, and you end up with two implicit variables that you never release.
Do not use DraftFolder.Items[1] - save the value of MailItem.EntryID in a variable after calling Save, then use it to reopen the message using Namespace.GetItemFromID.
I am developing a small project where I need to be able to retrieve emails from an Outlook mailbox in order to process the emails received.
I took an old program made in VB.net to rewrite it in C #.
With the project in Vb.net I have no errors
However I have this error: System.IO.FileNotFoundException : 'Could not load file or assembly 'office, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c'. The specified file can not be found.' with the C# project.
My references :
When I compare the Microsoft.Office.Interop.outlook library to the project in Vb.net installed is exactly the same (same version, etc.).
So if you have an idea to solve this problem I am interested :D
You can try the following steps to solve the System.IO.FileNotFoundException problem.
First, you need to change the current framework to .NET Core 3.0.
Second, Select Interop.Microsoft.Office.Interop.Outlook, right click properties and set "Embed Interop Types" to "Yes".
Finally, you can use the following code to retrieve emails from an Outlook mailbox.
using Outlook = Microsoft.Office.Interop.Outlook;
Outlook.Application oApp = null;
oApp = new Outlook.Application();
Outlook.NameSpace nameSpace = oApp.GetNamespace("MAPI");
Outlook.Items items = null;
try
{
// use default profile and DO NOT pop up a window
// on some pc bill gates fails to login without the popup, then we must pop up and lets use choose profile and allow access
nameSpace.Logon("", "", false, Missing.Value);
var folder = nameSpace.Folders["emailaddress"].Folders["Folder"];
items = folder.Items;
foreach (Outlook.MailItem item in items)
{
Console.WriteLine(item.Subject);
}
Console.WriteLine("yes");
Console.ReadKey();
}
catch (Exception)
{
// use default profile and DO pop up a window
nameSpace.Logon("", "", true, true);
}
While trying to open Outlook for attachment in mail, via IIS asp.net website got this error. Assign IIS USR and Network with full permissions in DCOMCnfg to Microsoft OutLook component but nothing work.
Retrieving the COM class factory for component with CLSID {0006F03A-0000-0000-C000-000000000046} failed due to the following error: 80070005 Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)).
using System;
using Outlook = Microsoft.Office.Interop.Outlook;
// Create the Outlook application.
Outlook.Application oApp = new Outlook.Application();
// Create a new mail item.
Outlook.MailItem oMsg = (Outlook.MailItem)oApp.CreateItem(Outlook.OlItemType.olMailItem);
// Set HTMLBody.
//add the body of the email
oMsg.HTMLBody = "Hello, This is test for sending pdf attachment using OutLook";
//Add an attachment.
String sDisplayName = "MyAttachment";
int iPosition = (int)oMsg.Body.Length + 1;
int iAttachType = (int)Outlook.OlAttachmentType.olByValue;
//now attached the file
Outlook.Attachment oAttach = oMsg.Attachments.Add(Server.MapPath("~/TestSendFile.pdf"), iAttachType, iPosition, sDisplayName);
//Subject line
oMsg.Subject = "Your Subject will go here.";
// Add a recipient.
Outlook.Recipients oRecips = (Outlook.Recipients)oMsg.Recipients;
// Change the recipient in the next line if necessary.
Outlook.Recipient oRecip = (Outlook.Recipient)oRecips.Add("user1#comecompany.com");
oRecip.Resolve();
// Send.
oMsg.Display();
Outlook Object Model (just like any other Office app) cannot be used from a service (such as IIS).
More than that, you are attempting to display a message on the server side where nobody will ever see it.
You can use either
Exchange Web Services (in case of an Exchange mailbox)
Extended MAPI (C++ or Delphi only)
Redemption (I am its author) - it wraps Extended MAPI and its RDO family of objects can be used from a service. It can be used from any language, including C#.
If you are attempting to display a message on the client side, your choices are
mailto url - does not allow HTML or attachments
Use Outlook Object Model from the client side Java Script. Your site must be trusted and you can ony use COM in IE.
Generate an EML (MIME) file and provide a link to it - Outlook will be happy to open from the browser and display it.
I have an SSIS package that runs an SQL query and exports it to a csv file via a Data Flow Task. After the csv is created, I have a "Script Task" set to connect to an SMTP server and send the csv file as an attachment.
On my local machine the package runs fine, but when I load it into SQL Server Management Studio on the server it doesn't work as expected. SQL Server MS says that the package executed successfully, and the csv file is generated in the location expected. However, the "Script Task" doesn't appear to be executing at all. I've included some statements in the C# script to write to a file for debugging purposes - one for the try/catch exception block and a couple of others for normal execution.
public void Main()
{
string sSubject = "Weekly PAX Test";
string sBody = "Test Message";
int iPriority = 2;
if (SendMail(sSubject, sBody, iPriority))
{
Dts.TaskResult = (int)ScriptResults.Success;
}
else
{
//Fails the Task
Dts.TaskResult = (int)ScriptResults.Failure;
}
}
public bool SendMail(string sSubject, string sMessage, int iPriority)
{
try
{
string sEmailServer = Dts.Variables["User::sEmailServer"].Value.ToString();
string sEmailPort = Dts.Variables["User::sEmailPort"].Value.ToString();
string sEmailUser = Dts.Variables["User::sEmailUser"].Value.ToString();
string sEmailPassword = Dts.Variables["User::sEmailPassword"].Value.ToString();
string sEmailSendTo = Dts.Variables["User::sEmailSendTo"].Value.ToString();
string sEmailSendFrom = Dts.Variables["User::sEmailSendFrom"].Value.ToString();
string sEmailSendFromName = Dts.Variables["User::sEmailSendFromName"].Value.ToString();
string sAttachmentPath = Dts.Variables["User::sAttachmentPath"].Value.ToString();
SmtpClient smtpClient = new SmtpClient();
MailMessage message = new MailMessage();
MailAddress fromAddress = new MailAddress(sEmailSendFrom, sEmailSendFromName);
//You can have multiple emails separated by ;
string[] sEmailTo = Regex.Split(sEmailSendTo, ";");
int sEmailServerSMTP = int.Parse(sEmailPort);
smtpClient.Host = sEmailServer;
smtpClient.Port = sEmailServerSMTP;
System.Net.NetworkCredential myCredentials =
new System.Net.NetworkCredential(sEmailUser, sEmailPassword);
smtpClient.Credentials = myCredentials;
message.From = fromAddress;
if (sEmailTo != null)
{
for (int i = 0; i < sEmailTo.Length; ++i)
{
if (sEmailTo[i] != null && sEmailTo[i] != "")
{
message.To.Add(sEmailTo[i]);
}
}
}
switch (iPriority)
{
case 1:
message.Priority = MailPriority.High;
break;
case 3:
message.Priority = MailPriority.Low;
break;
default:
message.Priority = MailPriority.Normal;
break;
}
//You can enable this for Attachments.
//sAttachmentPath is a string variable for the file path.
Attachment myAttachment = new Attachment(sAttachmentPath);
message.Attachments.Add(myAttachment);
message.Subject = sSubject;
message.IsBodyHtml = true;
message.Body = sMessage;
smtpClient.Send(message);
System.IO.File.WriteAllText("C:\\Users\\SQLCLservice\\SQLServerAgent\\file.txt", "Test");
return true;
}
catch (Exception ex)
{
System.IO.File.WriteAllText("C:\\Users\\SQLCLservice\\SQLServerAgent\\ex.txt", ex.ToString());
return false;
}
}
No email is being sent - no files are being written. It's as if the task is not running at all despite the "Successful Execution".
I did notice that the SQL Server Integration Services 11.0 service is running on my local machine but not on the server. However, if I disable this service on my local machine the task still executes.
Am I missing something else? I'm pretty new to SQL Server and I've been working on this problem for days.
EDIT: I'm running SQL Server 2012
EDIT2: I should also mention that I've tried both saving the package with 64-bit runtime set to false and running it in 32-bit mode through the SQL Server Agent.
I faced a similar situation earlier, where everything works fine in SSDT(SQL Server Data Tools - which is Visual studio interface) and when my package is deployed in SSMS, just the script task was failing.
Using SSIS 2012, I was loading an excel sheet and then in the script task, I was calling an Excel macro to sort and highlight the differences in the sheet. Everything was working fine in the SSDT environment but when I ran in SSMS (as a Scheduled Job - 32 bit mode), The script task was not executing. However, I could see the Excel sheet loaded with raw data - without sorting and highlighting the differences.
No errors were captured in SSMS package execution logs. As highlighted by #Tab Alleman in the comments section, some of the errors were logged in the Event viewer. In my case, the error was logged under WindowsLogs > System
Which showed permission errors for SQLSERVERAGENT while accessing Microsoft SQL Server Integration Services 11.0.
The application-specific permission settings do not grant Local
Activation permission for the COM Server application with CLSID
{FDC3723D-1588-4BA3-92D4-42C430735D7D} and APPID
{83B33982-693D-4824-B42E-7196AE61BB05} to the user NT
SERVICE\SQLSERVERAGENT
And then after granting appropriate access (Steps to grant access is described here), I received one more permission error while the account tried to access Excel
The machine-default permission settings do not grant Local Activation
permission for the COM Server application with CLSID
{00024500-0000-0000-C000-000000000046} and APPID
{00020812-0000-0000-C000-000000000046} to the user NT
SERVICE\SQLSERVERAGENT
Even after resolving all the permission errors, I still couldn't see the expected output. So I increased the custom logging (refer here for steps) for the script task.
Then I was able to see the exceptions raised in the script task.
My catch block looks something like the one below:
catch (Exception ex)
{
Dts.Log(ex.ToString(), 0, emptyBytes);
}
Which will log the errors in the sysssislog table (which you must have configured while configuring custom logging)
select * from [*YourDatabaseName*].[dbo].[sysssislog]
Should list down your custom logs.
I too faced the similar situation, but resolved it differently. I had two key tasks in my SSIS package. A Script Task running C# and a Data Flow Task reading an Excel file. I first received this error:
OLE DB provider Microsoft.Jet.OLEDB.4.0 is not registered. If the 64-bit drive is not installed, run the package in 32-bit mode.
After running in 32 bit mode, I noticed that my Script Task didn't run. SSIS just ignored it as if it was disabled. I did find some Audit Failures in my Event Viewer.
The root cause of my Script Task not running was because it was being compiled for x64 (the default setting). Here are my steps that I used to fix this:
Edit Script
Right click the c# project name that looks like a GUID and choose properties
Select the Build menu on the left side of the properties page
Set the Platform target = x86
Now your Script Task will now run in 32 bit mode along with your 32 bit OLEDB Jet driver.
Check the build version of your project.
This happens when your build version is > than the target server version that the catalog uses. IE. Build version 2017 in visual studio to a 2016 sql server.
Change the build version of your project, then recompile all script tasks.
Use the ispac file to redeploy your project.
The script tasks will execute as expected.
I have an application where i create a mailItem using Outlook interop.
On some systems the code works without problems.
But on one of the systems this error appears:
Message= 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 for the interface with IID
'{00063001-0000-0000-C000-000000000046}' failed
due to the following error: Interface not registered
I think it has something to do with the register see: Answer on Error accesing COM components
But i need to solve this problem in the code, because i can't acces all the systems with this kind of problem.
using Outlook = Microsoft.Office.Interop.Outlook;
//Create email body with the customers
string mailBody = customers;
//Create the email with the settings
Outlook.Application outlookApp = new Outlook.Application();
Outlook.MailItem mailItem = (Outlook.MailItem)outlookApp.CreateItem(Outlook.OlItemType.olMailItem);
mailItem.Subject = mailSubject;
mailItem.Attachments.Add(totalPath);
mailItem.Body = mailBody;
mailItem.Importance = Outlook.OlImportance.olImportanceNormal;
try
{
//Try to open outlook, set message if its not possible to open outlook
mailItem.Display(true);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return false;
}
How can i solve this in my code?
P.S. Every system uses the office 2013 version!
Try to use the following code instead:
oApp = Activator.CreateInstance(Type.GetTypeFromProgID("Outlook.Application")) as Microsoft.Office.Interop.Outlook.Application;
It looks like something is wrong with the windows registry records. Take a look at the similar forum thread - Error: Unable to cast COM object of type 'Microsoft.Office.Interop.Outlook.ApplicationClass' to interface type 'Microsoft.Office.Interop.Outlook._Application'..
Do you have the Click2Run edition of Office installed on the PC? See How to: Verify Whether Outlook Is a Click-to-Run Application on a Computer for more information.