2008-11-25 36 views
30

Tôi đang làm việc trên máy khách Windows được viết bằng WPF với C# trên .Net 3.5 Sp1, trong đó yêu cầu là dữ liệu từ email mà khách hàng nhận được có thể được lưu trữ trong cơ sở dữ liệu. Ngay bây giờ, cách dễ nhất để xử lý việc này là sao chép và dán văn bản, chủ đề, thông tin liên hệ và thời gian nhận được theo cách thủ công bằng cách sử dụng số tiền viêm khớp ctrl-c/ctrl-v.Kéo và thả một hoặc nhiều thư từ Outlook sang ứng dụng C# WPF

Tôi nghĩ rằng cách đơn giản để xử lý việc này là cho phép người dùng kéo một hoặc nhiều email từ Outlook (tất cả chúng đều đang sử dụng Outlook 2007) vào cửa sổ, cho phép ứng dụng của tôi trích xuất thông tin cần thiết và gửi nó vào hệ thống phụ trợ để lưu trữ.

Tuy nhiên, một vài giờ googling cho thông tin về điều này dường như chỉ ra một thiếu gây sốc của thông tin về nhiệm vụ này dường như cơ bản. Tôi sẽ nghĩ rằng một cái gì đó như thế này sẽ hữu ích trong rất nhiều thiết lập khác nhau, nhưng tất cả những gì tôi có thể tìm thấy cho đến nay đã là những giải pháp không nướng một nửa.

Có ai có lời khuyên nào về cách thực hiện việc này không? Vì tôi chỉ đọc thư và không gửi bất cứ điều gì hoặc làm bất cứ điều gì xấu xa, nó sẽ là tốt đẹp với một giải pháp mà không liên quan đến các cửa sổ pop up an ninh, nhưng bất cứ điều gì nhịp đập không thể làm điều đó cả.

Về cơ bản, nếu tôi có thể nhận danh sách tất cả các mục thư đã được chọn, kéo và thả từ Outlook, tôi sẽ có thể tự xử lý phần còn lại!

Cảm ơn!

Rune

+0

Rune bạn vẫn đang tìm kiếm câu trả lời cho điều này? – cgreeno

+0

Xin chào Chris - vâng, tôi đã tham gia một dự án hoàn toàn khác cho tháng trước. Tôi sẽ cố gắng theo dõi ngay sau khi tôi có đầu trên mặt nước. –

+0

Bạn không nên liên kết với máy chủ Exchange của mình và truy cập hộp thư Outlook theo cách đó? Tại sao không nhìn vào các đối tượng CDO? Điều này cho phép bạn nhận các bộ sưu tập tin nhắn từ máy chủ Exchange. http://msdn.microsoft.com/en-us/library/ms978698.aspx – D3vtr0n

Trả lời

32

Tôi đã tìm thấy một số lớn article cần thực hiện chính xác những gì bạn cần.

CẬP NHẬT

tôi đã có thể lấy mã trong bài viết đó làm việc trong WPF với một chút tinh chỉnh, dưới đây là những thay đổi mà bạn cần phải thực hiện.

Thay đổi tất cả các tài liệu tham khảo từ System.Windows.Forms.IDataObject để System.Windows.IDataObject

Trong constructor OutlookDataObject, thay đổi

FieldInfo innerDataField = this.underlyingDataObject.GetType().GetField("innerData", BindingFlags.NonPublic | BindingFlags.Instance); 

Để

FieldInfo innerDataField = this.underlyingDataObject.GetType().GetField("_innerData", BindingFlags.NonPublic | BindingFlags.Instance); 

Thay đổi tất cả DataFormats. GetFormat gọi tới DataFormats.GetDataFormat

Thay đổi việc thực hiện SetData từ

public void SetData(string format, bool autoConvert, object data) 
{ 
    this.underlyingDataObject.SetData(format, autoConvert, data); 
} 

ĐẾN

public void SetData(string format, object data, bool autoConvert) 
{ 
    this.underlyingDataObject.SetData(format, data, autoConvert); 
} 

Với những thay đổi đó, tôi đã có thể có được nó để lưu các thông điệp đến các tập tin như bài báo đã làm. Xin lỗi vì định dạng, nhưng danh sách đánh số/dấu đầu dòng không hoạt động tốt với đoạn mã.

+1

Cảm ơn - Tôi cũng đã tìm thấy cái này và cố gắng sử dụng nó, tuy nhiên tôi đang đập đầu vào sự khác biệt giữa System.Windows.Forms.IDataObject (cái được sử dụng trong Windows Forms và bài viết này) và System.Windows.IDataObject (cái mà WPF sử dụng). Tôi không biết gần như đủ COM (hoặc bất cứ điều gì đáng sợ tìm kiếm công cụ là) để có được điều này để làm việc, nó sẽ có vẻ ..! –

+0

Tôi đã cập nhật bài đăng của mình để phản ánh những thay đổi cần thiết để làm việc trong WPF. –

+1

Cảm ơn một lần nữa - Tôi khá gần với điều này làm việc cho tôi, chỉ cần phải đối phó với một số trường hợp ngoại lệ khi kéo nhiều tin nhắn. Chúc mừng bạn đã tìm ra một điều khó khăn. :) –

3

Trong XAML của bạn, bạn cần phải thiết lập cho sự kiện của bạn:

<TextBlock 
     Name="myTextBlock" 
     Text="Drag something into here" 
     AllowDrop="True" 
     DragDrop.Drop="myTextBlock_Drop" 
     /> 

Một khi bạn đã thiết lập AllowDrop = True và Thiết bạn thả sự kiện sau đó đi đến đoạn code sau và thiết lập sự kiện của bạn:

private void myTextBlock_Drop(object sender, DragEventArgs e) 
{ 
     // Mark the event as handled, so TextBox's native Drop handler is not called. 
     e.Handled = true; 
     Stream sr; 

      //Explorer 
      if (e.Data.GetDataPresent(DataFormats.FileDrop, true)) 
       //Do somthing 

     //Email Message Subject 
     if (e.Data.GetDataPresent("FileGroupDescriptor")) 
     { 
      sr = e.Data.GetData("FileGroupDescriptor") as Stream; 
       StreamReader sr = new StreamReader(sr2);//new StreamReader(strPath, Encoding.Default); 
      //Message Subject 
        string strFullString = sr.ReadToEnd(); 
     } 


} 

Nếu bạn muốn phá vỡ nó xuống thấp hơn nữa, bạn có thể sử dụng: đặc tả tập tin hoặc FILECONTENTS như phác thảo trong sau article

ot của bạn lựa chọn của cô ấy là gắn vào triển vọng MS Office Primary Interop Assemblies và chia nhỏ thông điệp theo cách đó.

+0

FileGroupDescriptor không chứa văn bản, chỉ dữ liệu nhị phân. Kết quả strFullString không có gì có thể đọc được –

+0

Tôi đã kiểm tra mã trước khi tôi đăng nó, có lẽ bạn cần phải thay đổi Mã hóa? – cgreeno

+1

cgreeno - Tôi quên bình luận rằng tôi đã thử điều này, nhưng tất cả những gì tôi nhận được là một loạt các số không và một nơi nào đó ở giữa, chủ đề của thông điệp. I E.nếu tôi kéo một thông điệp với chủ đề "Địa chỉ", tôi nhận được thông báo này: \ 0 \ 0 \ 0 [v.v., rất nhiều người trong số họ] Adresse.msg \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 [nhiều hơn nữa của họ]. Nếu tôi xóa các ký tự \ 0 tôi có thể nhận được ở chủ đề, nhưng không có dấu hiệu của nơi tôi có thể tìm thấy nội dung thư, bất kỳ tệp đính kèm, người gửi hoặc thông tin nào khác cần thiết. Cảm ơn bạn đã cố gắng tho, được nhiều người đánh giá cao. :) –

5

Tôi tìm thấy rất nhiều giải pháp cho thấy bạn sử dụng “FileGroupDescriptor” cho tất cả tên tệp và “FileContents” trên đối tượng DragEventArgs để truy xuất dữ liệu của từng tệp. "FileGroupDescriptor" hoạt động tốt cho tên tin nhắn email, nhưng "FileContents" trả về một null vì việc thực hiện IDataObject trong .Net không thể xử lý đối tượng IStorage được trả về bởi COM.

David Ewen có một lời giải thích tuyệt vời, mẫu tuyệt vời và tải xuống mã hoạt động tốt tại http://www.codeproject.com/KB/office/outlook_drag_drop_in_cs.aspx.

+0

Cảm ơn, điều này có vẻ rất hứa hẹn - tuy nhiên, nó được dựa trên một WinForms (?) IDataObject, trong khi IDataObject được sử dụng trong WPF là hơi khác nhau. Đối với điều này để làm việc, tôi sẽ cần một cách "lossless" để chuyển đổi giữa hai, hoặc ...? –

+0

Liên kết bị hỏng ... –

1

Tôi giả định rằng bạn có máy chủ Exchange chạy phía sau Outlook.

Điều bạn có thể làm là truy xuất thư từ máy chủ Exchange và lưu trữ vị trí của thư trong cơ sở dữ liệu của bạn dựa trên thư của EntryIDStoreID. Dưới đây là một đoạn VB.Net:

Imports Microsoft.Office.Interop 

Public Class OutlookClientHandler 

Private _application As Outlook.Application 
Private _namespace As Outlook.NameSpace 

Public Sub New() 
    If Process.GetProcessesByName("outlook".ToLower).Length > 0 Then 
     _application = New Outlook.Application 
    Else 
     Dim startInfo As ProcessStartInfo = New ProcessStartInfo("outlook.exe") 
     startInfo.WindowStyle = ProcessWindowStyle.Minimized 
     Process.Start(startInfo) 

     _application = New Outlook.Application 
    End If 
End Sub 

' Retrieves the specified e-mail from Outlook/Exchange via the MAPI 
Public Function GetMailItem(ByVal entryID as String, ByVal storeID as String) As Outlook.MailItem 
    _namespace = _application.GetNamespace("MAPI") 
    Dim item As Outlook.MailItem 
    Try 
     item = _namespace.GetItemFromID(entryID, storeID) 
    Catch comex As COMException 
     item = Nothing ' Fugly, e-mail wasn't found! 
    End Try 

    Return item 
End Function 
End Class 

Tôi đoán bạn cảm thấy thoải mái với việc sử dụng MAPI, nếu không bạn có thể đọc ở đây: http://msdn.microsoft.com/en-us/library/cc765775(v=office.12).aspx

Để lấy lại e-mail được lựa chọn từ triển vọng:

Public Function GetSelectedItems() As List(Of Object) 
    Dim items As List(Of Object) = New List(Of Object) 

    For Each item As Object In _application.ActiveExplorer().Selection 
     items.Add(item) 
    Next 

    Return items 
End Function 

Sau khi bạn đã truy xuất e-mail từ Outlook, bạn chỉ có thể đẩy chúng vào cơ sở dữ liệu của bạn! Lưu EntryIDStoreID (bạn có thể muốn lưu trữ của cha mẹ của họ (của thư mục) EntryIDStoreID là tốt).

Các vấn đề liên quan