How to change Sender in late binding Outlook Mail from c# - outlook

I want to send an eMail through Outlook by using late binding. It works fine so far but i want to use an other "FROM" adress, not the one my outlook-account uses.
Does anyone know how to do this?
By trying early binding i found some properties "Sender", "SenderEmailAdress" ... but nothing works for me or i'm doing it wrong ... (i think so)
This is my code for creating the mail and open outlook.
try
{
CreateObject co = new CreateObject("Outlook.Application");
object[] parms = new object[1];
parms[0] = 0;
object mailitem = co.Execute("CreateItem", parms);
// define TO
object recipients = mailitem.GetType().InvokeMember("Recipients", BindingFlags.GetProperty, null, mailitem, null);
object[] address = new object[1];
address[0] = toAdress;
recipients.GetType().InvokeMember("Add", BindingFlags.InvokeMethod, null, recipients, address);
// define subject
parms[0] = subject;
mailitem.GetType().InvokeMember("Subject", BindingFlags.SetProperty, null, mailitem, parms);
// define MailText
parms[0] = mailText;
mailitem.GetType().InvokeMember("Body", BindingFlags.SetProperty, null, mailitem, parms);
// open Outlook to send manually
mailitem.GetType().InvokeMember("Display", BindingFlags.InvokeMethod, null, mailitem, null);
}
catch (Exception ex)
{
throw;
}

You can only alter the SentOnBehalfOfName property; Sender and SenderEmailAddress are read-only properties. If you need to send using a different sender than you need to set the SendUsingAccount property to an Account object representing the account configured for that sender.

Related

Outlook VSTO - Create Mail and save it in Inbox - Set Sender using Outlook Redemption

I basically want to create emails which shall be displayed in the Outlook Inbox using C# Outlook VSTO AddIn.
I have installed the test dlls for Outlook Redemption in my C# Outlook VSTO Addin.
For testing purposes I created a Ribbon Bar with a button. When the button is clicked the following event is triggered:
private void CreateMailItemWithRedemption()
{
//FYI: outlookApp is set in Ribbon load event
//Outlook.Application outlookApp = Globals.ThisAddIn.Application as Microsoft.Office.Interop.Outlook.Application;
var outlookNameSpace = outlookApp.GetNamespace("MAPI");
RDOSession session = new RDOSession();
session.MAPIOBJECT = outlookNameSpace.MAPIOBJECT;
RDOFolder folder = session.GetDefaultFolder(rdoDefaultFolders.olFolderInbox);
RDOMail msg = folder.Items.Add("IPM.Note");
msg.Sent = true;
DateTime dt = new DateTime(2021, 8, 29, 5, 10, 20, DateTimeKind.Utc);
msg.ReceivedTime = dt;
msg.Subject = "Mail created with Redemption";
msg.To = “******#outlook.com”;
msg.Sender = GetAddressEntry("[TestFirstName] [TestLastName]");
msg.Save();
}
It basically works – but for the time being I am stuck with setting the Sender for the new RDOMail which I understand needs to be an RDOAddressEntry.
The GetAddressEntry method looks as follows (with firstname string + lastname string of an existing contact as parameter, like “John Do”):
private RDOAddressEntry GetAddressEntry(string _name)
{
RDOSession session = new RDOSession();
session.MAPIOBJECT = outlookApp.Session.MAPIOBJECT;
RDOAddressList contacts = session.AddressBook.GAL;
RDOAddressEntry contact = contacts.ResolveName(_name);
MessageBox.Show(contact.ToString());
return contact;
}
At contacts.ResolveName an exception is thrown. Do you have an idea what I am doing wrong?
Any hints are welcomed.
Many thanks in advance
Alexander

Access Custompropertie set by Office.js from EWS

I have made a Outlook Addin Angular8 Application using Office.js to interact with Outlook.
Everything works fine, the Addin works fine and stores a CustomPropertie to the Mailitem which can be read after reopening the Mailitem.
In this Implementation this is a simple hashmap.
this.customPropertiesContainer.set('lvAppointmentServiceId', this.selfiId);
this.customPropertiesContainer.saveAsync();
Now I want to read the Propertie in another Application using EWS to get the Mail Item.
Here the Implementation is very complex.
private PropertySet getPropertySetKnown() {
PropertySet propertySet = null;
try {
propertySet = new PropertySet(BasePropertySet.FirstClassProperties, getExtendedPropertyDefinition());
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return propertySet;
}
private ExtendedPropertyDefinition getExtendedPropertyDefinition() throws Exception {
ExtendedPropertyDefinition extendedPropertyDefinition = new ExtendedPropertyDefinition(
DefaultExtendedPropertySet.PublicStrings, CATERING_JIRA_ID, MapiPropertyType.String);
return extendedPropertyDefinition;
}
Item boundItem = Item.bind(this.exchangeService, appointmentId, getPropertySetKnown());
jiraCateringId = boundItem.getExtendedProperties().getItems().stream()
.filter(property -> property.getPropertyDefinition().getName().equals(CATERING_JIRA_ID)).findFirst()
.orElse(null);
Does anyone know in which DefaultExtendedPropertySet the Propertie could be found set by Office.js ?
Is there a way to get all Propertis using EWS with no need to define an own Definition?
Is there any Debug Tool in Outlook / Exchange to see the Customproperties in an Item?
As mentioned by #Glen Scales this should answer your question.
Also you can refer the doc Working with extended properties for more details on accessing extended properties from EWS.

Office.Interop how to find email using PR_SEARCH_KEY in sent Folder

I am using Outlook Object model (Interop) for my softawre.
Before I send email, I get and keep the PR_SEARCH_KEY of the email that we created.
If I want to find the email in sent folder using PR_SEARCH_KEY, how can I do that in c# using Office.Interop (not EWS or not redemption)?
I tried to find it from SentFolder.Items.Find(filter). But it does not work as the PR_SEARCH_KEY is binary.
Thanks !
public Outlook.MailItem FindEmailFromSentFolder(string emailId)
{
try
{
if (_sentFolderItems == null)
return null;
// find the sent mail from sent folder based on PR_Serach_Key
var filter = string.Format("#SQL=\"http://schemas.microsoft.com/mapi/proptag/0x300B0102\" = '{0}'",
emailId);
var item = _sentFolderItems.Find(filter);
if (item != null && item is Outlook.MailItem)
return item as Outlook.MailItem;
}
catch (Exception ex)
{
return null;
}
return null;
}
As you already noticed, OOM won't let you search for any binary property - you will need Extended MAPI (C++ or Delphi) or Redemption (any language).
Your best bet is to set some string property on the outgoing message and then look for it in the Sent Items folder.

Create mail in Exchange Online inbox programatically

Have been facing an issue since days about EWS. So my scenario is;
I was to programmatically sync GMAIL and EXCHANGE ONLINE. So here is what I have done;
Connect to Gmail using Gmail API
Fetch mail from gmail get the email body, to, from, attachment and
all other thing
connect to Exchange online using EWS 2.0
Now the problem is here, how can I create an email in Inbox which looks like incoming mail from the sender;
Here is the code I have done;
_service = new ExchangeService(ExchangeVersion.Exchange2013);
_service.TraceEnabled = true;
_service.Credentials = new WebCredentials("admin#xyz.onmicrosoft.com", "password");
_service.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
_service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "xyz#xyz.onmicrosoft.com");
EmailMessage message = new EmailMessage(_service);
Random r = new Random();
message.Subject = "Email Message";
message.From = new EmailAddress("xyz#gmail.com");
message.Sender = new EmailAddress("xyz#gmail.com");
message.Body = new MessageBody(BodyType.HTML, "<HTML><body><h1>This is a voice mail.</h1></BODY></HTML>");
message.ToRecipients.Add(new EmailAddress(""));
message.Save(WellKnownFolderName.Inbox);
This way its creating an email in inbox but it shows as a draft mail. I dont want it, I want it to look as RECEIVED mail.
Am I doing anything wrong?
You need to set a couple of properties before saving the message.
// Set a delivery time
ExtendedPropertyDefinition PidTagMessageDeliveryTime =
new ExtendedPropertyDefinition(0x0E06, MapiPropertyType.SystemTime);
DateTime deliveryTime = DateTime.Now; // Or whatever deliver time you want
message.SetExtendedProperty(PidTagMessageDeliveryTime, deliveryTime);
// Indicate that this email is not a draft. Otherwise, the email will appear as a
// draft to clients.
ExtendedPropertyDefinition PR_MESSAGE_FLAGS_msgflag_read = new ExtendedPropertyDefinition(3591, MapiPropertyType.Integer);
message.SetExtendedProperty(PR_MESSAGE_FLAGS_msgflag_read, 1);
These properties aren't settable after the items is saved, so it's important to do it before the first Save call.

WCF Data Service - Add Object With Related Object

I have the following situation, I have a WCF Data Service with User objects and message objects and the message object has two relations to user, a sender and a receiver.
When I try to add a new Message object the related users are left null
Message message = new Message();
message.text = InputText; // string
message.Sender = Sender; // User object
message.Receiver = Receiver; // User object
context.AddToMessages(message);
context.BeginSaveChanges(new AsyncCallback((result) =>
{
// Some code
}));
Now the Sender and Receiver will be null. When I try to set a link before the BeginSaceChanges like this I get the error "InvalidOperationException: The context is not currently tracking the entity."
context.AddToMessages(message);
context.AddLink(message, "Sender", message.Sender);
context.AddLink(message, "Receiver", message.Receiver);
context.BeginSaveChanges(new AsyncCallback((result) =>
{
// Some code
}));
How do I make sure the relations are created properly?
Thanks to Pratik I found the solution. I had to use attach the already existing users Sender and Receiver to the context first because they weren't tracked (and added a if if they are on the second call). Then I add the message and use SetLink to set the link to both users (instead of AddLink)
if(context.GetEntityDescriptor(message.Sender) == null)
context.AttachTo("Users", message.Sender);
if (context.GetEntityDescriptor(message.Receiver) == null)
context.AttachTo("Users", message.Receiver);
context.AddToMessages(message);
context.SetLink(message, "Sender", message.Sender);
context.SetLink(message, "Receiver", message.Receiver);
context.BeginSaveChanges(new AsyncCallback((result) =>
{
// Some code
}));
I believe you need to use the DbSet.Attach method instead. I assume you use Entity Framework on the back end here.

Resources