following this link - change outlook MailItem icon
I managed to change my inbox icons.
Here's what I did step by step.
1) Created a custom message class for new mail that arrives from the Internet
The class is IPM.Note.Internet
Outlook.NameSpace outlookNameSpace;
Outlook.MAPIFolder inbox;
Outlook.Items items;
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
outlookNameSpace = this.Application.GetNamespace("MAPI");
inbox = outlookNameSpace.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
items = inbox.Items;
items.ItemAdd += new Outlook.ItemsEvents_ItemAddEventHandler(items_ItemAdd);
}
void items_ItemAdd(object Item)
{
Outlook.MailItem mailitem = (Outlook.MailItem)Item;
String EmailHeader = mailitem.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x007D001E");
if (Item != null && EmailHeader.Contains("Look for a string in the headers here that we set for incomming mail") == true)
{
if (mailitem.MessageClass == "IPM.Note")
{
mailitem.MessageClass = "IPM.Note.Internet";
mailitem.Save();
}
}
}
2) Created a replacement Outlook Form Region matching the MessageClass. In this case I used IPM.Note.Internet
3) Assign the Icons in the Properties Pane of the Form Region Designer.
4) Debugged project and the next message that arrived from the internet was stamped with my custom icons after the message class was updated.
My issue now is that I can't preview or open the messages where I changed the message class. Similar to this post that's unanswered - Change Inbox-icons in Outlook at runtime
I think the issue is that my replacement Outlook Form Region is blank so the message is not able to be previewed.
If this is true than here's my question. What is the best way to export the standard IPM.Note message class template into visual Studio. I thing I need to overwrite my IPM.Note.Internet Outlook Form Region design.
There is an option when creating an Outlook Form Region-
To import an ".OFS" file. I was attempting to figure out how to export the file from the Outlook 2010 Client (Developer Tools) but I can't find a way to save the templates to that specific format. I can save to OFT (office template) but not .OFS
Thanks in advance for any help!
Rather then adding a form region and changing the message class I just ended up adding the PR_ICON_INDEX property and setting it's value. As outlined here in option #2 by Dmitry Link
There are many icons to choose from here. I couldn't locate a list with the integer values so I just entered random numbers for the PR_ICON_INDEX property in Outlook Spy changing the value till located the icon I wanted. There are many icons to choose from. Many from the 600-700 and 1000 and up range.
Here's the line I used to set the PR_ICON_INDEX property on the message-
mailitem.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x10800003", 4); // change the 4 to something like 600,601...etc to experiment
Related
I've a problem with my VSTO application for Outlook. I want to process the email body from a selected e-mail.
For selected e-mails out of the "default" list this code works fine:
Object selItem = Globals.ThisAddIn.Application.ActiveExplorer().Selection[1];
Outlook.MailItem mailItem = (Outlook.MailItem)selItem;
return mailItem.Body;
But if a user opens an email from the list with a double click, the email is displayed in a new window. If the addin is executed in this window (over the ribbon), the email from the list is still used (which is now in the background).
Is there a way to find out if the plugin was started in a separate window and then get the email body from it?
Regards,
Florian
Coincidentally, I just dealt with something similar to this. My situation isn't identical, but since I could easily piece together what it seems like you're looking for see below. I haven't tested this, and obviously you'll have to handle passing the correct reference to your Outlook Application, but since i had this immediately available I figured it would pass it along with the hope that you'll find it helpful.
private static void ribbonButton_Click(object sender, RibbonControlEventArgs e)
{
Outlook.Application application = new Outlook.Application();
Outlook.Inspector inspector = application.ActiveInspector();
if (application.ActiveExplorer().Selection[1] is Outlook.MailItem explorerMailItem)
{
// Write code to handle message if sourced from explorer (i.e., Reading Pane)
}
else if (inspector.CurrentItem is Outlook.MailItem inspectorMailItem)
{
// Write code to hanlde message if sourced from inspector
// (i.e., openened (double-clicked) message
}
}
When you double click on email item you open an inspector window and you can access it by using Application.ActiveInspector() method. The Inspector object has CurrentItem property which represents the opened item.
Also, you should avoid using multiple dots in expressions and properly release COM objects.
I have a task which i need to create a program that converts outlook email to pdf.
this is my code
Microsoft.Office.Interop.Outlook.Application app = new Microsoft.Office.Interop.Outlook.Application();
NameSpace outlookNs = app.GetNamespace("MAPI");
MAPIFolder rootFolder = outlookNs.Stores["Blah"].GetRootFolder();
List<MailItem> mailItems = new List<MailItem>();
Folders subFolders = rootFolder.Folders;
foreach (Folder folder in subFolders)
{
if (folder.Name == "Inbox")
{
Items items = folder.Items;
foreach (object item in items)
{
if (item is MailItem)
{
MailItem mailItem = item as MailItem;
string fileName = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "New folder", mailItem.EntryID + mailItem.SenderName.Replace("/", "") + ".msg");
mailItem.SaveAs(fileName, Microsoft.Office.Interop.Outlook.OlSaveAsType.olMSG);
}
}
}
}
the code is working but the outlook contains thousands of email. The outlook prompt a message every 10 minutes similar to the screenshot below
is there a way to avoid getting the message? Programatically or a setting will do?
Basically, it's not related to the programming instead of it's related the outlook security settings.
For every version of outlook you can find the settings for this pop-up just follow the instruction on this blog.
You can do a setting in your out look.
Mine is outlook 2013.
File->options : a window opens
In the window select Trust Center
You can see a button Trust center Settings
Options in window changes. Select Programmatic access
UnCheck the radio button Never warn me about suspicious activity (not recommended)
Through program, you can change below registry settings:
Go to "HKEY_CURRENT_USER\Software\Policies\Microsoft\Office\15.0\outlook\security"
Change below settings programatically:
PromptSimpleMAPISend -- 2
PromptSimpleMAPINameResolve -- 2
PromptSimpleMAPIOpenMessage -- 2
By default when outlook is installed, the above values comes with zero value. What I do in my program is, I turn them to "2" programatically just before sending the email and turn them back to zero later point of time.
Is there a way to persist user properties across to the appointment invitees/locations calendars?
I have created a form region for appointments, with some extra form fields on. Upon the appointment write event, I can save the form region data as user properties against the appointment. From the senders' point of view, these properties persist when the item is opened up, and can be updated etc.
However, any invitees on the appointment, or any meeting rooms/locations included can receive the appointment BUT the user properties don't seem to carry across with the item. Why is this, and can it be worked around?
The only one I could think of is to persist the user properties in a database also and load them upon item open with the FormRegion_Showing method. That's not ideal though as the whole point was to keep it all in outlook.
I'm using Outlook 2010 and Visual Studio 2015.
I came across this post which pretty much says it can't be done, however that is from 2011 and I can't find anything more recent that's relevant to this particular scenario.
Some cut down code - the Form Region:
// Form region class
[Microsoft.Office.Tools.Outlook.FormRegionMessageClass(Microsoft.Office.Tools.Outlook.FormRegionMessageClassAttribute.Appointment)]
[Microsoft.Office.Tools.Outlook.FormRegionName("Namespace.MyFormRegion")]
public partial class MyFormRegionFactory
{
}
private void MyFormRegion_FormRegionShowing(object sender, System.EventArgs e)
{
Outlook.AppointmentItem appointment = this.OutlookItem as Outlook.AppointmentItem;
this.appointment.Write += Appointment_Write;
}
private void Appointment_Write(ref bool Cancel)
{
Outlook.ItemProperties CateringData = this.appointment.ItemProperties;
var Serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
Outlook.ItemProperty MeetingNameProperty = CateringData.Add("MeetingName", Outlook.OlUserPropertyType.olText, true);
MeetingNameProperty.Value = this.MeetingName.Text;
// More properties saved
appointment.Save();
}
and in the addin class:
public partial class ThisAddIn
{
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
Application.ItemSend += Application_ItemSend;
}
private void Application_ItemSend(object Appointment, ref bool Cancel)
{
// Appointment is an AppointmentItem that has just been saved.
// How does this relate to the outgoing item that ends up in the
// Sent Items folder???
}
}
Using Outlook Spy the user properties are not in the item within the Sent Items. The form region does appear when opening the item from one of the invitees calendars, but the user properties are not there.
So, after lots of head scratching and modifications, and after using Outlook Spy with the help of Dmitry (http://www.dimastr.com/outspy/home.htm) to inspect User Properties I realised that I had been trying to set a property name that happened to be in use already by Outlook internally (MeetingType)
After changing the name of that property, all the other user properties now persist in both the sent items and invitees' calendars.
For anyone else coming across this same issue where properties don't persist, check your property names with those set in Outlook already, could save you hours of headache!
I am having difficulties with Interop in a WPF application.
What I actually want to do is drag and drop an Outlook file into my application and extract the attachments and store them. Apart from that I want to read the subject and search for a 4-digit-number which will then be the name of the folder the attachments are to be stored to.
I have been searching the web for solutions that don't use Interop, but I wasn't able to find anything that worked for me.
So I thought 'let's give it a shot' and it sounded pretty simple, because I found so many examples that followed this pattern:
if (e.Data.GetDataPresent("FileGroupDescriptor"))
{
Microsoft.Office.Interop.Outlook.Application app = new Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook.Selection selection = app.ActiveExplorer().Selection;
foreach (object mi in selection)
{
Microsoft.Office.Interop.Outlook.MailItem mailItem = (Microsoft.Office.Interop.Outlook.MailItem)mi;
string subject = "Untitled";
if (!string.IsNullOrEmpty(mailItem.Subject))
{
subject = mailItem.Subject;
MessageBox.Show(subject);
}
}
}
This works, but I have one problem: the selection keeps on growing. I tried the methods RemoveFromSelection and ClearSelection, but they don't work. Everytime I drag a new Outlook item to the surface it keeps displaying all the previous items as well.
Can anybody help me? I'm at a complete loss
Do you handle the Drag event in your application?
If so, try to call the following code in the event handler:
e.Data.GetData(“RenPrivateMessages”);
See Outlook, custom task pane and drag-drop problem for more information.
I'm working on an Outlook Add-In that can work in one of two ways, depending on a user's choice - it can process selected emails, or alternatively, process all emails in the selected folder. I've gotten the first part working, but the second part is giving me trouble, possibly because I'm just adapting the code from the first part incorrectly. I believe the trouble comes down to grabbing the currently selected folder properly in a C# Outlook add-in. I'm using .NET 3.5 and Outlook 2007, by the way.
First, the email code - if a user selects one or more emails in their inbox, and runs my add-in with the "selected emails" option, the following code is run (and works fine!):
public static void processSelectedEmails(Outlook.Explorer explorer)
{
//Run through every selected email
for (int i = 1; i <= explorer.Selection.Count; i++)
//alternatively, foreach (Object selectedObject in explorer.Selection)
{
Object selectedObject = explorer.Selection[i];
if (!(selectedObject is Outlook.Folder))
{
string errorMessage = "At least one of the items you have selected is not an email.";
//Code for displaying the error
return;
}
else
Outlook.MailItem email = (selectedObject as Outlook.MailItem);
//Do something with current email
}
}
I've tried to adapt this code to do something else if a user goes to the Navigation Pane (on the left by default) in Outlook, selects a folder or subfolder (perhaps Inbox, Sent Items, or another folder they've created). The user can then choose the "process selected folder" option in my Add-In, which will do essentially the same thing as the code above, but process all of the email inside the selected folder. I have set it to only work if the user has selected a single folder.
public static void processFolder(Outlook.Explorer explorer)
{
//Assuming they have selected only one item
if (explorer.Selection.Count == 1)
{
//Make sure that that selected item is a folder
Object selectedObject = explorer.Selection[1];
if (!(selectedObject is Outlook.Folder))
{
string errorMessage = "The item you have selected is not a folder.";
//Code for displaying the error
return;
}
//Code for running through every email in that folder
}
}
I have not yet written the code to actually run through all of the emails in the selected folder, because my code never gets past the if (!(selectedObject is Outlook.Folder)). Even if the most recently selected item is your Inbox, I receive the error I have programmed in at that point. Perhaps I am misusing the explorer.Selection thing? Any help would be much appreciated.
This may be important to answering my question - the add-in has a field called 'explorer', which is generated on startup: explorer = this.Application.ActiveExplorer. This is the 'explorer' that is passed to my functions so that they can know what is selected. As I said, this works fine for selected emails, but does not work for selected folders. Any insight would be greatly appreciated!
Edit 1: It appears that this question is basically a duplicate of Get all mails in outlook from a specific folder, but it has no answers.
Edit 2: I've been doing further research, it appears that I can get virtually the same functionality (but with an additional step unfortunately) by creating a popup to select a folder using the Application.Session.PickFolder() method. Is there any way to do it based on the currently selected folder, instead of forcing the user to pick a new folder?
Edit 3: I have modified the code found here: http://msdn.microsoft.com/en-us/library/ms268994(v=vs.80).aspx to further show what is not working properly for me:
public static void processFolder(Outlook.Explorer explorer)
{
string message;
if (explorer.Selection.Count > 0)
{
Object selObject = explorer.Selection[1];
if (selObject is Outlook.MailItem)
{
message = "The item is an e-mail";
}
else if (selObject is Outlook.Folder)
{
message = "The item is a folder";
}
else
{
message = "No idea what the item is!";
}
Console.WriteLine(Message);
return;
}
}
Whether I select a message, or go to the Navigation Pane and select a folder, I receive the message "This item is an e-mail".
Explorer.Selection is for Items only (MailItem, AppointmentItem, etc.) - not Folders. To get access to the currently selected Folder you would need Explorer.CurrentFolder.
Folder.Items would provide you access to all the Items in a given Folder.