Laden...

COM Interopt verhindert das schließen von Host Anwendung [COM]

Erstellt von LastGentleman vor 14 Jahren Letzter Beitrag vor 14 Jahren 3.664 Views
LastGentleman Themenstarter:in
1.274 Beiträge seit 2005
vor 14 Jahren
COM Interopt verhindert das schließen von Host Anwendung [COM]

Hallo Community,

ich hab eine DOT.NET DLL im Einsatz die ich in Microsoft Access über Latebinding verwende. Leider verhindert die Verwendung von den DLLs das Access beendet werden kann. Wenn ich Access zu mache, kommt kurz der Desktop und dann ist mein graues Access Fenster wieder da.

Hat jemand eine Idee woher dieses Verhalten kommt.

Liebe Grüße
LastGentleman

"Das Problem kennen ist wichtiger, als die Lösung zu finden, denn die genaue Darstellung des Problems führt automatisch zur richtigen Lösung." Albert Einstein

3.728 Beiträge seit 2005
vor 14 Jahren
Verweise

Hallo LastGentleman,

übergibst Du während der Laufzeit Access-Objekte als Parameter an Methoden der eingebundenen .NET-Assembly?
Falls ja, wird Access nicht beendet, weil noch Verweise darauf existieren (COM-Objekte können erst zerstört werden, wenn der letzte Verweis gefallen ist). COM-Objekt innerhalb von .NET-Code auf null zu setzen, genügt nicht. Der COM-Verweis lebt solange weiter, bis er vom Müllsammler abgeräumt wird. Du musst immer Marshal.ReleaseComObject verwenden, um den COM-Verweis unter der Haube freizugeben.

LastGentleman Themenstarter:in
1.274 Beiträge seit 2005
vor 14 Jahren

Danke Rainbird für die Information.

Im Prinzip geben ich keine Access Objekte als Parameter. Nur eigene COMVisible, Dot.net Objekte.

Muss dann jede Funktion die Objekte wieder freigeben?

"Das Problem kennen ist wichtiger, als die Lösung zu finden, denn die genaue Darstellung des Problems führt automatisch zur richtigen Lösung." Albert Einstein

LastGentleman Themenstarter:in
1.274 Beiträge seit 2005
vor 14 Jahren

Hab noch was rausgefunden, ich erzeuge über Activator.CreateInstance Objekte und gebe die an die COM Schnittstelle zurück. Ich vermute es liegt daran.

Hab versucht das ganze mal in einer AppDomain laufen lassen.

Nur bekomme ich da eine Exception zurück. Diese Fall tritt aber nur da auf, wo der Prozess der das COM Objekt verwendet, eine C# Konsolenanwendung macht da keine Probleme.

Exception Meldung
Es ist der Fehler Der transparente Proxy kann nicht in den Typ "AddinLoader.IRemoteLoader" umgewandelt werden.

"Das Problem kennen ist wichtiger, als die Lösung zu finden, denn die genaue Darstellung des Problems führt automatisch zur richtigen Lösung." Albert Einstein

3.728 Beiträge seit 2005
vor 14 Jahren
Was machst Du genau?

Was willst Du denn genau erreichen?

Es hört sich so an, als ob Du .NET-Module in eine Access-Lösung integrieren willst, oder liege ich da falsch? Falls ja, könnte ich Dir bestimmt weiterhelfen. Ich habe hier gerade auch eine große ERP Lösung am laufen, die halb Access 2003 und halb .NET 2.0 ist. Mittlerweile läuft auch die Windows.Forms-Integration stabil (und zwar als MDI-Child und nicht mit ShowDialog). Nur falls Dein Projekt in eine ähnliche Richtung geht.

Wenn ich genau weiß, was Du machen willst, kann ich Dir eher helfen.

3.728 Beiträge seit 2005
vor 14 Jahren

Habe die Diskussion über Sage in einen speraten Thread abgetrennt, da es mit der eigentlichen Frage nur indirekt etwas zu hatte.
Hier der Sage-Thread: ){orange} .NET-Integration in Access-ERP-Lösung (Sage?)

LastGentleman Themenstarter:in
1.274 Beiträge seit 2005
vor 14 Jahren

Hallo Rainbird,

genau baue mir einen Moniker den ich Parameter wie Assembly Dateiname und die erzeugende Klasse übergebe und dann eine Dot.net Objekt zurückgebe.
Möchte genau wie du halb gleisig fahren. Das mit der Objekterzeugung läuft soweit auch gut, nur leider will das Access nicht mehr zugehen. Beim Beenden flakert es kurz auf und dann ist das Access wieder da.

Bin beeindruckt die Forms integration hab ich mir mal kurz angesehen bin aber kläglich gescheitert. Das war so ein SetParent() API Versuch. Dem werde ich mich wieder mal widmen.

"Das Problem kennen ist wichtiger, als die Lösung zu finden, denn die genaue Darstellung des Problems führt automatisch zur richtigen Lösung." Albert Einstein

LastGentleman Themenstarter:in
1.274 Beiträge seit 2005
vor 14 Jahren

Hallo zusammen,

So hab jetzt wieder Zeit mir die Integration von DOT.NET Formulare in Access zu widmen.
Komme da nur nicht so ganz weiter. Ne Variante mit SetParent API ist nicht das ware das hab ich schon festgestellt.
Weis nur nicht so ganz wie ich das anstellen sollte. Der Aufbau vom Access (Forms 2.0), ist doch sehr unterschiedlich von System.Windows.Forms.

Wie bekomme ich die zwei Systeme zusammen?

Für Tipps bin ich dankbar,

Liebe Grüße
LastGentleman

"Das Problem kennen ist wichtiger, als die Lösung zu finden, denn die genaue Darstellung des Problems führt automatisch zur richtigen Lösung." Albert Einstein

3.728 Beiträge seit 2005
vor 14 Jahren
WinForms in Access laufen lassen

Hallo LastGentleman,

EDIT: Ich habe gerade herausgefunden, dass es noch viel einfacher geht. Und zwar mit dem Interop Forms Toolkit von Microsoft (kostenlos zum runterladen unter http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=934de3c5-dc85-4065-9327-96801e57b81d)
Allerdings funktioniert dieses Toolkit nur mit VB.NET und nicht mit C# X(. Deshalb habe ich mich nie näher damit beschäftigt. Aber da man ja grundsätzlich nur ein Host-Control braucht, kann man das auch mal in VB.NET schreiben.

das Problem ist, dass die Window Message Loop von Access nicht mit der von Windows.Forms-Formularen kompatibel ist. Deshalb kann man Windows.Forms-Formulare nicht direkt in Access laufen lassen.
Aber man kann ActiveX-Steuerelemente auf Access-Formularen verwenden. Mit .NET kann man Windows.Forms-Steuerelemente über viel zusätzliche Handarbeit zumindest soweit hinbekommen, dass sie als ActiveX-Steuerelemente im Internet Explorer oder auf VB6-Formularen laufen. Unter Access funktioniert aber auch das nicht. Ich hatte es mal soweit, dass ich ein Windows.Forms-UserControl auf einem Access-Formulare platzieren und einen Button darauf anklicken konnte, aber die Größe konnte nach dem Platzieren nicht mehr angepasst werden (auch mit Code nicht). Außerdem haben ToolStrips nicht auf Mausklicks reagiert und die Hälfte alle Sondertasten (Entf., Backspace, Ctl + C, ...) hat einfach nicht reagiert. Also nicht einsetzbar.

Die gebastelten .NET ActiveX-Steuerelemente funktionieren aber einwandfrei in VB6. Und mit VB6 erstellte ActiveX-Steuerelemente funktionieren einwandfrei in Access. Wenn man nun in VB6 ein ActiveX-Steuerelement schreibt, welches ein .NET ActiveX-Steuerelement hostet, kann dieses wiederum Windows.Forms-Formulare hosten, bei denen die Eigenschaft TopLevel auf false gesetzt wurde. Man braucht also folgende Zutaten:*1 Access-Formular (Multi-Instanz fähig) zum Hosten des VB6-Brücken-ActiveX-Controls *1 in VB6 geschriebenes Brücken-ActiveX-Control zum bereitstellen einer kompatiblen Message Loop innerhalb eines Access-Fensters *1 .NET Brücken ActiveX-Control welches auf dem VB6 Brücken-Control platziert wird *Und noch ein bsichen Infrastruktur-Code auf Access- und auf .NET Seite

Am Ende hat man dann im Access ein .NET-Hosting Formular, welches .NET Windows.Forms-Formulare anzeigen und vernünfig ausführen kann. Wenn man alles gut kapselt, könnte folgender Access-VBA-Code genügen, um ein .NET Formular innerhalb von Access zu starten:


' Host-Formular-Instanz erzeugen
Dim objHost As Form_DotNetHostForm
Set objHost=New Form_DotNetHostForm

' .NET Formular laden und anzeigen
objHost.LoadDotNetForm "SomeAssembly.dll","MyNamespace.MyDotNetForm"

' Methode LoadCustomer des .NET Formulars aufrufen, um den Kunden mit ID 129 zu laden und anzuzeigen
objHost.ExecuteDotNetMethod "LoadCustomer", 129

' Access-Formular mit eingebettetem .NET-Formular anzeigen
objHost.Visible=true

Wenn man einmal eine oder zwei Wochen für die Integrations-Infrastruktur investiert, kann man das so hinkriegen. Ich spreche aus Erfahrung.