When I iterate through all Outlook folders (in a C# Add-In) I see folder names like:
Yammer Root
Sync Issues
Subscriptions
These folders are not visible in Outlook. I like to check in my code if the folder is visible or not but I don't find a property like Hidden or Visible.
MAPIFolder folder has properties like:
folder.DefaultItemType
folder.Name
but not hidden.
How can I find out in my c# Add-In if folders are hidden or not?
You will need to read the PR_ATTR_HIDDEN MAPI property (DASL name http://schemas.microsoft.com/mapi/proptag/0x10F4000B). You can read it using MAPIFolder.PropertyAccessor.GetProperty.
You can see that (and other) property using OutlookSpy (I am its author) - click IMAPIFolder button.
At least on my machine I never retrieved a value for PR_ATTR_HIDDEN for all folders. I could not find out the reason although in OutlookSpy the value is true for the hidden folders.
Code:
var rootFolder = outlook.Session.DefaultStore.GetRootFolder();
foreach (Folder folder in rootFolder.Folders)
{
try
{
bool isHidden = folder.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x10F4000B");
// never reach this line
}
catch (System.Exception ex)
{
// always exception: value is not available
}
}
My workaround: If you want to retrieve the folders as they are displayed in Outlook you can use PR_CONTAINER_CLASS_W and compare it with IPF.Note or IPF.Imap.
Sample:
const string PR_CONTAINER_CLASS_W = "http://schemas.microsoft.com/mapi/proptag/0x3613001F";
string containerClass = folder.PropertyAccessor.GetProperty(PR_CONTAINER_CLASS_W);
bool isVisible = string.Equals(containerClass, "IPF.Note")|| string.Equals(containerClass, "IPF.Imap");
Related
I am creating a IPM.Document item using c# code. my sample code is below.
objDocItem = objFolder.Items.Add("IPM.Document");
objDocItem.Subject = "FileName.txt";
objDocItem.Save();
I want to change my custom icon in above display item.
Thanks.
The icon is determined by the message class, which in turn is determined by the extension. E.g. for a .txt file, the extension (txt) is used to read the default value from the HKCR\.txt registry key. That default value is "txtfile", which means the message class will be IPM.Document.txtfile. You must remember to add the attachment as well. Take a look at existing document items with OutlookSpy (click IMessage button).
If using Redemption is an option, it exposes the RDODocumentItem object, which sets the message class as well as other available properties (such as Author, etc. from the old IStorage based Office files such as .doc, .xls, etc.) in a single call:
set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
set Folder = Session.GetDefaultFolder(olFolderDrafts)
set Msg = Folder.Items.Add("IPM.Document")
Msg.SetDocument("c:\Temp\test.txt")
Msg.Save
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.
Someone knows how can we programmatically create a Root Folder in the calendar section of Outlook 2010/2013. I only can create a subfolder in my personnal calendar root folder but can't create an another root folder.
private void EnsureRootFolderExists()
{
bool create = false;
Folder rootStoreFolder = _app.Session.DefaultStore.GetRootFolder() as Folder;
try {
_rootFolder = rootStoreFolder.Folders["Owncloud"] as Folder;
}
catch {
create = true;
}
if (create) {
_rootFolder = rootStoreFolder.Folders.Add("Owncloud") as Folder;
}
else {
_rootFolder = rootStoreFolder.Folders["Owncloud"] as Folder;
}
}
I tried this too but it create a folder in the inbox section. Not really what i search for ...
Try to specify the type of folder.
The first parameter of the Add function accepts a string which contains the display name of the new folder. The second parameter accepts the OlDefaultFolders enumeration that indicates the type of folder you want to create. If the new folder type is not specified, it will default to the type of the folder in which it is created. The following values are possible for the second parameter: olFolderCalendar, olFolderContacts, olFolderDrafts, olFolderInbox, olFolderJournal, olFolderNotes and olFolderTasks.
I agree with you. But if i do like this it will create a subfolder in the olFolderCalendar which is the default calendar folder. I would like to be able to create an another root folder in the Calendar section. It's possible to do it trough the interface (right click : New calendar group). This what il would like to achieve but programmatically.
I am programmatically creating a search folder via Search.Save method. After I save the search (it creates a new folder in the Search Folders directory), I would like to set to focus on this newly created folder such that the view changes to this folder.
This is the code I have thus far....
searchFolders = inboxFolder.Store.GetSearchFolders();
foreach (Outlook.Folder folder in searchFolders)
{
if (folder.Name == "Expiring Retention Policy Mail")
{
folder.ShowItemCount = Microsoft.Office.Interop.Outlook.OlShowItemCount.olShowTotalItemCount;
//folder.SetCustomIcon(new Bitmap(32, 32));
folder.Display();
}
}
When I do folder.Display() it opens up an entirely new inspector window... I don't want this to happen, I simply want to select it (like via set focus?) and have it viewed in the same inspector window it exists in. Does anybody know how to do this?
Thank you.
This should work for you...
Get access to your Application object (or from the main add-in class). And then
this.Application.ActiveExplorer().CurrentFolder = folder;
i.e. you can use CurrentFolder of the ActiveExplorer
Of course, always make sure to properly release your COM objects (the ones that need releasing) - and
you should never do it like I did here (for simplicity) - i.e. chaining properties like
that. Save each (property) into a variable, and release via
Marshal.ReleaseComObject on your way out.
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.