来自兑换的 MAPI_E_FAILONEPROVIDER

发布于 2024-09-07 16:17:39 字数 1047 浏览 10 评论 0原文

我正在尝试使用“兑换”来更新用户的 Outlook 联系人。我正在影响的用户在exchangeUser中传递,称他为“目标用户”。 当我以我自己的身份登录运行该代码时,该代码有效:

public OutlookFolders(string outlookRootFolder, string exchangeUser, string mailServer)
{
    var session = new RDOSessionClass();
    session.LogonExchangeMailbox(exchangeUser, mailServer);
    session.Stores.FindExchangePublicFoldersStore();
    var store = session.GetSharedMailbox(exchangeUser);
    //...
}

我尝试以第三个用户“测试用户”身份登录,该用户不是我,也不是“目标用户”。我的程序在运行时到达 FindExchangePublicFoldersStore 时会出现密码提示,如果我不填写我的凭据,则会失败并显示错误:

System.Runtime.InteropServices.COMException (0x8004011D): Error in 
    IMAPISession.OpenMsgStore(pbExchangeProviderPrimaryUserGuid):
    MAPI_E_FAILONEPROVIDER
ulVersion: 0
Error: Microsoft Exchange is not available.  Either there are network
    problems or the Exchange computer is down for maintenance.
Component: Microsoft Exchange Information Store
ulLowLevelError: 2147746069
ulContext: 1318

我尝试授予“目标用户”邮箱和联系人文件夹的“测试用户”所有者权限。似乎没有什么区别。还需要设置哪些其他权限才能正常工作?

I'm trying to user Redemption to update a user's Outlook contacts. The user I'm affecting is passed in the exchangeUser, call him "Target User".
This code works when I run it logged in as myself:

public OutlookFolders(string outlookRootFolder, string exchangeUser, string mailServer)
{
    var session = new RDOSessionClass();
    session.LogonExchangeMailbox(exchangeUser, mailServer);
    session.Stores.FindExchangePublicFoldersStore();
    var store = session.GetSharedMailbox(exchangeUser);
    //...
}

I tried to log in as a 3rd user "Test User" who is not me and is not "Target User". My program brings up a password prompt at runtime when it gets to FindExchangePublicFoldersStore, and if I don't fill in my credentials it fails with the error:

System.Runtime.InteropServices.COMException (0x8004011D): Error in 
    IMAPISession.OpenMsgStore(pbExchangeProviderPrimaryUserGuid):
    MAPI_E_FAILONEPROVIDER
ulVersion: 0
Error: Microsoft Exchange is not available.  Either there are network
    problems or the Exchange computer is down for maintenance.
Component: Microsoft Exchange Information Store
ulLowLevelError: 2147746069
ulContext: 1318

I tried giving "Test User" owner permission on "Target User's" Mailbox and Contacts folder. Doesn't seem to make a difference. What other permissions need to be set for this to work?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

稚气少女 2024-09-14 16:17:39

经验法则是,以可以访问相关邮箱的用户身份运行代码,为当前用户调用 LogonExchangeMailbox,然后使用 GetSharedMailbox 打开其他用户的邮箱。

The rule of thumb is to run your code as a user who can access the mailboxes in question, call LogonExchangeMailbox for the current user, then open other users' mailboxes using GetSharedMailbox.

倒带 2024-09-14 16:17:39

这是德米特里答案的代码。
它还使用 Milan 博客 中的函数。

        public OutlookFolders(string exchangeUser, string mailServer)
        {
            var session = new RDOSessionClass();
            var userFullName = GetFullName("DOMAIN-NT\\" + Environment.UserName);
            session.LogonExchangeMailbox(userFullName, mailServer);
            session.Stores.FindExchangePublicFoldersStore();
            var store = session.GetSharedMailbox(exchangeUser);
            rootFolder = store.GetDefaultFolder((rdoDefaultFolders)OlDefaultFolders.olFolderContacts);
        }

        public static string GetFullName(string strLogin)
        {
            string str = "";
            string strDomain;
            string strName;

            // Parse the string to check if domain name is present.
            int idx = strLogin.IndexOf('\\');
            if (idx == -1)
            {
                idx = strLogin.IndexOf('@');
            }

            if (idx != -1)
            {
                strDomain = strLogin.Substring(0, idx);
                strName = strLogin.Substring(idx + 1);
            }
            else
            {
                strDomain = Environment.MachineName;
                strName = strLogin;
            }

            DirectoryEntry obDirEntry = null;
            try
            {
                obDirEntry = new DirectoryEntry("WinNT://" + strDomain + "/" + strName);
                PropertyCollection coll = obDirEntry.Properties;
                object obVal = coll["FullName"].Value;
                str = obVal.ToString();
            }
            catch (System.Exception ex)
            {
                str = ex.Message;
            }
            return str;
        }

Here's the code for Dmitry's answer.
It also uses a function from Milan's blog.

        public OutlookFolders(string exchangeUser, string mailServer)
        {
            var session = new RDOSessionClass();
            var userFullName = GetFullName("DOMAIN-NT\\" + Environment.UserName);
            session.LogonExchangeMailbox(userFullName, mailServer);
            session.Stores.FindExchangePublicFoldersStore();
            var store = session.GetSharedMailbox(exchangeUser);
            rootFolder = store.GetDefaultFolder((rdoDefaultFolders)OlDefaultFolders.olFolderContacts);
        }

        public static string GetFullName(string strLogin)
        {
            string str = "";
            string strDomain;
            string strName;

            // Parse the string to check if domain name is present.
            int idx = strLogin.IndexOf('\\');
            if (idx == -1)
            {
                idx = strLogin.IndexOf('@');
            }

            if (idx != -1)
            {
                strDomain = strLogin.Substring(0, idx);
                strName = strLogin.Substring(idx + 1);
            }
            else
            {
                strDomain = Environment.MachineName;
                strName = strLogin;
            }

            DirectoryEntry obDirEntry = null;
            try
            {
                obDirEntry = new DirectoryEntry("WinNT://" + strDomain + "/" + strName);
                PropertyCollection coll = obDirEntry.Properties;
                object obVal = coll["FullName"].Value;
                str = obVal.ToString();
            }
            catch (System.Exception ex)
            {
                str = ex.Message;
            }
            return str;
        }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文