Get Safe sender list in Outlook 2007 C# Add in

亡梦爱人 提交于 2019-12-11 02:27:54

问题


I have created an Outlook 2007 add-in in C#.NET 4.0.

I want to read the safe sender list in my C# code.

        if (oBoxItem is Outlook.MailItem)
        {
            Outlook.MailItem miEmail = (Outlook.MailItem)oBoxItem;
            OlDefaultFolders f = Outlook.OlDefaultFolders.olFolderContacts;

            if (miEmail != null)
            {
                string body = miEmail.Body;
                double score = spamFilterObject.CalculateSpamScore(body);

                if (score <= 0.9)
                {
                    miEmail.Move(mfJunkEmail);
                }
            }
        }

So, the above code moves all email to spam, even though they are present in the safe sender list. Thus I want to get the safe sender list so that I can avoid this spam checking.

Could anybody please help me on this?


回答1:


The Outlook object model doesn't expose these lists (for more or less obvious reasons). The safe sender list can be read straight from the registry at:

HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles\[PROFILE NAME]\0a0d020000000000c000000000000046\001f0418

This binary registry key contains double-byte characters, separated by a semicolon (;).

The MAPI property mapping onto this registry key is PR_SPAM_TRUSTED_SENDERS_W, documented here.




回答2:


Chavan, I assume since this hasn't been updated in over 4 years, you don't need any more information, but this question and the answer helped me find what I was looking for (it was very hard to find) and enabled me to write the code below that may help if you're still looking for an answer.

This code runs in LINQPad, so if you aren't a LINQPad user, remove the .Dump() methods and replace with Console.WriteLine or Debug.WriteLine.

Cheers!

const string valueNameBlocked = "001f0426";
const string valueNameSafe = "001f0418";

// Note: I'm using Office 2013 (15.0) and my profile name is "Outlook"
// You may need to replace the 15.0 or the "Outlook" at the end of your string as needed.
string keyPath = @"Software\Microsoft\Office\15.0\Outlook\Profiles\Outlook";

string subKey = null;
var emptyBytes = new byte[] { };
var semi = new[] { ';' };
string blocked = null, safe = null;

// I found that my subkey under the profile was not the same on different machines,
// so I wrote this block to look for it.
using (var key = Registry.CurrentUser.OpenSubKey(keyPath))
{
    var match =
        // Get the subkeys and all of their value names
        key.GetSubKeyNames().SelectMany(sk =>
        {
            using (var subkey = key.OpenSubKey(sk))
                return subkey.GetValueNames().Select(valueName => new { subkey = sk, valueName });
        })
        // But only the one that matches Blocked Senders
        .FirstOrDefault(sk => valueNameBlocked == sk.valueName);

    // If we got one, get the data from the values
    if (match != null)
    {
        // Simultaneously setting subKey string for later while opening the registry key
        using (var subkey = key.OpenSubKey(subKey = match.subkey))
        {
            blocked = Encoding.Unicode.GetString((byte[])subkey.GetValue(valueNameBlocked, emptyBytes));
            safe = Encoding.Unicode.GetString((byte[])subkey.GetValue(valueNameSafe, emptyBytes));
        }
    }
}

// Remove empty items and the null-terminator (sometimes there is one, but not always)
Func<string, List<string>> cleanList = s => s.Split(semi, StringSplitOptions.RemoveEmptyEntries).Where(e => e != "\0").ToList();

// Convert strings to lists (dictionaries might be preferred)
var blockedList = cleanList(blocked).Dump("Blocked Senders");
var safeList = cleanList(safe).Dump("Safe Senders");

byte[] bytes;

// To convert a modified list back to a string for saving:
blocked = string.Join(";", blockedList) + ";\0";
bytes = Encoding.Unicode.GetBytes(blocked);
// Write to the registry
using (var key = Registry.CurrentUser.OpenSubKey(keyPath + '\\' + subKey, true))
    key.SetValue(valueNameBlocked, bytes, RegistryValueKind.Binary);

// In LINQPad, this is what I used to view my binary data
string.Join("", bytes.Select(b => b.ToString("x2"))).Dump("Blocked Senders: binary data");
safe = string.Join(";", safeList) + ";\0"; bytes = Encoding.Unicode.GetBytes(safe);
string.Join("", bytes.Select(b => b.ToString("x2"))).Dump("Safe Senders: binary data");



回答3:


PST and IMAP4 (ost) stores keep the list in the profile section in the registry. Profile section guid is {00020D0A-0000-0000-C000-000000000046}. To access the data directly, you will need to know the Outlook version and the profile name.

Exchange store keeps this data as a part of the server side rule that processes incoming messages on the server side. You can see the rule data in OutlookSpy - go to the Inbox folder, "Associated Contents" tab, find the entry named (PR_RuleMsgName) == "Junk E-mail Rule", double click on it, take a look at the PR_EXTENDED_RULE_CONDITION property.

Outlook Object Model does not expose Junk mail settings. If using Redemption is an option, it exposes the RDOJunkEmailOptions.TrustedSenders collection (works both for the PST and Exchange stores):

set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
set Store = Session.Stores.DefaultStore
set TrustedSenders = Store.JunkEmailOptions.TrustedSenders
for each v in TrustedSenders
  debug.print v
next


来源:https://stackoverflow.com/questions/6250207/get-safe-sender-list-in-outlook-2007-c-sharp-add-in

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!