| |
VB.NET - Ein- und UmsteigerOutlook Mailitem schließen funktioniert nicht | | | Autor: Volker Bunge | Datum: 05.12.18 07:56 |
| Hallo zusammen,
ich will aus hunderten abgelegten Outlook 2007 Mails (MSG Dateien das Datum/Zeit und den Absender ermitteln (funktioniert soweit auch).
Anschließend soll die Datei das Erstellungsdatum der Mail bekommen und nicht wie jetzt das aktuelle Datum von gestern (da habe ich die Mails in Ordner abgelegt.
Hier mal mein bisheriger Code
Imports Microsoft.Office.Interop
Public Class Form1
Const Dateipfad As String = "C:\tmp\Zur Info - Satzung.msg"
Sub ändern(Dateipfad As String, neuesDatum As Date)
Dim sFile As String = Dateipfad
' FileInfo-Objekt erstellen
With New System.IO.FileInfo(sFile)
' Datums- und Zeitangaben auslesen
Debug.Print("Erstellungsdatum: " & .CreationTime)
Debug.Print("Letzter Zugriff: " & .LastAccessTime)
Debug.Print("Letzte Änderung: " & .LastWriteTime)
' Erstellungsdatum ändern
Dim DatumTag As Integer
'DatumTag = DateTime.Parse(neuesDatum.Day).DayOfWeek
.CreationTime = New Date(neuesDatum.Year, neuesDatum.Month, _
neuesDatum.Day, neuesDatum.Hour, neuesDatum.Minute, _
neuesDatum.Second)
' Datumsangabe "Letzter Zugriff" ändern
.LastAccessTime = neuesDatum ' New Date(2009, 5, 16, 13, 12, 11)
' Datum "Letzte Änderung" ändern
.LastWriteTime = neuesDatum ' New Date(2009, 5, 17, 13, 12, 11)
End With
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) _
Handles Button1.Click
Dim objOutlook As Outlook.Application
Dim objOutlookItem As Outlook.MailItem
Dim strPath As String
Dim strFile As String
Dim NeuesDatum As Date
' War auch mal ein Text, klappt unten aber auch nicht
Dim ExterneAnwendung As New System.Diagnostics.Process()
ExterneAnwendung.StartInfo.FileName = "OUTLOOK.EXE"
' ExterneAnwendung.Start() ' deaktiviert, da hier Outlook selbst _
starten würde
' Erzeugen...
objOutlook = New Outlook.Application
' Check...
If Not objOutlook Is Nothing Then
' Ab hier könntest Du eine Schleife draus machen,
' um die Dateien alle einzulesen
'
' Pfad und Datei...
strPath = "E:\Temp"
strFile = "TEST.msg"
' Mail öffnen...
objOutlookItem = CType(objOutlook.Session.OpenSharedItem( _
Dateipfad), Outlook.MailItem) 'strPath & "\" & strFile)
' Check...
If Not objOutlookItem Is Nothing Then
' Auslesen...
'MsgBox "Body: " & objOutlookItem.Body
'MsgBox "CreationTime: " & objOutlookItem.CreationTime
'MsgBox "DeferredDeliveryTime: " &
' objOutlookItem.DeferredDeliveryTime
MsgBox("ReceivedTime: " & objOutlookItem.ReceivedTime)
'MsgBox "ReminderTime: " & objOutlookItem.ReminderTime
MsgBox("SenderName: " & objOutlookItem.SenderName)
MsgBox("SenderEmailAddress: " & _
objOutlookItem.SenderEmailAddress)
MsgBox("Subject: " & objOutlookItem.Subject)
NeuesDatum = objOutlookItem.ReceivedTime
' Schließen...
' Hie scheint es dran zu liegen
objOutlookItem.Close(Outlook.OlInspectorClose.olDiscard) '
' Close(olDiscard) ' 1 = Discard = Verwerfen
'Outlook.Application.close()
End If
' Zurücksetzen...
objOutlookItem = Nothing
'
' Hier wäre das Ende der Schleife
'
' Abschließen schließen...
objOutlook.Quit()
End If
' Aufräumen...
objOutlook = Nothing
' ExterneAnwendung.kill() ' Findet hier keinen passenden Prozess. Liegt _
wohl an der oben deaktivierten .Start() Anweisung
Call ändern(Dateipfad, NeuesDatum)
End Sub
End Class Ich glaube, dass es an der Zeile
objOutlookItem.Close(Outlook.OlInspectorClose.olDiscard) ' Close(olDiscard) ' 1 = Discard = Verwerfen
liegt, denn Outlook ist als Task noch zu sehen. Beende ich Outlook manuell, dann funktioniert alles super.
(Die Massenabfertigung muss ich natürlich noch einbauen, und aufräumen sowieso).
Wäre echt super, wenn mir einer von Euch helfen könnte. Im Internet habe ich auch schon ein paar Stunden gestern gesucht aber immer nur das gleiche gefunden.
Vielen Dank
Volker | |
Re: Outlook Mailitem schließen funktioniert nicht | | | Autor: Volker Bunge | Datum: 05.12.18 11:09 |
| Hallo Manfred X,
vielen Dank erst einmal für den Link.
So, habe mal was ausprobiert:
1. Der neue Aufruf:
' Schließen...
' Hie scheint es dran zu liegen
' objOutlookItem.Close(Outlook.OlInspectorClose.olDiscard) ' Close(olDiscard) ' 1 = Discard = Verwerfen
' Outlook.Application.close()
ReleaseObj(objOutlookItem)
2. Neue Sub eingefügt
' Kamm bei der Übersetzung raus
Private Sub ReleaseObj(ByVal obj As Object)
Try
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
Catch
Finally
obj = Nothing
End Try
End Sub
Ergebnis: Funktioniert leider nicht.
Jetzt halt die Frage: Habe ich es bis hier her alles richtig gemacht? Wenn ja, woran liegt es dann bzw. welche Lösungen gibt es noch? Wenn nicht, wie müsste es richtig sein?
(P.S. Hatte beim ersten Versuch glaube ich kurz Erfolg, jetzt aber funktioniert es nicht, die OUTLOOK.EXE ist immer noch im Taskmanager sichtbar).
Hast Du bzw. ein anderer eine passende Lösung für mich?
Vielen Dank
Volker | |
Re: Outlook Mailitem schließen funktioniert nicht | | | Autor: Manfred X | Datum: 05.12.18 20:41 |
| Hallo!
Versuche folgendes:
Stelle sicher, daß Deine Anwendung Outlook nur einmal startet
(Taskmanager).
Stelle sicher, daß alle verwendeten Outlook-Objekte im Code auch
wieder freigegeben werden
Rufe die Outlook.Quit-Methode beim Release des Outlook-Objekts
Setze den Automatisierungscode in eine eigene Klasse
und implementiere dort die Dispose-Schnittstelle, um sicher zu stellen
daß der Garbage-Collektor für das freigegebene Objekt zum Einsatz kommt.
Entferne den Code für den Prozeß "externe Anwendung".
Beitrag wurde zuletzt am 05.12.18 um 20:47:02 editiert. | |
Re: Outlook Mailitem schließen funktioniert nicht | | | Autor: Volker Bunge | Datum: 11.12.18 09:41 |
| Hallo Manfred,
sorry, dass ich mich erst jetzt melde.
Zu Deiner Antwort bzw. Vorgehensweise habe ich noch so ein paar Verständnisfragen
Zuerst einmal was habe ich geändert:
1. "externe Anwendung" entfernt
2. Ein paar Kleinigkeiten gelöscht (bspw. die alte Pfadangabe)
3. Den Automatisierungscode ( Public Sub ReleaseObj(ByVal obj As Object) in eine cls_Outlook Klasse gepackt
Was ich aber noch nicht verstehe bzw. nicht weiss, ob das richtig ist ist folgendes
1. Stelle sicher, daß alle verwendeten Outlook-Objekte im Code auch wieder freigegeben werden
Also die Variablen objOutlookItem und objOutlook werden ja durch = Nothing gelöscht. Oder meinst Du was anderes?
2. Rufe die Outlook.Quit-Methode beim Release des Outlook-Objekts
Habe ich mal eingefügt (siehe Code). Es wird zumindestens kein offensichtlicher Fehler angezeigt.
3. und implementiere dort die Dispose-Schnittstelle, um sicher zu stellen daß der Garbage-Collektor für das freigegebene Objekt zum Einsatz kommt
Hier habe ich mal gegoogelt und folgenden Link gefunden und das erste Beispiel mal übersetzen lassen
https://docs.microsoft.com/de-de/dotnet/standard/garbage-collection/implementing-dispose
Habe dann den vb.net Code in die Klasse kopiert. Dort ist aber schon die 5. Zeile "Implements IDisposable" wellig unterstrichen.
(Fehlermeldung: Class "cls_Outlook" muss "Sub Dispose" für die System.IDispoable-Schnittstelle implementieren.)
Aber erlich gesagt: Ich verstehe hier auf der Seite nur noch Bahnhof.
Daher füge ich nun hier noch einmal den gesamten Code ein und hoffe, dass Du (oder ein anderer) mir weiterhelfen kann bzw. mal kurz erklären kann, was die Dispose-Sache eigentlich bedeutet.
Vielen Dank schon einmal im Voraus.
Volker | |
Re: Outlook Mailitem schließen funktioniert nicht | | | Autor: Volker Bunge | Datum: 11.12.18 09:41 |
| Hier nun der Code für das Formular
Imports Microsoft.Office.Interop
Public Class Form1
Const Dateipfad As String = "C:\tmp\Test.msg"
Sub ändern(Dateipfad As String, neuesDatum As Date)
Dim sFile As String = Dateipfad
' FileInfo-Objekt erstellen
With New System.IO.FileInfo(sFile)
' Datums- und Zeitangaben auslesen
Debug.Print("Erstellungsdatum: " & .CreationTime)
Debug.Print("Letzter Zugriff: " & .LastAccessTime)
Debug.Print("Letzte Änderung: " & .LastWriteTime)
' Erstellungsdatum ändern
Dim DatumTag As Integer
'DatumTag = DateTime.Parse(neuesDatum.Day).DayOfWeek
.CreationTime = New Date(neuesDatum.Year, neuesDatum.Month, _
neuesDatum.Day, neuesDatum.Hour, neuesDatum.Minute, _
neuesDatum.Second)
' Datumsangabe "Letzter Zugriff" ändern
.LastAccessTime = neuesDatum ' New Date(2009, 5, 16, 13, 12, 11)
' Datum "Letzte Änderung" ändern
.LastWriteTime = neuesDatum ' New Date(2009, 5, 17, 13, 12, 11)
End With
End Sub
Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) _
Handles Button2.Click
Dim objOutlook As Outlook.Application
Dim objOutlookItem As Outlook.MailItem
Dim NeuesDatum As Date
' Erzeugen...
objOutlook = New Outlook.Application
' Check...
If Not objOutlook Is Nothing Then
' Ab hier könntest Du eine Schleife draus machen,
' um die Dateien alle einzulesen
'
' Mail öffnen...
objOutlookItem = CType(objOutlook.Session.OpenSharedItem( _
Dateipfad), Outlook.MailItem) 'strPath & "\" & strFile)
' Check...
If Not objOutlookItem Is Nothing Then
' Auslesen...
'MsgBox "Body: " & objOutlookItem.Body
'MsgBox "CreationTime: " & objOutlookItem.CreationTime
'MsgBox "DeferredDeliveryTime: " &
' objOutlookItem.DeferredDeliveryTime
MsgBox("ReceivedTime: " & objOutlookItem.ReceivedTime)
'MsgBox "ReminderTime: " & objOutlookItem.ReminderTime
MsgBox("SenderName: " & objOutlookItem.SenderName)
MsgBox("SenderEmailAddress: " & _
objOutlookItem.SenderEmailAddress)
MsgBox("Subject: " & objOutlookItem.Subject)
NeuesDatum = objOutlookItem.ReceivedTime
' Schließen...
' Hie scheint es dran zu liegen
'objOutlookItem.Close(Outlook.OlInspectorClose.olDiscard) ' _
Close(olDiscard) ' 1 = Discard = Verwerfen
'Outlook.Application.close()
releaseObj(objOutlookItem)
End If
' Zurücksetzen...
objOutlookItem = Nothing
'
' Hier wäre das Ende der Schleife
'
' Abschließen schließen...
objOutlook.Quit()
End If
' Aufräumen...
objOutlook = Nothing
Try
Catch ex As Exception
End Try
Call ändern(Dateipfad, NeuesDatum)
End Sub
Private Sub releaseObj(objOutlookItem As Outlook.MailItem)
Throw New NotImplementedException
End Sub
End Class Für die Klasse cls_Outlook
Imports Microsoft.Win32.SafeHandles
Imports System
Imports System.Runtime.InteropServices
Class cls_Outlook
Implements IDisposable
Private disposed As Boolean = False
Private handle As SafeHandle = New SafeFileHandle(IntPtr.Zero, True)
Public Sub Dispose()
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If disposed Then Return
If disposing Then
handle.Dispose()
End If
disposed = True
End Sub
Public Sub ReleaseObj(ByVal obj As Object)
Try
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
Catch
Finally
obj = Nothing
End Try
End Sub
End Class | |
Re: Outlook Mailitem schließen funktioniert nicht | | | Autor: Manfred X | Datum: 12.12.18 10:22 |
| Hallo!
Wo ich mich diese Tage aufhalte, ist MS-Outlook nicht in Gebrauch.
Insofern kann ich nur eingeschränkt hilfreich sein.
Schnittstelle ...
Eine Schnittstelle ist eine Liste von Eigenschaften, Methoden usw
OHNE darin enthaltenen Code!
Eine Klasse kann eine Schnittstelle implementieren und muß dann alle
Methoden und Eigenschaften der Schnittstelle mit passendem Code
zur Verfügung stellen.
Schnittstellen erlauben es, im Programm an einer Stelle Instanzen
unterschiedlicher Klassen, die alle diese Schnittstelle impl., zu nutzen,
wenn man sich darauf beschränkt, diese Schnittstellen-Methoden zu verwenden.
IDisposable-Schnittstelle ...
In Net gibt es verwaltete und nicht-verwaltete Objekte.
Verwaltete Objekte werden innerhalb der Net-Umgebung erstellt, verwendet und
freigegeben.
Nicht-verwaltete Objekte erstellen intern weitere Objekte oder Ressourcen und
nutzen diese. Net kennt diese unverwalteten "Speicherinhalte" nicht und kann sie
weder direkt verwenden noch freigeben.
Es macht keinen Sinn, Zugriffsvariablen für nicht-verwaltete Objekte auf
Nothing zu setzen. Eine völlige Freigaben kann Net nicht durchführen.
Die IDisposable-Schnittstelle implementiert die Dispose-Methode.
In dieser Methode ist der Code einzutragen, durch den nicht-verwaltete
Bestandteile (Handles, Prozesse, ...) explizit "released" werden.
In Deinem Fall wäre das die Freigabe und das Quit von verwendeten
Outlook-Klassen.
Falls vorhanden, ruft Net bei Freigabe einer Instanz diese Methode auf.
Wenn sie korrekt für eine Klasse programmiert worden ist, ermöglicht dies
die vollständige Entfernung des Objekts aus dem Speicher. | |
Re: Outlook Mailitem schließen funktioniert nicht | | | Autor: Volker Bunge | Datum: 22.12.18 10:49 |
| Hallo ManfredX,
leider verstehe ich Deine "allgemeine" Erklärung nicht bzw. habe keine Ahnung, wie ich diese erfolgreich umsetzen könnte.
Daher meine Frage bzw. Bitte: Könntest Du mir (wenn Du wieder an einem Rechner mit Outlook bist), mir dies anhand eines Codebeispiels verdeutlichen?
Eigentlich kann es doch nicht so schwer sein, eine Anwendung zu öffnen und eine Verarbeitung zu vollziehen und diese dann wieder ordnungsgemäß zu beenden.
Wenn Du, oder natürlich jemand anderes, eine passende Lösung hätte, wäre ich sehr glücklich darüber.
Vielen Dank schon einmal an alle und ein frohes Fest Euch allen.
Gruß
Volker | |
| Sie sind nicht angemeldet! Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.
Einloggen | Neu registrieren |
|
|
sevAniGif (VB/VBA)
Anzeigen von animierten GIF-Dateien
Ab sofort lassen sich auch unter VB6 und VBA (Access ab Version 2000) animierte GIF-Grafiken anzeigen und abspielen, die entweder lokal auf dem System oder auf einem Webserver gespeichert sind. Weitere InfosTipp des Monats TOP Entwickler-Paket
TOP-Preis!!
Mit der Developer CD erhalten Sie insgesamt 24 Entwickler- komponenten und Windows-DLLs. Die Einzelkomponenten haben einen Gesamtwert von 1605.50 EUR...
Jetzt nur 599,00 EURWeitere Infos
|