簡體   English   中英

將Outlook聯系人導出到CSV時,“ RPC服務器不可用”

[英]“RPC Server is unavailable” when exporting Outlook contacts to CSV

我正在將具有自定義表單的Outlook聯系人從特定的Contacts文件夾導出為CSV。 此文件夾不是默認位置。 這是一個包含近7,000個聯系人的大文件夾。 這是Office 365中的共享郵箱,但是由於自定義數據,我們無法使用Outlook或Graph API。

我的下面的代碼工作正常,除了在遍歷200-800個聯系人之后,我收到此錯誤:“ RPC服務器不可用。(HRESULT的異常:0x800706BA)。”

我還嘗試將文件夾導出到.pst並訪問本地計算機上的該文件夾。 結果基本相同。 更新:我一直在任務管理器中觀看Outlook.exe,它在崩潰前穩定地將其內存消耗增加到300MB左右。 我在運行Office 2010的筆記本電腦上嘗試了相同的代碼,但出現“內存不足”錯誤。

無論Outlook是打開還是關閉,我都會收到錯誤消息,但是在程序運行過程中關閉Outlook會立即觸發此錯誤。 Outlook會在出現此錯誤后啟動(或重新啟動)。 我已經閱讀了許多與該錯誤有關的SO帖子和文章,但是我不確定到底是怎么回事。 任何幫助表示贊賞。

更新:根據Dmitry Streblechenko的建議,代碼已更新為for循環,而不是foreach循環。

using System;
using Microsoft.Office.Interop.Outlook;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;

namespace OutlookContacts
{
    class Program
    {
        static void Main(string[] args)
        {
            var encoding = Encoding.UTF8;
            string csvPath = @"myCSVPath";
            Application outlook = new Application();
            NameSpace ns = outlook.GetNamespace("MAPI");
            MAPIFolder sharedContacts;
            string recipientName = "myEmail@myDomain";
            StringBuilder headerRow = new StringBuilder();
            Recipient recip = ns.CreateRecipient(recipientName);
            StreamWriter writer = new StreamWriter(csvPath, false, encoding);

            recip.Resolve();
            if (recip.Resolved)
            {
                try
                {
                    //EntryID and StoreID of my folder
                    sharedContacts =
                        ns.GetFolderFromID(
                            "myEntryID",
                            "myStoreID"
                            );
                    Items contacts = sharedContacts.Items;

                    //Writing header row
                    ContactItem first = contacts.GetFirst();
                    var properties = first.ItemProperties;
                    for(int i = 0; i < properties.Count; i++)
                    {
                        try
                        {
                            headerRow.Append(string.Format("\"{0}\",", properties[i].Name));
                        }
                        catch (System.Exception ex)
                        {
                            headerRow.Append(string.Format("{0},", ex.Message));
                        }
                    }
                    headerRow.AppendLine(Environment.NewLine);
                    WriteToCSV(writer, headerRow);
                    Console.WriteLine("Header row written;");
                    Marshal.ReleaseComObject(properties);
                    Marshal.ReleaseComObject(first);

                    //Writing Records
                    for (int i = 1; i <= contacts.Count; i++)
                    {
                        object o = contacts[i];
                        if (o is ContactItem)
                        {
                            ContactItem contact = (ContactItem)o;
                            if (contact != null)
                            {
                                Console.Write(contact.FullName);
                                StringBuilder dataRow = new StringBuilder();
                                ItemProperties contactProps = contact.ItemProperties;
                                for (int j = 0; j < contactProps.Count; j++)
                                {
                                    ItemProperty property = contactProps[j];

                                    try
                                    {
                                        if (property.Value == null)
                                        {
                                            string value = "null,";
                                            dataRow.Append(value);
                                        }
                                        //else if (property.Name == "Attachments")
                                        //{
                                        //    //Attachment file names
                                        //    string attachment = "";
                                        //    for (int k = 1; k < contact.Attachments.Count; k++)  
                                        //    {
                                        //            attachment = (string.Format("\"{0}\"; ", contact.Attachments[k].FileName));
                                        //            dataRow.Append(attachment);
                                        //    }
                                        //    dataRow.Append(",");
                                        //}
                                        else
                                        {
                                            string value = property.Value.ToString();
                                            value = value.Replace("\r\n\r\n\r\n", "\r\n")
                                                .Replace("\r\n\r\n", "\r\n")
                                                .Replace("\"", "'");
                                            value = (string.Format("\"{0}\",", value));
                                            dataRow.Append(value);
                                        }
                                    }
                                    catch (System.Exception ex)
                                    {
                                        string value = string.Format("{0}: {1},", property.Name, ex.Message);
                                        dataRow.Append(value);
                                    }

                                    Marshal.ReleaseComObject(property);
                                }
                                dataRow.Append(Environment.NewLine);
                                WriteToCSV(writer, dataRow);
                                Marshal.ReleaseComObject(contactProps);
                                Marshal.ReleaseComObject(contact);
                            }
                            Marshal.ReleaseComObject(o);
                            counter++;
                            Console.WriteLine(": Written " + counter);
                        }
                    }
                }
                catch (System.Exception ex)
                {
                    Console.WriteLine(dataRow.ToString(), ex.Message);
                    Console.ReadKey();
                }

            }

        }

        static void WriteToCSV(StreamWriter writer, StringBuilder row)
        {
            var data = row.ToString();
            writer.WriteAsync(data);
        }

    }
}

看起來您用完了RPC通道。 您需要避免使用foreach循環(它們傾向於保持引用所有集合成員,直到循環退出),並在完成處理后立即顯式釋放所有COM對象。

從我的頭頂上:

for(int i = 1; i <= contacts.Count; i++)
{
    obejct o = contacts[i];
    ContactItem contact = o as ContactItem;
    if (o != null)
    {
        ItemProperties properties = contact.ItemProperties;
        StringBuilder newLine = new StringBuilder();
        for (int j = 1; j <= properties.Count; j++)
        {
            ItemProperty property = properties[j];
            var value = "";
            if (property.Value == null)
            {
                value = "null,";
                Console.WriteLine(value);
                newLine.Append(value);
            }
            else
            {
                value =  property.Value.ToString() + ",";
                newLine.Append(value);
            }
            Marshal.ReleaseComObject(property);
        }
        newLine.Append(Environment.NewLine);
        WriteToCSV(writer, newLine);
        Marshal.ReleaseComObject(properties);
        Marshal.ReleaseComObject(contact);
    }
    Marshal.ReleaseComObject(o);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM