DLL für COM verfügbar machen?!?

23/10/2007 - 13:29 von D.Follmann | Report spam
Hallo.
Ich habe ein Problem mit Com-Interoperation:
Ein COM-Client sucht in der Registry nach einer DLL, die bestimmte
Kategorien (GUID) implementiert. Soll heissen in der Registry sollen unter
HKCR/CLSID/(meineGUID)/Implemented Categories/
die Schlüssel mit den bestimmten GUID's eingetragen sein.
Die DLL soll eine Methode bool methodenName() enthalten, die von dem
COMClient aufgerufen werden kann und ihm einen bool-Wert zurückgibt.
in .../InprocServer32/ soll die Zeichenfolge "TheadingModel" mit dem Wert
"Apartment" stehen, wobei ich nicht genau weiss,was das bedeutet aber er muss
da sein, das weiss ich. Und die "default"-Zeichenfolge in InprocServer32 soll
den Pfad auf die dll selbst enthalten und nicht "mscoree.dll" oder so (das
hatte ich da bisher immer komischerweise)
Naja und wichtig ist halt, dass das ganze COM-Sichtbar ist wie gesagt.
Wàre klasse, wenn mir da jemand helfen könnte!
Vielen Dank im voraus!

MfG
Dominik
 

Lesen sie die antworten

#1 Günter Prossliner
23/10/2007 - 16:46 | Warnen spam
Hallo Dominik!

Ein COM-Client sucht in der Registry nach einer DLL, die bestimmte
Kategorien (GUID) implementiert. Soll heissen in der Registry sollen
unter HKCR/CLSID/(meineGUID)/Implemented Categories/
die Schlüssel mit den bestimmten GUID's eingetragen sein.



Leider gibt es in .NET kein Attribut, welches regasm anweist, die
"Implemented Categories" auf selbst definierte Werte zu setzen.

Allerdings gibt es die Möglichkeit mittels eines Attributs bei der
Registrierung bzw. Deregistrierung eigenen Code auszuführen.

z.B.:

class MyType {

[ComRegisterFunction]
static ComRegisterCallback(Type type){
RegisterImplementedCategory(type, ...);
}

static void RegisterImplementedCategory(Type type, Guid categoryGuid) {
string guidRegFormat = type.Guid.ToString("P");
using(RegistryKey clsKey =
Registry.ClassesRoot.OpenSubKey("CLSID\\"+guidRegFormat, true)){
Debug.Assert(clsKey != null);
using(RegistryKey catsKey = clsKey.CreateSubKey("Implemented
Categories")){
using(RegistryKey catKey =
catskey.CreateSubKey(categoryGuid.ToString("P"))){ }
}
}
}

}


[ComRegisterFunctionAttribute-Klasse (System.Runtime.InteropServices)]
http://msdn2.microsoft.com/de-de/li...nattribute(VS.80).aspx


[ComUnregisterFunctionAttribute-Klasse (System.Runtime.InteropServices)]
http://msdn2.microsoft.com/de-de/li...nattribute(VS.80).aspx


Die DLL soll eine Methode bool methodenName() enthalten, die von dem
COMClient aufgerufen werden kann und ihm einen bool-Wert zurückgibt.



Die "DLL" kann keine Methode besitzen. Du meinst warscheinlich die Klasse.

Ist diese Methode in einem COM-Interface definiert, welches Du
implementieren musst, oder wird diese Methode late-bound (also über den
Namen) aufgerufen?

Im ersten Fall musst Du das COM-Interface importieren. Das geht (meist) über
das tlbimp.exe Tool. Für einzelne bzw. einfache Interfaces kannst Du auch
selbst attributieren.

in .../InprocServer32/ soll die Zeichenfolge "TheadingModel" mit dem
Wert "Apartment" stehen, wobei ich nicht genau weiss,was das bedeutet



Das gibt das unterstützte Threading-Model an.

aber er muss da sein, das weiss ich.


.NET Komponenten verwenden default-màßig als Threading-Model "Both". Sollte
also ohne weiteres Zutun funktionieren (wenn der COM-Client richtig
implementiert ist).

Und die "default"-Zeichenfolge
in InprocServer32 soll den Pfad auf die dll selbst enthalten und
nicht "mscoree.dll" oder so (das hatte ich da bisher immer
komischerweise)



Nein.

.NET Komponten welche über COM aufrufbar sind, enthalten immer "mscoree.dll"
als InprocServer32. Diese dll ist der Default CLR Host. Das ist aber auch ok
so.

Der Ablauf ist nàmlich:
* Der COM-Client macht ein CreateObject auf eine bestimmte CLSID
* mscoree.dll wird inproc geladen.
* mscoree überprüft ob die (bzw. eine) CLR bereits im Prozess geladen ist,
und làd bzw. initalisiert die (default) CLR im Client-Prozess.
* mscoree liesst die weiteren (.NET spezifischen) Registrierungs-Attribute
(vor allem "Assembly" und "Class") aus der Registry aus
* mscoree erstellt die managed Klasse und den CCW (automatisch generierter
Wrapper).
* Der COM-Client bekommt eine Referenz auf den CCW zurück, welcher sich wie
ein "normales" COM-Objekt / Interface verhàlt. Dieser betreibt auch das
Marschalling von Argumenten und Return-Values bei Methodenaufrufen.

Fazit: Für den COM-Client ist es unerheblich, ob nun "mscoree.dll" drinnen
steht oder was anderes. Dieser sollte normalerweise einfach ein
CoCreateInstance absetzen, und mit dem zurückgegeben IUnkown arbeiten.
Sollte das nicht der Fall sein (was ich nicht glaube), ist der COM-Client
nicht spzifikationskonform implementiert.

Naja und wichtig ist halt, dass das ganze COM-Sichtbar ist wie gesagt.



Hast Du Dir mal in der MSDN zum Thema COM-Interop schlau gemacht?

[COM Interop Part 2: C# Server Tutorial (C#)]
http://msdn2.microsoft.com/en-us/library/aa645738(VS.71).aspx

[Exposing .NET Framework Components to COM]
http://msdn2.microsoft.com/en-us/li...ww439.aspx

[Advanced COM Interoperability]
http://msdn2.microsoft.com/en-us/li...cdfyx.aspx


OK?
mfg GP

Ähnliche fragen