Win32 Aufgaben Outlook



  • Martin Richter schrieb:

    Wie man es macht steht in der Outllok Doku. Den VB Code soltest Du ohne Probleme auf COM mit C++ übertragen können.
    http://msdn.microsoft.com/en-us/library/bb623455.aspx

    Eenn du einfach keine Lust hast hier hilfreich zu sein, dann ist das ja soweit ok, da hier ja kein Zwang besteht. Wenn du aber damit sagen willst, dass sich auf Grund dieser Online Doku jede weitere Antwort in Bezug auf die Verwendung in C++ erübrigen würde, dann finde ich das den übrigen Lesern ebenfalls nicht ganz fair gegenüber, da man eben definitiv die Verwendung der Redemption API ausschließlich konzeptionell konzeptionell der Online Doku entnehmen kann.

    Da sind null Informationen enthalten, wie das in C++ geht. Und das es dort vollkommen unterschiedlich funktioniert, habe ich bereits hinreichend ausgeführt.

    Gruß, IceRage



  • IceRage schrieb:

    Aber woher weiß ich jetzt, wie ich die einzelnen Elemente benutzen muss? In VB, C# oder so gibts ja keine Pointer, Referenzen usw ... Außerdem sind die Übergabeparameter bestimmt auch ganz andere. Gibts denn keine C++ Referenz für Redemption?

    also, wenn dann von den Entwicklern der Redemption.dll.

    wenn die keine vernurnftige Doku und keine brauchbaren Beispiele liefern, dann such dir ne anderen Hersteller.

    gruss
    Dirk



  • Hier habe ich mal ein Schnipsel, dass lt. Entwickler funktionieren sollte.

    IRDOSession session;
    session.CreateDispatch(L"Redemption.RDOSession");
    COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
    session.Logon(covOptional, covOptional, covOptional, covOptional,
    covOptional ,covOptional);
    

    Da braucht es allerdings den afxdisp.h header, der in den MFC enthalten ist, die widerwurm nicht Bestandteil von VS Express sind.


  • Mod

    Und warum brauchst Du die MFC? Wegen COleVarian`?
    Es gibt doch auch variant_t! Und VARIANT pur kannst Du auch verwenden...



  • Vielen Dank, werd ich so machen.

    Übrigens: Der Codeschnippsel direkt hier oben drüber, kann so nicht funktionieren 😉

    Wie ich eben herausfand ist IRDOSession ist eine abstrakte Klasse. Und da dürfte es schwierig werden, ein Objekt davon zu instanziieren. Passender Weise sind aber natürlich die Member der Klasse nicht statisch, so dass beispielsweise: Logon() nicht benutzt werden kann ... wunderbare Windoofswelt ...



  • IceRage schrieb:

    Wie ich eben herausfand ist IRDOSession ist eine abstrakte Klasse. Und da dürfte es schwierig werden, ein Objekt davon zu instanziieren. Passender Weise sind aber natürlich die Member der Klasse nicht statisch, so dass beispielsweise: Logon() nicht benutzt werden kann ... wunderbare Windoofswelt ...

    Instanziieren kannst du es nicht, aber du kannst Zeiger darauf anlegen - danach holst du dir dann ein Objekt, das die akstrakten Methoden definiert hat (das passiert bei COM normalerweise hinter den Kulissen, so daß du den Typ dieses Objekts nicht kennst).

    (in Sprachen wie Java oder C# nennt man so etwas dann "Interface")



  • Ich muss doch jetzt aber nicht anfangen von dem Interface zu erben, nur damit ich ein konkretes Objekt anlegen kann.

    Also ein Zeiger darauf anlegen ist klar:

    IRDOSession *session;
    

    Und wie soll ich mir da jetzt ein konkretes Objekt holen?

    EDIT: CoCreateInstance?



  • IceRage schrieb:

    Ich muss doch jetzt aber nicht anfangen von dem Interface zu erben, nur damit ich ein konkretes Objekt anlegen kann.

    Nein, das hat der Autor der DLL für dich schon erledigt.

    Und wie soll ich mir da jetzt ein konkretes Objekt holen?

    EDIT: CoCreateInstance?

    Vermutlich schon. Aber dazu wartest du besser auf die COM-Experten.


  • Mod

    IceRage schrieb:

    Und wie soll ich mir da jetzt ein konkretes Objekt holen?

    EDIT: CoCreateInstance?

    Ja! Oder eben von einem anderen Objekt, dass Du über einen Moniker oder aus der IROT erhältst.



  • Das mit dem CreateObjekt funktioniert soweit wies aussieht:

    // OutlookRedemption.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
    //
    
    #include "stdafx.h"
    
    #import "C:\Programme\Redemption\Redemption.dll"
    
    using namespace Redemption;
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	HRESULT hr = CoInitialize(NULL);
    	CLSID clsid;
    	IRDOSession *pSession;
    	BSTR path = OLESTR("C:\\vs_projects\\Outlook.pst"); //SysAllocString(L"C:\vs_projects\Outlook.pst");
    
    	VARIANT store;
    	VariantInit(&store);
    	V_VT(&store)=VT_BSTR;
    	V_BSTR(&store)=SysAllocString(L"Idiot Store");
    
    	VARIANT pass;
    	VariantInit(&pass);
    	V_VT(&pass)=VT_BSTR;
    	V_BSTR(&pass)=SysAllocString(L"test");
    
    	try {
    		hr = CLSIDFromProgID(OLESTR("Redemption.RDOSession"), &clsid); 
    		hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (LPVOID*)&pSession);
    		IRDOPstStorePtr pPstStore = pSession->LogonPstStore(path, 1, store, pass, 0);
    
    		IRDOPstStore *oPstStore;
    		hr = CLSIDFromProgID(OLESTR("Redemption.RDOPstStore"), &clsid);
    		hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (LPVOID*)&oPstStore);
    		printf("%s", oPstStore->Name);
    	} catch (...) {
    		printf("crap\n");
    	}
    
    	system("PAUSE");
    	return 0;
    }
    

    Das Problem ist, in Zeile 30, also bei der Logon... Methode fliege ich mit einem Speicherzugriff raus.

    Unbehandelte Ausnahme bei 0x00958bb3 in OutlookRedemption.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0xfc655ea5.
    

    Übrigens: lt. Online Doku: http://www.dimastr.com/redemption/rdo/rdosession.htm sind die letzten 3 Parameter für LogonPstStore angeblich optional. In VB wird das möglicherweise auch der Fall sein. In C++ ist dies definitiv NICHT der Fall. Wenn ich versuche ausschließlich den Pfad an LogonPstStore zu übergeben, erhalte ich die Fehlermeldung, dass die Methode zu wenig Argumente enthält! Deswegen biege ich mir da auch was mit VARIANT zurecht. Aber trotzdem dieser Speicherzugriffsfehler.

    Montag bekomme ich ein Buch CDO Programmierung. Dann schmeisse ich diesen ganzen überflüssigen Redemption Scheiss raus!

    Wenn hier nur mal jemand bereit wäre ein paar, wenige Codezeilen zu posten, die die Verwendung von extended MAPI Objekten, bezogen auf das Auslesen von Aufgaben aus einem Outlook PST File darstellen, zu posten ... Aber sich hier mal über konkreten Code zu unterhalten, schein euch in diesem CPLUPLUS Forum ja sehr schwer zu fallen ... nur Geschwafel, und unspezifische Halbaussagen ...

    KONKRETE CODEBEISPIELE !! Das kann man verstehen, oder zumindest zielführend diskutieren. Alles andere ist Prosa! Man programmiert schließlich problemorientiert, und nicht zum Selbstzweck!


  • Mod

    Das Problem ist, in Zeile 30, also bei der Logon... Methode fliege ich mit einem Speicherzugriff raus.
    [/quote]

    Solange Du nicht mal ürfst ob Du einen gültigen Zeiger hast (hr==S_OK) brauchen wir uns gar nicht weiter unterhalten.

    IceRage schrieb:

    Übrigens: lt. Online Doku: http://www.dimastr.com/redemption/rdo/rdosession.htm sind die letzten 3 Parameter für LogonPstStore angeblich optional. In VB wird das möglicherweise auch der Fall sein. In C++ ist dies definitiv NICHT der Fall.

    Dann solltest Du auch hier einfach mal Grundlagen lernen.
    Doch die sindoptimal. Nur musst Du sie dennoch angeben. Du benutt hier das direkjt COM Interface und eben nicht VB.
    Intern macht VB nämlich das hier und so musst Du es bei "optionalen" Parametern auch machen:
    http://support.microsoft.com/kb/238981

    IceRage schrieb:

    Montag bekomme ich ein Buch CDO Programmierung. Dann schmeisse ich diesen ganzen überflüssigen Redemption Scheiss raus!

    Redemptionist kein Scheiß. Es ist in vielen Fällen die einzige Möglichkeit an alles heran zu kommen.
    Mit CDO geht vieles gar nicht.

    IceRage schrieb:

    Wenn hier nur mal jemand bereit wäre ein paar, wenige Codezeilen zu posten, die die Verwendung von extended MAPI Objekten, bezogen auf das Auslesen von Aufgaben aus einem Outlook PST File darstellen, zu posten ... Aber sich hier mal über konkreten Code zu unterhalten, schein euch in diesem CPLUPLUS Forum ja sehr schwer zu fallen ... nur Geschwafel, und unspezifische Halbaussagen ...

    KONKRETE CODEBEISPIELE !! Das kann man verstehen, oder zumindest zielführend diskutieren. Alles andere ist Prosa! Man programmiert schließlich problemorientiert, und nicht zum Selbstzweck!

    Ich kann keinen Code posten, weil der nämlich der Firma gehört für die ich arbeite.
    Sample Codee ist bei Redemption genug dabei. Dein Problemist eher Dein "Verstehen" und "Arbeiten" mit COM und das umsezen von VB samples auf COM mit C++...



  • Martin Richter schrieb:

    Solange Du nicht mal prüfst ob Du einen gültigen Zeiger hast (hr==S_OK) brauchen wir uns gar nicht weiter unterhalten.

    Du magst Recht haben mit dem was du sagst. Aber das ich S_OK natürlich auch mit dem schrittweisen Debuggen überprüfen kann, müsstest du eigentlich wissen. Ich muss das nicht programmatisch mit einer Kontrollstruktur überprüfen. Wenn mir der Debugger für hr = S_OK anzeigt, dann ist das Objekt instanziert worden.

    Es ist schon klar, dass ich in einem lauffähigen Programm, dann schon mit Kontrollstrukturen arbeite. Bloß für den Moment geht es mir lediglich mal darum, einen Anfang zu finden - also überhaupt mal irgendeinen Wert aus einer PST Datei herauszulesen. Wenn ich das habe, dann gehts weiter. Wüßte nicht, was an dieser Arbeitsweise falsch sein sollte.

    Vielen Dank für deinen Tipp bezüglich der der optionalen Parameter, dass schaue ich mir an.


  • Mod

    IceRage schrieb:

    Wenn ich das habe, dann gehts weiter. Wüßte nicht, was an dieser Arbeitsweise falsch sein sollte.

    Weil Du hier Code postest und uns nicht sagt das der Zeiger OK ist aber der Crash danach kommt.
    Ohne Fehlerprüfung gehe ich davon aus, dass der Fehler woanders liegt.
    So sähe bei mir nicht mal Test-Code aus.

    Weitere Fehler in Deinem Programm.

    BSTR path = OLESTR("C:\\vs_projects\\Outlook.pst"); //SysAllocString(L"C:\vs_projects\Outlook.pst");
    

    Das ist kein BSTR. BSTR müssen mit SysAllocString belegt werden!
    Keine Ahnung warum Du den richtigen Code nicht verwendest.

    2. Du hast keien Cleanup Code 😉 auch so etwas gehört in den Testcode...

    PS: Beschäftige Dich etwas mehr mit Grundlagen bevor Du so extrem herum maulst. Es sind nicht meine Fehler die Du machst 😉



  • Ich habe jetzt trotzdem noch einmal programmatische Abfragen auf hr laufen lassen:

    hr = CLSIDFromProgID(OLESTR("Redemption.RDOSession"), &clsid);
    		if (hr != S_OK) return 2;
    		hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (LPVOID*)&pSession);
    		if (hr != S_OK) return 2;
    		IRDOPstStorePtr pPstStore = pSession->LogonPstStore(path, varOpt, varOpt, varOpt, varOpt);
    

    Läuft leider ohne Erfolg. pSession->LogonPstStore(....); wird aufgerufen und verursacht einen Speicherzugriffsfehler.



  • Martin Richter schrieb:

    PS: Beschäftige Dich etwas mehr mit Grundlagen bevor Du so extrem herum maulst. Es sind nicht meine Fehler die Du machst 😉

    Ich habe auch nicht gesagt, dass ich ein Problem mit meinen Fehlern habe; daraus lerne ich ja. Ganz im Gegenteil. Ich mache gern Fehler. Was mir nur auf die nerven geht, ist das hier jeder herumpalavert, und niemand mal konkrete Codezeilen postet, die sehr viel hilfreicher wären, als jede Erklärung. Optimal wären natürlich Codezeilen inkl. Erklärung. Das wäre nebenbei gesagt für alle Leser hier von Vorteil. Warum du im Speziellen keinen Code posten "darfst", hast du ja bereits erklärt. Damit muss man dann halt leben.

    Aber was du hier Grundlagen nennst, ist eigentlich nicht wirklich im Bereich der Grundlagen anzusiedeln. Das ist alles Windoofs spezifisch. Oder hast du schon mal für einen Code unter Linux VB COM Code aus Windoofs anwenden müssen?



  • Bei dem Code hier entsteht übrigens ein "Schlechtes Ptr", also wohl ein Bad Pointer:

    // OutlookRedemption.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
    //
    
    #include "stdafx.h"
    
    #import "C:\Programme\Redemption\Redemption.dll"
    
    using namespace Redemption;
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	HRESULT hr = CoInitialize(NULL);
    	CLSID clsid;
    	IRDOSession *pSession;
    	BSTR path = SysAllocString(L"C:\\vs_projects\\Outlook.pst");
    
        VARIANT varOpt;
        varOpt.vt = VT_ERROR;
        varOpt.scode = DISP_E_PARAMNOTFOUND;
    
    	try {
    		hr = CLSIDFromProgID(OLESTR("Redemption.RDOSession"), &clsid);
    		if (hr != S_OK) return 2;
    		hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (LPVOID*)&pSession);
    		if (hr != S_OK) return 2;
    		IRDOPstStorePtr pPstStore = pSession->LogonPstStore(path, varOpt, varOpt, varOpt, varOpt);
    
    		IRDOPstStore *oPstStore;
    		hr = CLSIDFromProgID(OLESTR("Redemption.RDOPstStore"), &clsid);
    		hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (LPVOID*)&oPstStore);
    		printf("%s", oPstStore->Name);
    	} catch (...) {
    		printf("crap\n");
    	}
    
    	system("PAUSE");
    	return 0;
    }
    

    Genau dann, wenn raw_LogonPstStore(...) aus der Redemption.cli aufgerufen wird, dann entsteht der Bad Pointer Fehler.



  • IceRage schrieb:

    Was mir nur auf die nerven geht, ist das hier jeder herumpalavert, und niemand mal konkrete Codezeilen postet, die sehr viel hilfreicher wären, als jede Erklärung.

    Jo, weil die grad jeder passend herumliegen hat. Oder bei so einem speziellen Thema einfach aus dem Ärmel schüttelt.

    IceRage schrieb:

    Aber was du hier Grundlagen nennst, ist eigentlich nicht wirklich im Bereich der Grundlagen anzusiedeln. Das ist alles Windoofs spezifisch.

    Windows-Grundlagen halt..

    "👍" für Martins Geduld.



  • Naja vielleicht hat ein COMer ja so etwas herumliegen 😉

    Ach is mir auch Latte. Wenn ihr meint, dass hier ansonsten alles in Ordnung ist, dann ist es doch ok. Ich meine halt, dass hier alles viel zu sehr künstlich verkompliziert wird. .. nicht persönlich nehmen, ist halt meine Ansicht.

    Das es auch einfach geht, zeigen die folgenden Zeilen, als beispielhaftes Grundgerüst. So kann man den ProfilNamen, und den default ordner eines pst Files auslesen. Einzubindende Header sind dabei:

    #include <stdio.h>
    #include <tchar.h>
    #include <exception>
    #include <iostream>
    

    Und der Code is as follows 😉

    // OutlookRedemption.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
    //
    
    #include "stdafx.h"
    
    #import "C:\Programme\Redemption\Redemption.dll"
    
    using namespace Redemption;
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	HRESULT hr = CoInitialize(NULL);
    	CLSID clsid;
    	IRDOSession *pSession;
    	BSTR path = SysAllocString(L"C:\\vs_projects\\Outlook.pst");
    
        VARIANT varOpt;
        varOpt.vt = VT_ERROR;
        varOpt.scode = DISP_E_PARAMNOTFOUND;
    
    	try {
    		hr = CLSIDFromProgID(OLESTR("Redemption.RDOSession"), &clsid);
    		if (hr != S_OK) return 2;
    		hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, _uuidof(IRDOSession), (LPVOID*)&pSession);
    		if (hr != S_OK) return 2;
    		std::cout << pSession->Profiles->GetDefaultProfileName() << std::endl;
    		IRDOPstStorePtr pPstStore = pSession->LogonPstStore(path, varOpt, varOpt, varOpt, varOpt);
    
    		std::cout << pPstStore->GetName() << std::endl;
    
    		hr = pSession->Logoff();
    	} catch (std::exception *e) {
    		printf("exception: \n", e->what());
    	}
    
    	system("PAUSE");
    	return 0;
    }
    

    Damit lässt sich sicherlich erstmal weit mehr anfangen, als mit prosaischen Erzählungen.

    Noch ein Wort an Martin Richter: Wie du annehmen kannst, dass jemand ganz allein von deiner Gunst abhängig sein könnte, zeugt entweder vom Intellekt der Menschen in deinem Umfeld, oder von deiner eigenen Eitelkeit. Ich jedenfalls bin ein frei denkender Mensch, und mit Sicherheit weder von dir, noch von sonst jemandem abhängig. Und wenn ich es etwas will, dann setze ich es durch, und das umso lieber je stärker sich mir Widerstände in den Weg stellen!

    In diesem Sinne: Adieu!



  • Was mir gerade so auffällt (und ohne Garantie): Der vorletzte Parameter von CoCreateInstance() gibt afaik an, welches Interface du eigentlich benötigst. Dort verlangst du nur IUnknown-Objekte, also hat die DLL vermutlich keine Ahnung, daß du da eigentlich etwas benötigst, was die IRDOSession bzw. IRDOPstStore Interfaces unterstützt.
    (edit: Bei deinem letzten Beispiel hast du ja auch mit _uuidof() die richtige ID geholt)

    IceRage schrieb:

    Noch ein Wort an Martin Richter: Wie du annehmen kannst, dass jemand ganz allein von deiner Gunst abhängig sein könnte, zeugt entweder vom Intellekt der Menschen in deinem Umfeld, oder von deiner eigenen Eitelkeit. Ich jedenfalls bin ein frei denkender Mensch, und mit Sicherheit weder von dir, noch von sonst jemandem abhängig. Und wenn ich es etwas will, dann setze ich es durch, und das umso lieber je stärker sich mir Widerstände in den Weg stellen!

    Ich bin zwar nicht Martin, aber das hat nichts mit "Gunst" zu tun. Du kommst hierher und stellst eine Frage, also können wir auch nur auf das reagieren, was du hier als Informationen mitgibst. Da machen wohl die wenigsten von uns irgendwelche impliziten Annahmen, was du noch unausgesprochen gelassen hast, sondern nehmen die vorhandenen Informationen als Ausgangspunkt der Fehlersuche.
    (wenn es ganz schlimm wird, wird hier regelmäßig das Wort mit K erwähnt - Kristallkugel)


Anmelden zum Antworten