Dateiliste aus Clipboard leer nach Kopieren von Mail-Attachements (Outlook) in Clipboard

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 12 Antworten in diesem Thema. Der letzte Beitrag () ist von mrMo.

    Dateiliste aus Clipboard leer nach Kopieren von Mail-Attachements (Outlook) in Clipboard

    Aufgabenstellung: Ich kopiere direkt in Outlook (Office 365) die vorhandenen Attachements in die Zwischenablage und füge die Files in meine VB.NET-Applikation ein (copy/paste). In der Applikation lese ich die Clipboard.GetFileDropList() aus und speichere die Dateien in einem entsprechenden Ordner, den die Applikation vorgibt.

    Problemstellung: Nach dem Kopieren der Attachements in die Zwischenablage bleibt die Clipboard.GetFileDropList() leer. Die MessageBox zählt 0 Einträge und die nachfolgende Abfrage ist false. Trotzdem kann ich im Windows-Explorer die Dateien mit CTRL-V tadellos in einen beliebigen Ordner einfügen.

    VB.NET-Quellcode

    1. MsgBox(Clipboard.GetFileDropList.Count)
    2. If Clipboard.ContainsFileDropList = True Then ' Auslesen Dateien, wenn eine Dateiliste kopiert wird
    3. Dim files As Collections.Specialized.StringCollection = Clipboard.GetFileDropList()
    4. SaveFilesRes(files)
    5. End If


    Wichtig: Die Dateiinhalte oder -formate interessieren nicht. Es geht darum, mit der Applikation alle Attachement-Dateien in einer Datenbank zu verwalten.
    Bemerkung: Alle Dateien, die ich im Windows-Explorer kopiere, kann ich mit dem obigen Code problemlos in meine Applikation einfügen. Es funktioniert nur nicht aus Outlook. Was ist der Unterschied?
    Was mache ich falsch? Danke schon im Voraus für ein paar Tipps

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „icewather“ ()

    @icewather Mail-Anhänge sind im Sinne des Betriebssystems ggf. keine Dateien, da sie sich nicht als solche auf Platte befinden.
    Vielleicht klärst Du zunächst auf, was sich da in der Zwischenablage befindet und konvertierst es dann in "richtige" Dateien.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Danke RFG für den Hinweis! - Dann würde also der WinExplorer daraus auch zuerst "richtige" Dateien machen.
    Kannst du mir einen weiteren Tipp geben, wie ich herausfinden kann, was in der Zwischenablage ist? und dann: Wie mache ich daraus richtige Dateien?

    Ich weiss leider nur, wie ich gezielte Inhalte aus dem Clipboard abfragen kann. Aber unbestimmte Inhalte, wie frage ich die ab?
    @icewather Zunächst testest Du, ob ühaupt was da ist.

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. Dim d = Clipboard.GetDataObject()
    3. MessageBox.Show(d.ToString)
    4. End Sub

    Um diesen OleConverter müsstest Du Dich mal kümmern.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany - Danke für deine weiterführenden Hinweise.
    Ich denke, dass das die richtige Spur ist und habe mal kräftig gegoogelt. Das scheint eine heisse Spur zu sein: codeproject.com/articles/28209…and-drop-in-c?msg=4265034

    Vor allem dieser Abschnitt:

    C#-Quellcode

    1. //get the internal ole dataobject and its GetDataFromHGLOBLAL method
    2. BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Instance;
    3. FieldInfo innerDataField =
    4. e.Data.GetType().GetField("innerData", bindingFlags);
    5. IDataObject oleDataObject =
    6. (System.Windows.Forms.IDataObject)innerDataField.GetValue(e.Data);
    7. MethodInfo getDataFromHGLOBLALMethod =
    8. oleDataObject.GetType().GetMethod("GetDataFromHGLOBLAL", bindingFlags);
    9. getDataFromHGLOBLALMethod.Invoke(oleDataObject,
    10. new object[] { format, medium.unionmember });


    Leider bin ich unfähig, das nun so in VB.NET zu übertragen, dass ich mehr als nur Fehlermeldungen kriege. Und weil ich das nicht kann, weiss ich auch nicht, ob das zu einer Lösung führen würde.
    Hier ein weiterer Link, aber auch das kriege ich nicht hin: codeproject.com/messages/33194…-in-csharp-but-not-i.aspx
    Wie weiter? hat jemand einen Tipp?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „icewather“ ()

    Hier ein spannender Link in Bezug auf ein ähnliches Problem: Outlook-Attachements per Drag-and-Drop in Windows-Form einbauen: codeproject.com/Articles/7140/…-File-From-Outlook-and-ab

    Leider auch wieder in C# - ich werde mal versuchen, das in VB.NET umzuschreiben. Allerdings wird dieser Ansatz das Problem der verborgenen Outlook-Clipboard-Dateien nicht lösen.
    Hab das neulich erst gemacht, allerdings ziehe ich mir die Mail aus Outlook direkt in mein Programm per Drag&Drop.

    Hierzu erzeuge ich ein Outlook.MailItem.
    Die Anhänge findet man dort in Form vom Objekttyp Outlook.Attachment

    Nutze hierfür Microsoft.Office.Interop

    Edit: Beispiel Code

    VB.NET-Quellcode

    1. Public Function GetMailInhalte() As OutlookEMail
    2. Dim Mail As OutlookEMail
    3. Dim app As New Outlook.Application
    4. Dim ex As Outlook.Explorer = app.ActiveExplorer()
    5. 'Hier wird die in Outlook selectierte Mail ermittelt
    6. Dim GewaehlteMails As Outlook.Selection = ex.Selection()
    7. If (GewaehlteMails.Count <> 1) Then Return Nothing
    8. For Each item As Object In GewaehlteMails
    9. Dim EMailItem As Outlook.MailItem = TryCast(item, Outlook.MailItem)
    10. Mail = New OutlookEMail(EMailItem)
    11. Next
    12. Return Mail
    13. End Function


    Ich habe eine Separate Klasse (OutlookEMail) in der ich unter anderem die Anhänge aus der Mail zeihe. Der Konstruktor erwartet in meinem Fall ein Outlook.MailItem. Aus diesem kann ich alle Infos raus zeihen, unter anderem auch die Anhänge:

    VB.NET-Quellcode

    1. For Each Anhang As Outlook.Attachment In Mail.Attachments
    2. 'Anhänge einer List(Of Outlook.Attachment)​ hinzufügen
    3. _lstAnhaenge.Add(Anhang)
    4. Next
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „mrMo“ ()

    @mrMo
    Danke, ein spannender Ansatz, den ich ausprobieren möchte. Sorry, eine dumme Frage: Woher kriegst du den Typ OutlookEMail her? Ich habe den Verweise installiert: Microsoft Outlook 16.0 Object Library
    Dazu die nötigen Importbefehle:

    VB.NET-Quellcode

    1. Imports Microsoft.Office.Interop
    2. Imports Microsoft.Office.Interop.Outlook


    Doch leider kann ich auch auf dem Web keinen Hinweis finden, wie zu der Typenbeschreibung OutlookEMail komme. Kannst du mir bitte weiterhelfen?
    @icewather

    Hab mir eine eigene Klasse mit dem Namen OutlookEMail geschrieben. Daher findest du hierzu nix im Netz ;)

    In der Klasse sind die Properties und der Konstruktor. Steht auch in meinem Post oben.
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    Ich schätze, wenn du meinen Code oben leicht umbaust, brauchst du keine Klasse mehr. Vor allem, da drin passiert nix magisches. Da sind blos die Accessoren und ein Konstruktor drin um die Eigenschaften vom Outlook.MailItem schön auslesen zu können. Die Anhänge findest du im Outlook.MailItem.

    So in der Richtung könnte (ungetestet, vom Handy, ausm Kopf, vor dem ersten Kaffee) es ohne die separate Klasse gehen:

    VB.NET-Quellcode

    1. Dim EMailItem As Outlook.MailItem
    2. For Each item As Object In GewaehlteMails
    3. EMailItem = TryCast(item, Outlook.MailItem)
    4. Next
    5. Dim lstAnhaenge As New List(Of Outlook.Attachment)
    6. For Each Anhang As Outlook.Attachment In EMailItem.Attachments
    7. lstAnhaenge.Add(Anhang)
    8. Next
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „mrMo“ ()

    @mrMo
    Ein RIESIGES DANKE!!!! Du hast mir eine Funktion in meiner Applikation ermöglicht, die mich beflügelt. Ich brauche diesen Attachement-Transfer jeden Tag mehrfach und musste das bis jetzt "von Hand" machen. Ein mega Danke für deine Unterstützung!!!!!!! Hier mein Code:

    VB.NET-Quellcode

    1. Private Sub conResFileOutlook_Click(sender As Object, e As EventArgs) Handles conResFileOutlook.Click
    2. Dim EMailItem As Outlook.MailItem = Nothing
    3. Dim app As New Outlook.Application
    4. Dim vDateien(0) As Object
    5. Dim ex As Outlook.Explorer = app.ActiveExplorer()
    6. Dim GewaehlteMails As Outlook.Selection = ex.Selection()
    7. dbSysDao = dbEn.OpenDatabase(vdbSysPath, Nothing, False)
    8. rsSysTemp = dbSysDao.OpenRecordset("SELECT * FROM Optionen WHERE rdbName = '" & rDbName & "'")
    9. Dim vPath As String = rsSysTemp.Fields("optOrdnerWord").Value
    10. rsSysTemp.Close()
    11. If Len(vPath) < 5 Then
    12. MessageBox.Show("Der Speicherort für die automatische Ablage der Outlook-Mail-Dateianhänge ist nicht definiert. Bitte wählen Sie in >Extra / Einstellungen / Dateifunktionen / Ablagerdner für automatische Dokumente< einen Ordner aus.", "Fehlender Ordner für Datenspeicherung", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
    13. Exit Sub
    14. End If
    15. If Microsoft.VisualBasic.Right(vPath, 1) <> "\" Then vPath = vPath & "\"
    16. For Each item As Object In GewaehlteMails
    17. EMailItem = TryCast(item, Outlook.MailItem)
    18. Next
    19. Dim lstAnhaenge As New List(Of Outlook.Attachment)
    20. Dim i As Integer = 0
    21. For Each Anhang As Outlook.Attachment In EMailItem.Attachments
    22. Anhang.SaveAsFile(vPath & Anhang.FileName)
    23. vDateien(i) = vPath & Anhang.FileName
    24. i = i + 1
    25. ReDim Preserve vDateien(i)
    26. Next
    27. SaveFilesRes(vDateien)
    28. End Sub
    @icewather schön, freut mich wenn ich dir geholfen habe :)
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen