Send email attachment to a local folder - windows

I am trying to send an email from a client PC (i.e. Windows) with an attachment and have the attachment saved to a local folder on the same client PC. I have looked at a couple of alternatives, such as MailDrop (email to dropbox) and Outlook 2003 Interop library - but want to make sure I am implementing this the best way.
Does anyone have any different ideas on a simple/elegant solution?

As long as you know Outlook will be installed on all the clients the Outlook solution works very well. You can create a file and save it, then in your outlook interop you just attach and send. You didn't specify what tools you are using but here's the basic email creation method I use for Outlook in C# (Where OutlookSetup.OutlookApp is just a static method that returns the currently open instance of the Outlook application or creates a new one if Outlook isn't open). Otherwise there are several examples here on SO of using SmtpClient to achieve similar ends.
public EmailMessage(EmailInfo emailInfo, string filenameToAttach=null)
{
Message = OutlookSetup.OutlookApp.CreateItem(OL.OlItemType.olMailItem);
Message.To = emailInfo.To;
Message.CC = emailInfo.Cc ?? "";
Message.Subject = emailInfo.Subject;
if (filenameToAttach != null)
{
Message.Attachments.Add(filenameToAttach);
}
}

Related

MAPI showing details of contacts

We are currently using MAPI to load contact information into a form.
Within a MapiSession we are creating a RDOAddressEntry "recepient" with this bit of code
using (MapiSession session = new MapiSession())
{
//open outlook contact dialog
RDOAddressEntry recipient = session.GetAddressEntryFromID(contact.EntryId);
if (recipient.Type == null)
{
throw new ArgumentException("type not defined");
}
recipient.Details(handle.ToInt32());
}
Our problem seems to be that the dialog that opens with the last line of code creates two different dialogs. One for exchange contacts and another one for SMTP contacts.
In the last version of our application it was always opening the same dialog for both RDOAddressEntry-types and we did NOT change anything in our code...
Can you help me fix this issue so that both SMTP and exchange will bring the same dialogs again?
I am not sure why you were getting the same dialog for both before - the dialog is actually provided by the particular address book provider, so it will be different for the entries from different providers.

Is there any better way to launch outlook add-appointment window in bot application?

I need to launch outlook calendar appointment in bot application. I found the below code in Microsoft documentation for launching outlook email.
var message = context.MakeMessage() as IMessageActivity;
message.ChannelData = JObject.FromObject(new
{
action = new { type = "LaunchUri", uri = "mailto:someone#example.comsubject=This%20is%20the%20subject&body=This%20is%20t e%20body"
}
});
await context.PostAsync(message);
And also i tried the Microsoft.Office.Interop.Outlook to add appointment , it also doesn't work for me.
Outlook.Application outlookApp = new Outlook.Application(); // creates new outlook app
Outlook.AppointmentItem oAppointment = (Outlook.AppointmentItem)outlookApp.CreateItem(Outlook.OlItemType.olAppointmentItem); // creates a new appointment
oAppointment.Subject = apt.Subject;
oAppointment.Body = apt.Body;
oAppointment.Location = apt.Location;
oAppointment.Start = Convert.ToDateTime(apt.StartTime);
oAppointment.End = Convert.ToDateTime(apt.EndTime);
Is there any better way to launch outlook calendar appointment.
Your code must call oAppointment.Save.
What exactly are you trying to do? Silently create an appointment (then you code above needs to call oAppointment.Save) or display it to the user (then call oAppointment.Display)?
If your code is running on a server, create an iCal file and let the user download and open in (local) Outlook - it will be happy to display the appointment.
Steve mentioned you could use Microsoft Graph.
You might be able to send an ics file as a media attachment (I haven't tried).
Or you can investigate if the protocol handler outlookcal: supports deep linking.
I think this link tells you how it works in Teams
https://learn.microsoft.com/en-us/microsoftteams/platform/concepts/deep-links

Outlook 365 get Mail Item

I have following problem:
We have an Outlook Addin (VSTO), with which we archive emails (orders) in SAP.
Now the plugin should be implemented for Outlook 365. I already looked at the new api and i get die subject or maitext but there seems no way to get to the raw .msg file.
So my question now is, is there a way to get an mailitem as an .msg file (or any other format)?
There are two ways may be you can try
Use the process to run the .msg
string file= #"C:\PWS\myMail.msg";
Process.Run(file);
Use OpenSharedItem to open it:
var app = new Outlook.Application();
var item = app.Session.OpenSharedItem(msgfile) as Outlook.MailItem;
//Do stuff with the mail.
item.Close(OlInspectorClose.olDiscard);
app.Quit();
Marshal.ReleaseComObject(item);

How to check existence of a property in Outlook Interop?

I am trying to determine sender of a email in Outlook 2007 and above. In Outlook 2010 you have a Sender property on the MailItem object while in Outlook 2007 you have to do it differently like mentioned in this question.
So now I need to know whether current version of Outlook supports the Sender property, and if it does not, use the other method. The reason for doing this is I would prefer to use the Sender property for compatibility with future versions of Outlook rather than having condition on version of Outlook.
So the question is how do I determine whether a property exists in Outlook Interop ? Obviously, this being a COM object I cannot use reflection here.
I used the MailItem.ItemProperties collection to check for the "Sender" property. Below is the code
Microsoft.Office.Interop.Outlook.MailItem myMail;
//Code to get the mail
....
Microsoft.Office.Interop.Outlook.ItemProperties mailProps = myMail.ItemProperties;
Microsoft.Office.Interop.Outlook.ItemProperty mailProp = mailProps.Item ("Sender"); //the parameter is case-sensitive
if(mailProp != null)
{
//get email address using Sender object
Microsoft.Office.Interop.Outlook.AddressEntry theSender = myMail.Sender;
}
else
{
//use alternate method for Outlook 2007
}
You can use IDispatch::GetIDsOfNames to see if the property exists

Outlook.Application.CreateItem with Office365 says: The operation failed

We've written an Outlook plugin using Add-in-Express. Code:
private void CreateShowMessageUsingCreateItem(Outlook._Application OutlookApp)
{
Outlook.MailItem mail = null;
try
{
mail = OutlookApp.CreateItem(Outlook.OlItemType.olMailItem) as Outlook.MailItem;
mail.Save();
mail.Display(false);
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
}
finally
{
if (mail != null) Marshal.ReleaseComObject(mail);
}
}
Works when Outlook is connected to Exchange. Fails when
Outlook is connected to Office365. Error:
Exception: System.Runtime.InteropServices.COMException (0x80004005): The operation failed.
at Microsoft.Office.Interop.Outlook.ApplicationClass.CreateItem(OlItemType ItemType)
at DocuSignInk.DSToolbox.ShowResponse(MailItem senderEmail) in C:\docusign_source\Ink_Outlook\DocuSignInk\DSToolbox.cs:line 540
Some research indicates that you need to release your objects
when making these calls in a loop. But I'm not in a loop. I
can't even get one call to work, so I don't get to the point
where I can release anything.
Testing with Wireshark and Charles indicates that the problem is
in the client. I was trying to see if there is a more detailed
error coming from the server, but there's no traffic to the server
at all.
A quick Python script works from the command line.
import win32com.client
outlook = win32com.client.Dispatch('Outlook.Application')
mail = outlook.CreateItem(win32com.client.constants.olMailItem)
mail.Save()
mail.Display(False)
So it must be something in the client. I'm guessing maybe thread-related?
This can happen if you haven't activated Microsoft Office (which includes Outlook).
Short, test add-ins can work if they run right away before the activation check happens.
Once the activation check happens the API calls will fail.
Firstly, the code is correct, no additional releasing is required. The most obvious reason is that your Outlook, when connected to Exchange Online, cannot create a mail item. You can check this with the following VBA macro:
Public Sub CreateEmailItem()
Dim mail As Outlook.MailItem
Set mail = Application.CreateItem(olMailItem)
mail.Save
mail.Display (False)
Set mail = Nothing
End Sub
Regards,
Dmitry Kostochko (Add-in Express Team)
I had the same exception along with HResult that was -2147467259.
The direct reason was an outlook popup window informing about its trial version or an outlook closing process which is pending after you have closed previous activities in outlook including an email that was showed up by executing the above code (this process is indicated by a respective tray icon in the taskbar until it disappears).
You need to close the window first or wait for the tray icon to disappear before you execute creating new email.

Resources