Benutzer mit den meisten Antworten
MDB Brücke 32 Bit 64 Bit

Frage
-
Hallo , das Problem ist schon alt aber fällt mir wieder auf die Füße, wir haben etliche Projekte die Access-MDB's zur Datenspeicherung nutzen, alles MFC VC++ Windows Anwendungen, einige davon würden von einer 64 Bit Umstellung profitieren, da gibt's aber kein DAO MDB Zugriff mehr. Um meine Kollegen zu unterstützen wollte ich jetzt was schreiben was Ihren Aufwand der 64 Bit Umstellung in der Hinsicht minimiert. Es sind ja nur eine Handvoll Funktionen die genutzt werden und nach längeren Recherchen im Netz fand ich die Idee eine "DaoProxies" in 32 Bit geschrieben nicht schlecht. Auf der 64 Bit Seite würde ich eine CDaoDatabase definieren die den Open Call an den Proxy weiterleitet. Ich habe für den Proxy einen simplen RPC Server geschrieben, zum einfachen Test gibt's da eine CDaoDatabase Objekt das mit einem RPC Call geöffnet wird und mit einem weiteren geschlossen, jetzt merke ich aber das RPC für jeden Call einen neuen Thread aufmacht, ist vielleicht auch logisch aber so kann ich DAO ja auch auf 32 Bit nicht benutzen :-( . Meine Frage ist ob jemand noch einen anderen Vorschlag als RPC für einen DaoProxy hat der eine Brücke zwischen 64 Bit und 32 Bit schlägt?
Freudi
Antworten
-
Hallo
Eine Komponente ist für ein bestimmtes Threading-Model gebaut. Wenn die Komponente also nur für "Apartment" gebaut ist, dann kann sie nicht im Multi-Threading-Model laufen (CoInitialize mit NULL als Parameter baut ein STA, also Single Threaded Apartment auf, während du mit dem anderen Aufruf ein MTA also Multi Threaded Apartment baust). Ich tippe also drauf, dass die Komponente so nicht läuft und daher nicht instanziert werden kann.
Übrigens: ein Threading-Model ist pro Thread festgelegt. Du könntest also einen Thread bauen, das als STA initialisieren und dann alle Aufrufe über ihn umlenken. Wobei ich glaube, dass du dann am Ende zwei Nachrichtenschleifen ineinander hättest, da ein STA soweit ich weiss alles per Nachrichtenschleife synchronisiert.
Ah richtig... :-) da gibt's ja noch was von Microsoft dazu: https://msdn.microsoft.com/en-us/library/ms678517(VS.85).aspx ... du musst die Schnittstelle von STA nach MTA marshallen lassen. Der baut dann einen Proxy, damit der MTA-Teil das STA-Teil nutzen kann. Das wär dann der korrekte Weg es zu tun.
Rudolf
- Bearbeitet Rudolf Meier Freitag, 15. Juli 2016 17:04
- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Dienstag, 19. Juli 2016 06:14
- Als Antwort markiert Freudi Dienstag, 19. Juli 2016 07:51
Alle Antworten
-
Hallo
Von 64 nach 32 bit kommst du relativ einfach mit COM. Da kannst du aus einem 64 bit Programm 32 bit Komponenten aufrufen. Diese müssen nur in einem anderen Prozess laufen (CLSCTX_LOCAL_SERVER). Natürlich muss dazu die Schnittstelle fähig sein. Aber wenn du Glück hast, kannst du sogar die bestehenden Teile direkt so ansteuern. Sonst müsstest du halt 'n Wrapper drum bauen. Andere RPC Techniken gingen auch... wobei mir im Moment gerade keine einfache einfällt, die öffentlich verfügbar wäre.
Rudolf
- Bearbeitet Rudolf Meier Freitag, 8. Juli 2016 18:26
-
Hallo Rudolf
Wenn das so ist warum kann man nicht die MFC Sourcen von DAO einfach mal auf 64 Bit kompilieren, ich denke das JET was die ansprechen wird auch ein COM Modul sein, müsste man mal schauen ob man das hinbekommt das als CLSTX_LOCAL_SERVER anzusprechen, ich staune nur das niemand auf die Idee gekommen sein soll, alle ärgern sich nur das sie mit 64 Bit keine MDB's mehr aufmachen können.
Freudi
Freudi
-
Hallo
Das ist die erste gute Frage und die zweite wäre: *.accdb kann ich mit dem 64bit OLEDB Treiber von der Access Runtime öffnen. Und angeblich unterstützt diese auch *.mdb ... daher frag ich mich gerade, ob das nicht einfach damit geöffnet werden könnte? Also einfach statt den JET, Access nutzen.
Hier die zwei GUIDS, einmal die vom JET und einmal die von Access, die ich jeweils nutze (bzw. genutzt habe... ich verwende so gut wie kein SQL mehr).
const CLSID_DB_CLSID_MSACCESS = {0x3be786a0L, 0x0366, 0x4f5c, {0x94, 0x34, 0x25, 0xcf, 0x16, 0x2e, 0x47, 0x5e}};
const CLSID_DB_CLSID_MSJETDB = {0xdee35070L, 0x506b, 0x11cf, {0xb1, 0xaa, 0x00, 0xaa, 0x00, 0xb8, 0xde, 0x95}};Ausprobiert habe ich es nicht... könnte ich aber mal tun. :-) ... vielleicht am Wochenende, wenn nicht wieder unvorhergesehenes dazwischen kommt.
Rudolf
-
Hallo Freudi,
Jet / DAO gibt es nur als 32-Bit Komponente. Erst für Office/Access 2010 hat man eine 64-Bit Version entwickelt. Die geht aber nicht mehr als DAO durch sondern als Access Runtime durch, die es auch je Office Version separat als Download gibt
Dabei ist das größte Problem, dass nur die passende zur Office Version installiert sein darf, parallel 32 / 64 Bit geht nicht ;( Siehe Choose the 64-bit or 32-bit version of Office 2016 (entsprechend auch für 2010/2013).
Vom Design kann man .NET nachahmen, das einen Connection Pool verwendet, um Verbindungen länger vorzuhalten - was einen Vorteil bringen kann, da u. U. das Öffnen einer MDB (+ .LDB) länger dauern kann als die ganze Abfrage.
Gruß Elmar
-
Es gibt dazu aber Workarounds... https://knowledge.autodesk.com/support/autocad-civil-3d/troubleshooting/caas/sfdcarticles/sfdcarticles/How-to-install-64-bit-Microsoft-Database-Drivers-alongside-32-bit-Microsoft-Office.html
Ich weiss nicht, welche Probleme daraus entstehen könnten.
Rudolf
-
Hallo Rudolf,
zum einen installieren viele 32 Bit auf Windows 64 Bit, Gründe siehe Artikel (oder alte Gewohnheit ;).
Zum anderen sind solche "Workarounds" immer problematisch, denn beim nächsten Update/Reparatur korrigiert Office solche Dinge gerne hinten rum (was es darf, da gemischte Installation nicht unterstützt werden).
Was genervte Anrufe beim Help Desk produziert...
Gruß Elmar
-
Genau das kann ich bestätigen, es läuft immer solange bis man einmal WORD o.ä. startet dann geht's wieder nicht mehr, wobei ich den Registry Trick von Rudolf noch nicht ausprobiert habe. Mit diesem Accesstreiber kann man dann mit ODBC arbeiten aber DAO meldet weiterhin
fatal error C1189: #error : DAO Database classes are not supported for Win64 platforms
D.h. auch für den Accesstreiber müsste ich etwas schreiben was die ODBC Dataclassen auf CDaoDatabase mappt.
Wenn das JET Modul aber nun ein COM Modul ist, vielleicht muss man in DAO/MFC Klassen nur etwas patchen so das die JET Engine als CLSTX_LOCAL_SERVER ausgeführt wird, dann könnte ich mir sparen selber ein COM Server zu schreiben.
Freudi
-
Zum anderen sind solche "Workarounds" immer problematisch, denn beim nächsten Update/Reparatur ...
Ja, das ist mir klar. Im Grunde ist das mit allen Produkten so, die man "einkauft". Plöztlich heisst es "wir haben beschlossen, dass wir jetzt allen den Teppich unter den Füssen wegziehen... ihr könnt nun selber schauen wo ihr bleibt, das Produkt wird eingestampft" (oder so ähnlich) ... deshalb verwende ich weder Access, noch SQL. Bei vielen Programmen, welche eine "Datenbank" benötigen habe ich gemerkt, dass die Daten oft nur 0-5 MB gross sind. Da lade ich den Mist einfach vollständig ins Memory und schreib das Zeug ab und zu wieder runter. Das ist nicht weniger effizient und oft viel einfacher zu bauen. Und für grössere Sachen... ja gut, das kann nicht jeder... da haben wir in der Firma unseren eigenen DB-Server geschrieben :-) ... aber bei kleinerem bin ich ziemlich gut gefahren mit der Strategie. Genau wegen Access-Zeug hab ich damit angefangen... das war so nervig. Und am Ende war's ja dann immer "meine" bzw. "unsere" Software, die schlecht ankam beim Kunden.
Rudolf
-
Hallo Rudolf,
wenn man nur ein Datenkrümel hat, gehts auch ohne SQL Datenbank.
Aber es gibt massig Anwendungen die ein wenig bis sehr viel mehr brauchen.
Für kleinere Anwendungen bleibt Access, wenn auch von Microsoft in den letzten nicht anständig weiterentwickelt, eine Lösung. Und wird es größer gibt es wenig Alternativen[1] zu einem SQL Server (nicht unbedingt Microsoft).
Als ehedem Access wie SQL Server MVP mag ich aber etwas vorbelastet sein ;)
Gruß Elmar
[1] außer vielleicht NoSQL Datenbanken, wenns passt.
-
Bei den neueren Projekten nehmen wir immer SQLite. Da kann man mittels :MEMORY: auch Datenbanken im Speicher bauen und später abspeichern oder auch in den Speicher laden, das hat mir einem Projekt sehr geholfen wo viele kleine Kataloge existierten, das geht jetzt enorm schnell.
Das Problem ist das wir größere, lange gewachsene Projekte mit Access haben, wo beim Kunden weitere Prozesse dort Access erwarten, da haben wir also mal die falsche Entscheidung getroffen. Jetzt ist es bei einigen Projekten dort angezeigt auf 64 Bit zu wechseln, mir bleibt also nichts anders übrig als Lösung zu finden. :-(
Freudi
-
Ja, das Problem ist von der blöderen Sorte ... kenne ich. Umbauen ist manchmal keine Option ... obwohl man's prüfen muss. Aber in dem Fall ist wohl die Idee mit dem MFC-Klassen-Umbau oder halt eine weitere COM-Wrapper-Zwischenschicht die beste oder einzige Lösung.
Aber noch schnell was zum "Access erwarten" ... ich hatte das bei einem Projekt so gelöst, dass ich alles auf eine neue Lösung (in dem Fall war's ein SQL-Server Express) umgebaut und die Daten konvertiert hatte und den Zugriff dann für die alten Programme über eine neue MDB/ACCDB mit "externen Daten" eingerichtet hatte. Irgendwie kann man ja im Access externe DBs wie interne Tabellen verlinken.... wobei, das ist schon sehr lange her. So im Detail kenne ich das nicht mehr.
Rudolf
-
Ich halte Euch mal auf den Laufenden ... Ich habe mir die 3 Dao Sourcen aus der MFC Source geholt und in mein 64 Bit Programm eingebunden, das kann man übersetzen, dann kommt er zu der Stelle wo er via COM die Jet Engine startet, da muss dann erst mal der passende "Jet-COM-Key" für 64 Bit auch angelegt werden damizt er die JET Engine findet, aber es klappt auf diesem Weg dann trotzdem nicht weil die JET Engine wohl nur als InProc Server vorliegt und damit der 32-64 Bit Konflikt vorliegt. Oder gibt's die JET Engine auch irgendwo als EXE ?
Freudi
-
Nein, du brauchst eine EXE dazu. Aber da gibt's eine Standard-Exe im Windows drin für sowas... soweit ich weiss. Benutzt habe ich das so aber noch nie... http://thrysoee.dk/InsideCOM+/ch12b.htm
Rudolf
-
Das hat geklappt man kann die JET Engine damit aus 64 Bit heraus ansprechen. Allerdings scheint die Surrogate EXE (DllHost.exe) wohl nur UNICODE zu können, jedenfalls geht alles Bestens wenn ich mein 64 Bit Programm als UNICODE übersetze aber die meisten alte Programme die wir haben sind nicht UNICODE. Hat jemandvielleicht nich en Tipp ob es DllHost.exe auch als nicht UNICODE oder Source irgendwo gibt ?
Freudi
-
Hmm also diese beiden Zeilen (siehe Code) starten die Engine. Die letzte Zeile. geht schief wenn ich nicht UNICODE bin.
Diese Notation mit L war schon von mir weil ich dachte da muss UNICODE stehen. Im Original steht da V_BSTR(&varkey)
COleVariant varKey = _T("mbmabptebkjcdlgtjmskjwtsdhjbmkmwtrak"); LPCLASSFACTORY2 pCF2; DAO_CHECK_ERROR(::CoGetClassObject(CLSID_CDAODBEngine,CLSCTX_LOCAL_SERVER, NULL, IID_IClassFactory2, (LPVOID*)&pCF2),AFX_DAO_ERROR_ENGINE_INITIALIZATION); DAO_CHECK_ERROR(pCF2->CreateInstanceLic(NULL, NULL, guidEngine, L"mbmabptebkjcdlgtjmskjwtsdhjbmkmwtrak", (LPVOID*)&pDaoState->m_pDAODBEngine), AFX_DAO_ERROR_ENGINE_INITIALIZATION);
Aber auch so wie es jetzt da steht funktioniert es wenn ich UNICODE definieren, aber der DAOCHECK wirft ein Error wenn es nicht UNICODE ist.
Freudi
-
*hmm* ... nun, also ein BSTR müsste es schon sein. Weil das wird ja verlangt. Bei nur L".." fehlt dir im Speicher die Länge vom String (steht vorne am String). Ich würde auch kein COleVariant machen, sondern direkt ein BSTR mit SysAllocString (später löschen mit SysFreeString) ... was passiert dann?
Rudolf
-
Ja mache ich die genauen Schritte kommen später nochmal, es ist auch noch das Stadium das ich probiere und nicht genau weiß was jetzt wirklich nötig war und was überflüssig.
Im groben ...
mit regsrv32 (in system32 !!! wegen 64 Bit) dao360.dll registrieren.
3 DAO Src/Incl aus den MFC Quellen ins Projekt holen
in den DAO Quellen dafür sorgen das auch bei 64 Bit alles übersetzt wird.
Den Aufruf der JET Engine auf Out Procserver umstellen
Mit OleView.exe den DllHost.exe als surrogate einstellen.
Im Moment geht's aber nur für die UNICODE CLSID, die Interface dbEngine hat 2 CLSID's eine für Unicode, eine für nicht UNICODE. Nur die UNICODE funktioniert wobei seltsamerweise die CLSID für Nichtunicode in der ganzen Registry gar nicht zu finden, aber an dem Thema bin ich gerade dran , hab da ein altes Buch mit einem Beispiel DllNanny das ist ein Custom Surrogate, damit schaffe ich das morgen bestimmt, heute ist keine Zeit mehr.
Freudi
-
Mit dem Unicode habe ich ein seltsames Problem, die CLSID für die Nicht Unicode Version ist
{00000020-0000-0010-8000-00AA006D2EA4}
die ist in der ganzen Registry nicht zu finden. Initialisiere ich die COM Lib mit CoInitialize(NULL) findet er aber das Interface. Initialisiere ich aber mit CoInitializeEx(NULL, COINIT_MULTITHREADED) wie ich es in einem Surrogate Host auch machen muss dann findet er das Interface nicht.
Hat da jemand vielleicht einen Tipp?
Freudi
-
Hallo
Eine Komponente ist für ein bestimmtes Threading-Model gebaut. Wenn die Komponente also nur für "Apartment" gebaut ist, dann kann sie nicht im Multi-Threading-Model laufen (CoInitialize mit NULL als Parameter baut ein STA, also Single Threaded Apartment auf, während du mit dem anderen Aufruf ein MTA also Multi Threaded Apartment baust). Ich tippe also drauf, dass die Komponente so nicht läuft und daher nicht instanziert werden kann.
Übrigens: ein Threading-Model ist pro Thread festgelegt. Du könntest also einen Thread bauen, das als STA initialisieren und dann alle Aufrufe über ihn umlenken. Wobei ich glaube, dass du dann am Ende zwei Nachrichtenschleifen ineinander hättest, da ein STA soweit ich weiss alles per Nachrichtenschleife synchronisiert.
Ah richtig... :-) da gibt's ja noch was von Microsoft dazu: https://msdn.microsoft.com/en-us/library/ms678517(VS.85).aspx ... du musst die Schnittstelle von STA nach MTA marshallen lassen. Der baut dann einen Proxy, damit der MTA-Teil das STA-Teil nutzen kann. Das wär dann der korrekte Weg es zu tun.
Rudolf
- Bearbeitet Rudolf Meier Freitag, 15. Juli 2016 17:04
- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Dienstag, 19. Juli 2016 06:14
- Als Antwort markiert Freudi Dienstag, 19. Juli 2016 07:51
-
Danke für die fundierte Auskunft, manches wusste ich, manches habe ich nur geahnt, aber es kam mir halt komisch vor, wir reden immerhin von nur genau einer dao360.dll und innerhalb der gibt es für Unicode ein MTA Interface und für nicht UNICODE ein STA, das hat aber wahrscheinlich gar nichts mit Unicode zu tun sondern das eine Interface ist wahrscheinlich viel früher entstanden als das andere und dann haben sie beides in eine DLL gepackt.
Freudi
-
Auf einer frischen Maschine habe ich gerade gemerkt das das mit dem regsrv32 nicht klappt, die 64 Bit Version ruft automatisch die 32 Bit Version von regserv32 auf :-( Also hier noch mal die Registry Einträge die nötig sind.
Natürlich muss da der richtige Pfad der Surrogate rein, den Quelltext kann jeder haben, einfach Nachricht an mich oder hier im Forum.
Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\AppID\{00000100-0000-0010-8000-00AA006D2EA4}] @=hex(2):44,00,41,00,4f,00,2e,00,44,00,42,00,45,00,6e,00,67,00,69,00,6e,00,65,\ 00,2e,00,33,00,36,00,00,00 "DllSurrogate"="E:\\Development\\MSVC12\\dllnanny\\Debug\\dllnanny.exe" [HKEY_CLASSES_ROOT\Wow6432Node\AppID\{00000100-0000-0010-8000-00AA006D2EA4}] @=hex(2):44,00,41,00,4f,00,2e,00,44,00,42,00,45,00,6e,00,67,00,69,00,6e,00,65,\ 00,2e,00,33,00,36,00,00,00 "DllSurrogate"="E:\\Development\\MSVC12\\dllnanny\\Debug\\dllnanny.exe" [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID\{00000100-0000-0010-8000-00AA006D2EA4}] @=hex(2):44,00,41,00,4f,00,2e,00,44,00,42,00,45,00,6e,00,67,00,69,00,6e,00,65,\ 00,2e,00,33,00,36,00,00,00 "DllSurrogate"="E:\\Development\\MSVC12\\dllnanny\\Debug\\dllnanny.exe" [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\WOW6432Node\AppID\{00000100-0000-0010-8000-00AA006D2EA4}] @=hex(2):44,00,41,00,4f,00,2e,00,44,00,42,00,45,00,6e,00,67,00,69,00,6e,00,65,\ 00,2e,00,33,00,36,00,00,00 "DllSurrogate"="E:\\Development\\MSVC12\\dllnanny\\Debug\\dllnanny.exe" [HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Classes\AppID\{00000100-0000-0010-8000-00AA006D2EA4}] @=hex(2):44,00,41,00,4f,00,2e,00,44,00,42,00,45,00,6e,00,67,00,69,00,6e,00,65,\ 00,2e,00,33,00,36,00,00,00 "DllSurrogate"="E:\\Development\\MSVC12\\dllnanny\\Debug\\dllnanny.exe"
Freudi