I am trying to send a mail on Outlook 2013 startup programmatically that has programmatically added attachments. Then the programm takes these attachments and creates a Password-locked Zip File and also adds this File as attachment. My Problem is, that I keep getting an
"System.IO.FileNotFoundException"
when executing
mail.Attachments.Add(pathToAttachment1);
I thought the path might not exist, but I can add this Path to a new zip-directory (using the same String), so it seems to be a Problem with the
Attachments.Add(Object)-Method.
MSDN says it is totally fine to give it a Pathname as String. In VBA it even worked, but in c# not (for whatever reason). Does somebody have an idea what i am doing wrong?
The Code i want to execute:
String pathToAttachment1 = #"C:\Testfile.txt";
//create a new ZipFile
ZipFile zipAttachment = new ZipFile("EncodedAttachments.zip");
zipAttachment.Password = "1234";
//Create a new MailItem
Outlook.MailItem mail = Application.CreateItem(Outlook.OlItemType.olMailItem);
//set Receiver, Body and Subject for the MailItem
mail.To = "foo";
mail.Body = "This is the body.";
mail.Subject = "This is the Subject.";
//This is working:
zipAttachment.AddFile(pathToAttachment1);
//This is the line where the Exception is thrown:
mail.Attachments.Add(pathToAttachment1);
This code is called in the Startup-Method handling the Outlook Startup Event. Does anyone have an idea what i might do wrong or could change to make it work?
Related
Here is the c# code:
Program.cs
string path = #"E:\Example.txt";
if (!File.Exists(path))
{
File.Create(path);
}
// smtp code for sending emails
SmtpClient clientDetails = new SmtpClient();
...
MailMessage mailDetails = new MailMessage();
...
Attachment attachment = new Attachment(#"E:\Example.txt"); // Error "The process can not access the file because it is being used by another process" occurs here
mailDetails.Attachments.Add(attachment);
clientDetails.Send(mailDetails);
Problem: The error (The process can not access the file because it is being used by another process) occurs only when the "Example.txt" file is NOT already existing. Meaning, the error only occurs if File.Create(path);creates "Example.txt" file and then, smtp is supposed to send this file. So, I assume that File.Create() is using the file even after creation of file is completed. Please help me to prevent it from using the txt file once it is created.
Thanks in advance for all kinds of help.
i am trying to create my own add-in for Outlook. My point is to extract some data from mails and then move these mails to Archive folder. When i open unread mails it works as i expect, but i got an error when i open unread mails in the moment when i am trying to move mail to Archive folder. I got an instance of mail from inspector. Here is some code.
Outlook.MailItem mail = inspector.CurrentItem as Outlook.MailItem;
var email = mail.UserProperties.Session.CurrentUser.Address;
Outlook.NameSpace ouNs = Globals.ThisAddIn.Application.GetNamespace("MAPI");
Outlook.MAPIFolder baseFolder = ouNs.Folders[email];
var archiveFolder = findFolderRecursive(baseFolder, archiveFolderName);
mail.Move(archiveFolder);
Messages returned from the inspector disallow some methods. Try to track the Inspector.Close event, store the message entry id in a variable, and enable a timer (use Timer class from the Forms namespace - it runs on the same thread). When the timer fires, disable it, open the item by its entry id using Namespace.GetItemFromID, then move it.
I want to open a specific email in Outlook from my C# winforms application.
At the moment I have got the following code:
//...Get Folder & Entry ID for last Email in Sent Box
Outlook.Application myApp = new Outlook.ApplicationClass();
Outlook.NameSpace mapiNameSpace = myApp.GetNamespace("MAPI");
Outlook.MAPIFolder mySentBox = mapiNameSpace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderSentMail);
Outlook.MailItem myMail = ((Outlook.MailItem)mySentBox.Items[1]);
string guid = myMail.EntryID;
string folderEntryID = mySentBox.EntryID;
string folderStoreID = mySentBox.StoreID;
string mailAddressee = myMail.To;
MessageBox.Show(mailAddressee);
//...Attempt to Open that Email at a later date
Outlook.MAPIFolder getFolder = (Outlook.MAPIFolder)mapiNameSpace.GetFolderFromID(folderEntryID, folderStoreID);
Outlook.MailItem getItem = (Outlook.MailItem)getFolder.Items.Find("[EntryID] = " + guid);
getItem.Display();
The first an second parts of the code will be run at different times, although they are in the same Method for testing at the moment.
The first part obtains the relevant IDs for the mst recently sent email from Outlook. This part seems to work fine as evidence my the Messagebox I've built in.
The second part however is not working and I'm struggling to find the right code to access and open that specific mailItem having obtained its ID and folder location in the first part.
Anyone able to complete this little project for me please.
Done it at last by replacing the following lines of code . . .
Outlook.MAPIFolder getFolder = (Outlook.MAPIFolder)mapiNameSpace.GetFolderFromID(folderEntryID, folderStoreID);
Outlook.MailItem getItem = (Outlook.MailItem)getFolder.Items.Find("[EntryID] = " + guid);
with this . . .
Outlook.MailItem getItem = (Outlook.MailItem)mapiNameSpace.GetItemFromID(guid, folderStoreID);
You can not use EntryId with the _Items.Find method. The MSDN reference is here.
There is also a remark which could be interesting for your project:
"The Entry ID changes when an item is moved into another store, for
example, from your Inbox to a Microsoft Exchange Server public folder,
or from one Personal Folders (.pst) file to another .pst file.
Solutions should not depend on the EntryID property to be unique
unless items will not be moved."
MailItem.EntryID Property (Outlook).
I've made program which one of the purposes is to open OutLook client where user can write his email, add attachments etc. After sending I want to get all attachments which were added to email, as well as all email in my program.
I tried to handle close event
((Microsoft.Office.Interop.Outlook.ItemEvents_10_Event)email.oMsg).Close += new Microsoft.Office.Interop.Outlook.ItemEvents_10_CloseEventHandler(GetAttachmentsInfo);
and then
if (email.oMsg.Attachments.Count > 0)
{
foreach (Microsoft.Office.Interop.Outlook.Attachment at in email.oMsg.Attachments )
{ attachments.Add(at); }
}
email is OutlookEMail
oMsg is Email Item
attachments is List<Attachment>
but when I close client Attachment throws exception that cannot find object. as well as these in List.
I know that Microsoft.Office.Interop.Outlook.Attachment is not a file, but only something like path to this file containing it name and size.
So question : is it possible to save attachments after client is closed in my program?
(Without using Email.SaveAttachments os SaveEmail methods, because it uses time and computer space)?
Here are two other options you could try:
1. You could listen for MailItem additions to the SentItems Folder via Folder.ItemAdd.
Outlook.Folder sentItems = Application.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderSentMail) as Outlook.Folder;
sentItems.ItemAdd += new Outlook.ItemsEvents_ItemAddEventHandler(GetAttachmentsInfo);
2. You could attach to the MailItem.Send event.
((Outlook.ItemEvents_10_Event)MailItem).Send += new Outlook.ItemEvents_10_SendEventHandler(GetAttachmentsInfo);
I'm facing a problem with an Internet application I'm working on right now (programming in C#).
I have to create a report and then send it via email to a certain user. After I create the report, I save it first into a temporary file, then attached it to the email giving the file path.
It's working on my computer because I have the administrator right, but it doesn't for my coworkers who don't have the admin right on their computer.
The file path I'm using is:
string filePath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.InternetCache),
fileName
);
Is there any temporary repository I can use that doesn't require admin rights?
Thanks.
Considering your ASP.NET tag, you should look at using Isolated Storage.
If you're using the built in mail classes in .Net, there's really no reason you need to write the attachment to a file at all, unless whatever is generating the report requires it.
This would work, assuming your report generator doesn't require file output and can just return bytes.
SmtpClient smtpClient = new SmtpClient(); //do whatever else you need to do here to configure this
byte[] report = GetReport();//whatever your report generator is
MailMessage m = new MailMessage();
//add your other mail fields (body, to, cc, subject etc)
using (MemoryStream stream = new MemoryStream(report))
{
m.Attachments.Add(new Attachment(stream,"reportfile.xls"));//just guessing, use the right filename for your attachment type
smtpClient.Send(m); //note that we send INSIDE this using block, because it will not actually read the stream until you send
//and you want to make sure not to dispose the stream before it reads it
}
How are you attaching it to the email? From the sounds of your question it appears that all you're doing is giving them the path to the file you create, rather than attaching it (as, once you attach it, it's embedded in the email and thus there are no paths involved).
If the web application is creating the temporary file then you can use the app_data folder (which is usually writable), and get a unique file name by using Path.GetRandomFileName().
So, something like
var myTemporaryFileName = Path.Combine(HttpContext.Current.Server.MapPath("~/App_Data",
Path.GetRandomFileName());
Then write your file to this temporary file name, then attach it to the email
MailMessage message = new MailMessage("recipient#example.com", "", ""
"subject",
"mail body");
Attachment data = new Attachment(file, MediaTypeNames.Application.Octet);
ContentDisposition disposition = data.ContentDisposition;
disposition.FileName = "thefilenameyouwanttouseintheemail.ext";
message.Attachments.Add(data);
Now you can send it.
Don't forget to clean them up after though!