Save content of Email body in outlook to a file - c#

i want to save the contents of the Email Body in outlook to a file. I am able to save the entire message .msg but i want to save only the html content of the body.
for example:
In the outlook email body i have a table i want to save that table to a file.
the script which i am working on:
public void GetAttachments()
{
Microsoft.Office.Interop.Outlook.Application myolApp = default(Microsoft.Office.Interop.Outlook.Application);
Microsoft.Office.Interop.Outlook.NameSpace ns = default(NameSpace);
MAPIFolder Inbox = default(MAPIFolder);
object Item = null;
Attachment Atmt = default(Attachment);
string FileName = null;
string subject = null;
string AttachmentName = null;
string Body = null;
string SenderName = null;
string SenderEmailAddress = null;
string CreationTime = null;
int i = 0;
int j = 0;
try
{
myolApp = (Microsoft.Office.Interop.Outlook.Application)Interaction.CreateObject("Outlook.Application","");
ns = myolApp.GetNamespace("MAPI");
ns.Logon("", "", false, true);
Inbox = ns.Folders["Mailbox - Name"].Folders["Inbox"];
i = 0;
j = 1;
//Scan for attachments
foreach (object Item_loopVariable in Inbox.Items)
{
Item = Item_loopVariable;
System.Windows.Forms.Application.DoEvents();
if ((Item as MailItem) != null ? ((MailItem)Item).UnRead : false)
{
Body = ((Microsoft.Office.Interop.Outlook.MailItem)Item).Body;
((Microsoft.Office.Interop.Outlook.MailItem)Item).HTMLBody = Body;
((Microsoft.Office.Interop.Outlook.MailItem)Item).SaveAs(#"\\path\"+"filename", Microsoft.Office.Interop.Outlook.OlSaveAsType.olHTML );
j = j + 1;
}
}
//Clear Memory
Atmt = null;
Item = null;
ns = null;
}
catch (System.Exception ex)
{
MessageBox.Show("An unexpected error has occurred."
+ "\r\n" + "Please note and report the following information."
+ "\r\n" + "Script Name: GetAttachments"
+ "\r\n" + "Error Description: " + ex.Message
+ "\r\n" + "Error StackTrace: " + ex.StackTrace
, "Error!");
Atmt = null;
Item = null;
ns = null;
}
}
I need changes in these piece of code:
Body = ((Microsoft.Office.Interop.Outlook.MailItem)Item).Body;
((Microsoft.Office.Interop.Outlook.MailItem)Item).HTMLBody = Body;
((Microsoft.Office.Interop.Outlook.MailItem)Item).SaveAs(#"\\path\"+"filename", Microsoft.Office.Interop.Outlook.OlSaveAsType.olHTML );

Outlook has some issues with saving the body of an email, as far as the filesystem security goes. A workaround is to use the file system objects to save the body - worked for me.

Related

Exception from HRESULT: 0x80004004 (E_ABORT) at Outlook.Mailitem.getHtmlBody()

I have a custom add-in which gets the body on clicking a button when it got installed. so I am getting this error on a customer machine. code is working fine on my side and for other customers but one customer is facing this problem.
this is my code
private void button1_Click(object sender, RibbonControlEventArgs e)
{
Microsoft.Office.Interop.Outlook.Application olApp = new Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook.NameSpace ns = olApp.GetNamespace("MAPI");
Explorer olExp = olApp.ActiveExplorer();
Selection olSel = olExp.Selection;
string msg = "";
int iterate = 1;
MAPIFolder inbox = null;
if (olSel.Count > 1)
{
MessageBox.Show("Sorry! You can't report more then 1 email at a time", "Report Email");
return;
}
foreach (_MailItem mail in olSel)
{
inbox = ns.GetDefaultFolder(OlDefaultFolders.olFolderInbox);
mail.GetInspector.Display(false);
Thread.Sleep(2100);
string screenShot = getScreenShot(mail);
mail.GetInspector.Close(OlInspectorClose.olDiscard);
String msgToShow = "Are you sure you want to report this email as suspicious?";
if (mail != null && mail.Subject != null)
msgToShow += "\n\nSubject : " + mail.Subject.ToString();
DialogResult dr = MessageBox.Show(msgToShow, "Please Confirm", MessageBoxButtons.YesNo,
MessageBoxIcon.Exclamation);
if (dr == DialogResult.Yes)
{
msg += reportMail(mail, screenShot, e);
}
else {
return;
}
iterate++;
break;
}
if (!msg.Equals(""))
MessageBox.Show(msg, "Report Email");
else
return;
if (!msg.Contains("Success"))
return;
MailItem moveMail = null;
MAPIFolder subfolder = null;
try
{
subfolder = inbox.Folders["Reported Emails"];
}
catch (System.Exception ex) {
subfolder = inbox.Folders.Add("Reported Emails", OlDefaultFolders.olFolderInbox);
}
foreach (MailItem eMail in olSel)
{
try
{
moveMail = eMail;
if (moveMail != null)
{
string titleSubject = (string)moveMail.Subject;
moveMail.Move(subfolder);
}
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
private string reportMail(_MailItem mail, string screenShot, RibbonControlEventArgs e)
{
try
{
var m = Globals.ThisAddIn.Application.GetNamespace("MAPI");
var mailitem = mail;
if (mailitem != null)
{
// Console.WriteLine("Email body ::: " + mailitem.HTMLBody);
String reporterEmail = getReporterEmail(mailitem);
String senderEmailAddress = "";
String senderName = "";
AddressEntry mailsender;
if (reporterEmail.Equals(""))
{
MessageBox.Show("Sorry! This email can't be reported because you are not included in Recipients.", "Report Email");
}
else
{
if (mailitem.SenderEmailType == "EX")
{
mailsender = mailitem.Sender;
if (mailsender != null)
{
if (mailsender.AddressEntryUserType == OlAddressEntryUserType.olExchangeUserAddressEntry || mailsender.AddressEntryUserType == OlAddressEntryUserType.olExchangeRemoteUserAddressEntry)
{
ExchangeUser exchUser = mailsender.GetExchangeUser();
if (exchUser != null)
{
senderEmailAddress = exchUser.PrimarySmtpAddress;
senderName = exchUser.Name;
}
}
}
}
else
{
senderEmailAddress = mailitem.SenderEmailAddress;
senderName = mailitem.SenderName;
}
String emailHeader = mailitem.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x007D001E");
String emailBody = mailitem.Body.Replace("%"," percent").Replace("#","").Replace("|", "");
//String res = HttpPost(Properties.Settings.Default.address, "ReporterEmail=" + reporterEmail + "&suspectedName=" + senderName + "&FromEmail=" + senderEmailAddress
// + "&ToEmail=" + mailitem.To + "&Subject=" + mailitem.Subject + "&EmailBody=" + emailBody + "&AttachmentName=" + GetAttachments(mailitem)
// + "&reporter=" + reporterEmail + "&emailHeader=" + emailHeader + "&mailImage=" + screenShot);
String htmlBody = mail.HTMLBody;
MessageBox.Show(htmlBody);
Dictionary<string, object> postParameters = new Dictionary<string, object>();
postParameters.Add("ReporterEmail", reporterEmail);
postParameters.Add("suspectedName", senderName);
postParameters.Add("FromEmail", senderEmailAddress);
postParameters.Add("ToEmail", mailitem.To);
postParameters.Add("Subject", mailitem.Subject);
postParameters.Add("EmailBody", emailBody);
List<String> attachmentDetails = GetAttachments(mailitem);
postParameters.Add("AttachmentName", attachmentDetails[0]);
postParameters.Add("reporter", reporterEmail);
postParameters.Add("emailHeader", emailHeader);
postParameters.Add("mailImage", screenShot);
string res = HttpPost(Properties.Settings.Default.serverAddress+ "/PhishRod-portlet/reporter", postParameters, htmlBody,attachmentDetails[1]);
return res + "\n";
}
}
}
catch (System.Exception ex)
{
log.Error(ex);
return "Error: " + ex + "-- - " + ex.StackTrace.ToString() + "\n";
}
return "";
}
In the event handler of your button I see the following lines of code:
Microsoft.Office.Interop.Outlook.Application olApp = new Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook.NameSpace ns = olApp.GetNamespace("MAPI");
There is no need to create a new Outlook Application instance in the add-in. Instead, you need to use the Application property which doesn't trigger a security issue when dealing with OOM from external applications:
var app = Globals.ThisAddIn.Application

c# - How to call/link a workflow on a web application from a c# program?

I have a C# (WinForms) application that can scan documents via a printer. After scanning, I will be able to enter document details on it and have a button to finalize the documents. The documents details and info will be stored in my database ABC in certain tables.
Now, I have another web application written in Java(IntelliJ) that has some button functionality to upload documents and then start a workflow and route it to another user to approve the document. I won't go into detail on the specifics. This application also connects to the same database ABC.
So now comes the tougher part, I need to link these two applications in a way that when I finalize my document
on the C# application, it has to auto trigger the workflow on the web application side. Rather than manually starting the workflow on the web application, it would just call or trigger the workflow, so I do not need to access the web application at all for the process to start.
private void FinButton_Click(object sender, EventArgs e)
{
int count = 0;
var txtBoxFields = new List<TextBox>
{
textBox1,
textBox2,
textBox3,
textBox4,
textBox5,
textBox6,
textBox7,
textBox8,
textBox9,
textBox10,
textBox11,
textBox12,
textBox13,
textBox14,
textBox15
};
var templateFields = new List<String>
{
"T1",
"T2",
"T3",
"T4",
"T5",
"T6",
"T7",
"T8",
"T9",
"T10",
"T11",
"T12",
"T13",
"T14",
"T15"
};
//long tid = 0;
//Start insert query into templatebatch table in db
var dbConnection2 = DBConnection.Instance();
dbConnection2.DatabaseName = ConfigurationManager.AppSettings["dbName"];
if (dbConnection2.IsConnect())
{
bool test = true;
for (int i = 1; i <= 15; i++)
{
var input = txtBoxFields[i - 1].Text;
var insertQuery = "INSERT INTO templateinfo(TID, THEADER, " + templateFields[i - 1] + ") VALUES(#tid, #theader,#t" + i + ")";
var insertCmd = new MySqlCommand(insertQuery, dbConnection2.Connection);
insertCmd.Parameters.AddWithValue("#tid", tid);
insertCmd.Parameters.AddWithValue("#theader", "N");
if (String.IsNullOrEmpty(input))
{
count = 1;
insertCmd.Parameters.AddWithValue("#t" + i, String.Empty);
break;
}
else
{
if (test)
{
insertCmd.Parameters.AddWithValue("#t" + i, txtBoxFields[i - 1].Text);
insertCmd.ExecuteNonQuery();
test = false;
var selectQuery = "select TINFOID from templateinfo where TID=" + tid + " and THEADER = 'N'";
var selectCmd = new MySqlCommand(selectQuery, dbConnection2.Connection);
var selectReader = selectCmd.ExecuteReader();
using (MySqlDataReader dr = selectReader)
{
while (dr.Read())
{
tinfoid = Convert.ToInt32(dr["TINFOID"]);
}
}
}
else
{
var updateQuery = "update templateinfo set " + templateFields[i - 1] + "='" + txtBoxFields[i - 1].Text + "' where TINFOID = '" + tinfoid + "' and TID=" + tid + " and THEADER='N'";
var updateCmd = new MySqlCommand(updateQuery, dbConnection2.Connection);
var updateReader = updateCmd.ExecuteReader();
using (var reader = updateReader)
{
}
}
}
}
}
if (count == 1)
{
//MessageBox.Show("Input field(s) cannot be left empty.");
}
//Finalize here
var client = new LTATImagingServiceClient();
client.Finalize(userID, tid, tinfoid, batchID);
Debug.WriteLine(userID + ", " + tid + ", " + tinfoid + ", " + batchID);
var batchName = templateView.SelectedNode.Text;
var folderPath = #"C:\temp\batches\" + mastertemplatename + #"\" + subtemplatename + #"\" + batchName + #"\";
ThumbnailLists.Items.Clear();
// var img = Image.FromFile(#"C:\temp\batch-done.png");
if (ImageBox.Image != null)
{
ImageBox.Image.Dispose();
}
ImageBox.Image = null;
try
{
using (new Impersonation(_remoteDomain, _remoteUser, _remotePassword))
{
// MessageBox.Show(_remoteUser);
// MessageBox.Show(_remotePassword);
var tPath = #"\\126.32.3.178\PantonSys\SAM\Storage\3\" + mastertemplatename + #"\" + subtemplatename + #"\" + batchName + #"\";
bool exists = System.IO.Directory.Exists(tPath);
if (!exists)
{
System.IO.Directory.CreateDirectory(tPath);
}
string[] fileList = Directory.GetFiles(folderPath, "*");
foreach (var file in fileList)
{
File.Copy(file, tPath + Path.GetFileName(file));
}
CurrentPageBox.Text = "";
NumberPageBox.Text = "";
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
MessageBox.Show(ex.Message);
}
var dbConnection = DBConnection.Instance();
dbConnection.DatabaseName = ConfigurationManager.AppSettings["dbName"];
if (dbConnection.IsConnect())
{
var deleteBatchQuery = "DELETE FROM templatebatch WHERE batchname ='" + templateView.SelectedNode.Text + "'";
var deleteBatchCmd = new MySqlCommand(deleteBatchQuery, dbConnection.Connection);
var deleteBatchReader = deleteBatchCmd.ExecuteReader();
using (var reader = deleteBatchReader)
{
while (reader.Read())
{
}
}
templateView.Nodes.Remove(templateView.SelectedNode);
Directory.Delete(folderPath, true);
MessageBox.Show("Successfully Transferred.");
foreach (var txtFields in txtBoxFields)
{
txtFields.Text = "";
txtFields.Enabled = false;
}
finButton.Visible = false;
finButton.Enabled = false;
}
bindButton.Visible = false;
}
Would this be possible to achieve or just being far-fetched?
I would appreciate any suggestions or pointers on this. Do let me know if there is anything unclear in my explanation.
EDIT:
Request URL: http://126.32.3.178:8111/process/taskmanager/start/start.jsp
Request Method: POST
Status Code: 200 OK
Remote Address: 126.32.3.178:8111
Referrer Policy: no-referrer-when-downgrade
Is there a way I could call this from the C# application?
You can send your file directly from your C# app with use of Http client. Here is code sample:
private async Task<bool> Upload(string filePath)
{
const string actionUrl = #"http://126.32.3.178:8111/process/taskmanager/start/start.jsp";
var fileName = Path.GetFileName(filePath);
var fileBytes = File.ReadAllBytes(filePath);
var fileContent = new ByteArrayContent(fileBytes);
using (var client = new HttpClient())
using (var formData = new MultipartFormDataContent())
{
formData.Add(fileContent, fileName);
var response = await client.PostAsync(actionUrl, formData);
return response.IsSuccessStatusCode;
}
}
Also, note that there maybe some sort of authentication should be performed before you can post a request.

How to ignore protected pdf's?

I am writing on my pdf-word converter and I just received a really strange exception witch makes no sens to me.
Error:PdfiumViewer.PdfException:{"Unsupported security scheme"}
Its the first time that such a exception appears. but I have to be honest that I never tried to convert more then 3-4 files from pdf to word and right now I am doing more then 100 files.
Here is my code I am sry if its too long but I simply do not know on which line the error occurs
public static void PdfToImage()
{
try
{
Application application = null;
application = new Application();
string path = #"C:\Users\chnikos\Desktop\Test\Batch1\";
foreach (string file in Directory.EnumerateFiles(path, "*.pdf"))
{
var doc = application.Documents.Add();
using (var document = PdfiumViewer.PdfDocument.Load(file))
{
int pagecount = document.PageCount;
for (int index = 0; index < pagecount; index++)
{
var image = document.Render(index, 200, 200, true);
image.Save(#"C:\Users\chnikos\Desktop\Test\Batch1\output" + index.ToString("000") + ".png", ImageFormat.Png);
application.Selection.InlineShapes.AddPicture(#"C:\Users\chnikos\Desktop\Test\Batch1\output" + index.ToString("000") + ".png");
}
string getFileName = file.Substring(file.LastIndexOf("\\"));
string getFileWithoutExtras = Regex.Replace(getFileName, #"\\", "");
string getFileWihtoutExtension = Regex.Replace(getFileWithoutExtras, #".pdf", "");
string fileName = #"C:\Users\chnikos\Desktop\Test\Batch1\" + getFileWihtoutExtension;
doc.PageSetup.PaperSize = WdPaperSize.wdPaperA4;
foreach (Microsoft.Office.Interop.Word.InlineShape inline in doc.InlineShapes)
{
.....
}
doc.PageSetup.TopMargin = 28.29f;
doc.PageSetup.LeftMargin = 28.29f;
doc.PageSetup.RightMargin = 30.29f;
doc.PageSetup.BottomMargin = 28.29f;
application.ActiveDocument.SaveAs(fileName, WdSaveFormat.wdFormatDocument);
doc.Close();
string imagePath = #"C:\Users\chnikos\Desktop\Test\Batch1\";
Array.ForEach(Directory.GetFiles(imagePath, "*.png"), delegate(string deletePath) { File.Delete(deletePath); });
}
}
}
catch (Exception e)
{
Console.WriteLine("Error: " + e);
}
}
}
}

Outlook 2007: Reading Pane is not updated when an encrypted Email is imported

we use Redemptiontools to develop a Addin for Outlook. At first we create Emailstubs from a Metadataset. When the User select a Mail we load a msg file from the Network and import it into the Emailstub. We dont have any problems in Outlook 2010/2013/2016.
But in Outlook 2007 the reading pane doesnt refresh if the mail has a Signature. I have deselect and reselect the Mail and then i can see the new mail.
Creating the Emailstub from an metadataset:
using (ComObjectWrapper<RDOFolder> rdoFolder = RDOSession.Resource.GetFolderFromID(folderEntryID).WithComCleanup())
{
using (ComObjectWrapper<RDOMail> mailstub = rdoFolder.Resource.Items.Add().WithComCleanup())
{
mailstub.Resource.Sent = true;
mailstub.Resource.SenderName = metadatamail.SenderName + " ";
mailstub.Resource.SenderEmailAddress = metadatamail.SenderEmailAddress + " ";
mailstub.Resource.SentOnBehalfOfName = metadatamail.SentOnBehalfOfName + " ";
mailstub.Resource.SentOnBehalfOfEmailAddress = metadatamail.SentOnBehalfOfEmailAddress + " ";
mailstub.Resource.Subject = metadatamail.Subject + " ";
mailstub.Resource.ReceivedTime = metadatamail.ReceivedTime;
mailstub.Resource.Body = metadatamail.Body + " ";
mailstub.Resource.To = metadatamail.To + " ";
mailstub.Resource.ReceivedByName = metadatamail.ReceivedByName + " ";
mailstub.Resource.UnRead = metadatamail.UnRead;
if (metadatamail.ContainsAttachments)
{
var Attach = mailstub.Resource.Attachments.Add(new char[0]);
Attach.FileName = "Attachment.txt";
}
mailstub.Resource.Save();
}
}
Importing the msg file in the selection change Event of the Explorer (expl):
void expl_SelectionChange()
{
using (var selection = expl.Selection.WithComCleanup())
{
foreach (var item in selection.Resource)
{
if (item is Outlook.MailItem)
{
string entryID = (item as Outlook.MailItem).EntryID;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
if (!string.IsNullOrEmpty(entryID))
{
using (var researchEntry = RDOSession.Resource.GetMessageFromID(entryID).WithComCleanup())
{
string mailpath = GetEmailFromNetwork(entryID);
if (!string.IsNullOrEmpty(mailpath))
{
Redemption.SafeMailItem sItem = new Redemption.SafeMailItem();
sItem.Item = researchEntry.Resource;
sItem.Import(mailpath, (int)rdoSaveAsType.olMSG);
sItem.ReleaseComObject<Redemption.SafeMailItem>();
researchEntry.Resource.Save();
}
}
}
}
}
}
}
RDOSession:
private ComObjectWrapper<RDOSession> RDOSession
{
get
{
try
{
var rdoSession = Activator.CreateInstance(Type.GetTypeFromProgID("Redemption.RDOSession")) as RDOSession;
if (rdoSession != null)
{
rdoSession.MAPIOBJECT = this.Application.Session.MAPIOBJECT;
return rdoSession.WithComCleanup();
}
}
catch { }
return null;
}
}
Does anyone have a hint or a solution?

Error Occurs at the time of assigning data to DataSource

Below code works the first time - at Page_Load it's working, data showing in the gridview control. But when I add new data to the database and retrieve I get an error.
I put the breakpoint and I checked step-by-step: DataTable dtsent is not null, it has data, but when it comes to gridSent.DataSource=dtsent an error occurs:
NullReferenceException was unhandled by user code
Object reference not set to an instance of an object
public void BindGridSent()
{
try
{
BusinessObject.BusinessObject bogetMS = new BusinessObject.BusinessObject();
bogetMS.UserID = Convert.ToInt32(HttpContext.Current.Session["uid"]);
DataTable dtsent = new DataTable();
dtsent.Columns.Add("msgID");
dtsent.Columns.Add("ToUsername");
dtsent.Columns.Add("msgContent");
dtsent.Columns.Add("msg_sent_date");
dtsent.Columns.Add("fullmsgContent");
DataRow dwsent = null;
DataSet dssent = businssLogicMS.MessageSentList_BAL(bogetMS);
if (dssent.Tables[0].Rows.Count > 0)
{
for (int i = 0; i < dssent.Tables[0].Rows.Count; i++)
{
dwsent = dtsent.NewRow();
string msgID = dssent.Tables[0].Rows[i]["msgID"].ToString();
dwsent["msgID"] = msgID;
//string username=" <b>" + dssent.Tables[0].Rows[i]["ToUsername"].ToString() + "</b> ";
string username = dssent.Tables[0].Rows[i]["ToUsername"].ToString();
dwsent["ToUsername"] = username;
string stmsg = dssent.Tables[0].Rows[i]["msgContent"].ToString();
string message = stmsg.Substring(0, Math.Min(stmsg.Length, 80)) + "...";
string editmsgbody = message.ToString().Replace("<br />", Environment.NewLine);
dwsent["msgContent"] = editmsgbody;
dwsent["fullmsgContent"] = stmsg;
string date = String.Format("{0:MMM dd}", dssent.Tables[0].Rows[i]["msg_sent_date"]);
dwsent["msg_sent_date"] = "<font color='Red'>" + date + "</font>";
dtsent.Rows.Add(dwsent);
}
gridSent.DataSource = dtsent; --- Error Occurs Here
gridSent.DataBind();
}
else
{
dtsent.Rows.Add(dtsent.NewRow());
gridSent.DataSource = dtsent;
gridSent.DataBind();
int columncount = gridSent.Rows[0].Cells.Count;
gridSent.Rows[0].Cells.Clear();
gridSent.Rows[0].Cells.Add(new TableCell());
gridSent.Rows[0].Cells[0].ColumnSpan = columncount;
gridSent.Rows[0].Cells[0].Text = "No Record Found....";
}
}
catch (Exception ex)
{
throw ex;
}
}

Categories