Laden...

ein in .NET erstelltes Assembly für COM zur Verfügung stellen

Erstellt von Cordoba vor 18 Jahren Letzter Beitrag vor 18 Jahren 7.612 Views
C
Cordoba Themenstarter:in
54 Beiträge seit 2005
vor 18 Jahren
ein in .NET erstelltes Assembly für COM zur Verfügung stellen

Hallo ihr Auskenner,

ich habe mir eine Klasse in .net erstellt (Sie realisiert RPC).
Diese Klasse/Assembly möchte ich in einer COM-basierten Anwendung (Microsoft Axapta kann leider nix anderes 🙁 ) verwenden.

Ich habe dazu die MSDN bemüht und alle Schritte unter "Verpacken einer Assembly für COM" ausgeführt -> ich konnte die entsprechende DLL in VB.6 nicht verweisen. VB.6 verwende ich nur hier zu Testzwecken, damit ich später das gleiche in Axapta machen kann.

Kann mir jemand einen Tip geben?
Wäre sehr dankbar.

Cordoba

4.221 Beiträge seit 2005
vor 18 Jahren
  • Hast Du eine CLSID vergeben ?

  • Hast Du in den Projekteinstellungen "für COM Interop registrieren" auf True gestellt ?

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

1.274 Beiträge seit 2005
vor 18 Jahren

wo vergibt man ein CLSID

"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

4.221 Beiträge seit 2005
vor 18 Jahren

Direkt auf der Klasse die man über Com rausstellen will




namespace XYCodeWriter
{
	[Guid("12346410-B1F6-4d84-A119-2FD641E00307")]
	public class DeineKlasse

Die Guid musste halt selber generieren.

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

C
Cordoba Themenstarter:in
54 Beiträge seit 2005
vor 18 Jahren

Also ich habe auf die Tips hin nochmal probiert:
->in den Projekteinstellungen "für COM Interop registrieren" auf True gestellt

der Code in meiner Ausgangsklasse myApp.cs lautet ungefähr:


namespace myclass
{
	/// <summary>
	/// Summary description for FPSEPublish.
	/// </summary>
	public class myclass
	{
		public myclass()
		{
		}
		
		public void UrlToWebUrl(string uri, out string webUrl, out string fileUrl)
		{
				//methodencode
		}

		public void PutDocument(string uri, string fileName, string metaInfo)
		{
                                 //methodencode
		}

	
	}
}

dann die Anleitung der MSDN vollzogen:

So betten Sie eine Typbibliothek als Win32-Ressource in eine NET-basierte Anwendung ein

Kompilieren Sie die verwaltete Anwendung als Bibliotheksdatei. Wenn Sie beispielsweise eine Assembly für eine Anwendung namens MyApp erstellen möchten, geben Sie an der Eingabeaufforderung den folgenden Befehl ein:
[C#]
csc /t:library MyApp.cs

xportieren Sie eine Typbibliotheksdatei aus der Assembly unter Verwendung von Tlbexp.exe. Geben Sie an der Eingabeaufforderung den folgenden Befehl ein:
tlbexp MyApp.dll /out:mytypelib.tlb

Erstellen Sie ein Ressourcenskript, das die folgende Anweisung enthält:
IDR_TYPELIB1 typelib "mytypelib.tlb"

Der Name der Skriptdatei für dieses Beispiel lautet myresource.rc

Kompilieren Sie das Skript mit dem Ressourcencompiler von Microsoft Windows (Rc.exe). Geben Sie in der Eingabeaufforderung folgenden Befehl ein:
rc myresource.rc

Rc.exe erstellt die Ressourcendatei myresource.res

Kompilieren Sie die Quelldatei noch einmal, und geben Sie die Ressourcendatei an. Geben Sie in der Eingabeaufforderung folgenden Befehl ein:

C#]
csc /t:library MyApp.cs /win32res:myresource.res

Hierbei hab ich gelesen,dass das tool tlbexp automatisch durch die tlb-Datei eine CLSID vergibt .....

jedoch hat die verfahrensweise nicht funktioniert.
Ich würde als nächstes die GUID im Quellcode der klasse mit eintragen-weiß aber nicht wie ich mir eine GUID generiere...

Hat jemand noch einen TIP?

4.221 Beiträge seit 2005
vor 18 Jahren

Original von Cordoba
Ich würde als nächstes die GUID im Quellcode der klasse mit eintragen-weiß aber nicht wie ich mir eine GUID generiere...

Hat jemand noch einen TIP?

Im Devenev Menü Extras: GUID erstellen

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

C
Cordoba Themenstarter:in
54 Beiträge seit 2005
vor 18 Jahren

Danke für deinen Tip.Habe jetzt den Quellcode geändert:


[Guid("7C2A493D-7B27-4197-B41D-BFBED8FE47A6")]

namespace myclass
{
    /// <summary>
    /// Summary description for FPSEPublish.
    /// </summary>
    public class myclass
    {
        public myclass()
        {
        }
        
        public void UrlToWebUrl(string uri, out string webUrl, out string fileUrl)
        {
                //methodencode
        }

        public void PutDocument(string uri, string fileName, string metaInfo)
        {
                                 //methodencode
        }

    
    }
}

jedoch blieb diese Änderung ohne Erfolg, ich habe die prozedur wie oben beschrieben jetzt nochmal durchgemacht-hat nix geholfen.Würde mich über tips freuen.

Danke

4.221 Beiträge seit 2005
vor 18 Jahren

"für COM Interop registrieren" auf True gestellt ?

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

C
Cordoba Themenstarter:in
54 Beiträge seit 2005
vor 18 Jahren

ja das ist auf true gestellt.

ich teste das ganze immer in VB6.0 und versuche die dll als Verweis hinzuzufügen->"verweis auf die angegebene Datei kann nicht hinzugefügt werden"

die tlb-Datei jedoch kann ich einbinden, da findet VB6.0 die methoden meiner klasse aber nicht!

Wo liegt nun mein Fehler?

*hilfe*

4.221 Beiträge seit 2005
vor 18 Jahren

Nicht auf dem Namespace !!

Hast Du das mal gelesen COM Interop Part 2: C# Server Tutorial

Auszug:


// CSharpServer.cs
// compile with: /target:library
// post-build command: regasm CSharpServer.dll /tlb:CSharpServer.tlb

using System;
using System.Runtime.InteropServices;
namespace CSharpServer
{
   // Since the .NET Framework interface and coclass have to behave as 
   // COM objects, we have to give them guids.
   [Guid("DBE0E8C4-1C61-41f3-B6A4-4E2F353D3D05")]
   public interface IManagedInterface
   {
      int PrintHi(string name);
   }

   [Guid("C6659361-1625-4746-931C-36014B146679")]
   public class InterfaceImplementation : IManagedInterface
   {
      public int PrintHi(string name)
      {
         Console.WriteLine("Hello, {0}!", name);
         return 33;
      }
   }
}

Interessant ist auch der PostBuild ganz oben

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

C
Cordoba Themenstarter:in
54 Beiträge seit 2005
vor 18 Jahren

Ja das ist gut,das hat mir weitergeholfen.
Jedoch zeigt er mir meine Methoden in VB6 nicht an,sondern nur InterfaceImplementation und IManagedInterface als Methode der COM-Klasse.
Hier kann ich keine Parameter übergeben,zumindest schlägt er keine vor.

Muss ich für jede Methode/Funktion die ich im QUellcode hab eine GUID vergeben?

meine Klasse sieht jetzt so aus:


namespace myclass
{
	/// <summary>
	/// Summary description for FPSEPublish.
	/// </summary>
	[Guid("7C2A493D-7B27-4197-B41D-BFBED8FE47A6")] 
	public interface IManagedInterface
	{
		void PutDocument(string uri, string fileName, string metaInfo);
	}

	[Guid("955A2617-AFA1-433d-9DA8-8C1D8B0E61AE")]
	public class InterfaceImplementation : IManagedInterface
	{
		public void PutDocument(string uri, out string webUrl, out string fileUrl)
		{
                                     //mach etwas
                }
	}
}

3.728 Beiträge seit 2005
vor 18 Jahren
Klassenschnittstelle

Standardmäßig wird nur eine Schnittstelle für späte Bindung erstellt (IDispatch-COM-Implementierung). Du musst eine eigene Klassenschnittstelle schreiben, damit die Intellisense in VB6 & Co klappt. Diese muss von der Klasse implementiert werden, die als COM-Komponente veröffentlich werden soll. Außerdem musst Du das erzeugen der standardmäßigen-IDispatch-Schnittstelle abschalten. Dazu gibst Du Deiner Klasse das folgende Attribut:

[ClassInterface(ClassInterfaceType.None)]

Schau Dir einfach mal den folgenden Link an. Dort wird alles erklärt. Es gibt da noch einiges zu beachten (z.B. bei Events).

http://www.codeproject.com/csharp/COM_Object_in_C_.asp

Nach zwei oder drei Klassen wird die COM-Interop-Prozedur Routine. Außerdem kümmerst Du Dich automatisch um eine korrekte Versionierung. Du wirst es bei großen Projekten zu schätzen wissen.

C
Cordoba Themenstarter:in
54 Beiträge seit 2005
vor 18 Jahren

Danke für den Tip. Habe jetzt alles nach den Vorschriften des Links gemacht.
Jetzt kann ich auch auf die Funktion "PutDocument" in VB6 zugreifen - zumindest wird sie vorgeschlagen.

Problem ist jetzt nur noch, dass entweder das COM-Objekt nicht richtig registriert ist (obwohl ich "regasm COMObject.dll" ausgeführt habe) oder die Parameterübergabe nicht stimmt.

Denn bei folgenden VB6 code:


Private Sub Command1_Click()

Dim test As COMObject.MyClass
test.PutDocument "myURLweblink", "c:\document.jpg", ""

End Sub

kommt die Fehlermeldung:
"Objektvariable oder With-Blcokvariable nicht festgelegt"

Meine dll in C# heißt "COMObject" und die benutzte Klasse heißt "myClass".

Ich habe das ganze dann mit dem Zusatz


Set test = CreateObject("MyClass", "COMObject")

probiert. Da kommt die Fehlermeldung:

"Klasse ist auf lokalem Computer nicht registriert"

Wo könnte mein Fehler liegen?
Vielleicht habe ich bei der Registrierung was falsch gemacht? (habe nur regasm COMObject.dll ausgeführt)

C
Cordoba Themenstarter:in
54 Beiträge seit 2005
vor 18 Jahren

Nach ewigem probieren ist jetzt folgendes aufgetreten.

Ich hab den Quellcode des COM-Clients in VB6 so geändert:


Private Sub Command1_Click()

 Set test = CreateObject("COMObject.MyClass", "COMObject")
 Dim test As COMObject.MyClass
 test.PutDocument "myURLweblink", "c:\document.jpg", ""

End Sub

Jetzt meldet VB6 mir folgendes:
"Der Remote-Server-Computer" existiert nicht oder ist nicht verfügbar!"

anscheinend erwartet VB6 als COM-Client einen Server als tatsächliche Maschine?
Ich will das ganze aber erstmal lokal betreiben.
Die Registrierung des COM-Objektes ist aber erfolgreich verlaufen.

Für Hilfe wäre ich sehr dankbar.
*langsamverzweifel*

C
Cordoba Themenstarter:in
54 Beiträge seit 2005
vor 18 Jahren

Jetzt hat das ganze funktioniert.
Das Problem hat im VB-Code gelegen. Das CreateObject-Statement war überflüssig, da ein Verweis schon eingefügt war.

Jetzt wäre nur noch die Frage was es für Vorteile bringt, meine COM-Klasse in den Komponentendiensten von Win2000/XP hinzuzufügen?

3.728 Beiträge seit 2005
vor 18 Jahren
Com+

Ich habe die Antwort bereits auf Deinen anderen Thread gegeben. Sag bescheid, wenn Du mehr Informationen brauchst.

C
Cordoba Themenstarter:in
54 Beiträge seit 2005
vor 18 Jahren

Ich habe nun ein Programm fertig gestellt um es auf anderen Rechnern zu registrieren.

Was führt Visual Studio eigentlich im Hintergrund aus wenn ich in den Projekteinstellungen "für COM Interop registrieren" auf True gestellt habe?

Ich will meine erstellte COM interop-Assembly nun auch auf anderen Clients mit COM ansprechen, indem ich die Dll dort einbinde-wie geht das?

ich hab es mit regsvr32 probiert-welche Registry-Einträge werden da eigentlich eingetragen?

Danke für eure Hilfe..

4.221 Beiträge seit 2005
vor 18 Jahren

regsvr32 sollte eigentlich ok sein und die Einträge erstellen (welche mag ich jetzt auch nicht nachguken.... such doch mal nach deinen GUIDS in der Registry dann findest Du die Einträge selber

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...