AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Plug-ins realisieren für (D)COM Server

Ein Thema von SyntaxError · begonnen am 14. Jul 2008 · letzter Beitrag vom 14. Jul 2008
Antwort Antwort
SyntaxError

Registriert seit: 19. Jun 2008
16 Beiträge
 
Delphi 2006 Enterprise
 
#1

Plug-ins realisieren für (D)COM Server

  Alt 14. Jul 2008, 11:47
Hallo,

Ich entwickle gerade ein Logging mechanismus als DCOM Server, damit ich eine generelle Schnittstelle habe für ggf. zukünftige Anwendungen. Das Interface ist sehr einfach gehalten: start,stop,log(message)
Funktioniert auch alles prima, nur möchte ich den Server erweiterbar machen, d.h. logs werden nicht nur in textfiles geschrieben, sondern können auch (durch implementieren eines Interfaces) in beliebige Orte gespeichert werden. Weiss jemand wie ich das realisieren könnte?Ich hatte daran gedacht eine Library pro Ziel typ zu erstellen (als z.b XMLplugin.dll, EmailPlugin.dll, MSEventsPlugin.dll etc).
Wie weiss aber der Server welche plugins vorhanden sind?
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#2

Re: Plug-ins realisieren für (D)COM Server

  Alt 14. Jul 2008, 12:58
Zitat von SyntaxError:
Wie weiss aber der Server welche plugins vorhanden sind?
Am Server registrieren oder in ein bestimmtes Verzeichnis packen.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Benutzerbild von Codewalker
Codewalker

Registriert seit: 18. Nov 2005
Ort: Ratingen
945 Beiträge
 
Delphi XE2 Professional
 
#3

Re: Plug-ins realisieren für (D)COM Server

  Alt 14. Jul 2008, 13:58
Ich habe das (zwar nicht für DCOM) mit TJvPlugin gemacht. Das klappt wunderbar - wollte schon immer ein Tutorial schreiben .... wäre mal ein Anlass
Thomas
  Mit Zitat antworten Zitat
SyntaxError

Registriert seit: 19. Jun 2008
16 Beiträge
 
Delphi 2006 Enterprise
 
#4

Re: Plug-ins realisieren für (D)COM Server

  Alt 14. Jul 2008, 16:11
Also ich habs jetzt "einigermassen" hingekriegt weiss zwar nicht wie effizient das ganze ist (und ausführlich getestet habs ich auch noch nicht) aber es funktioniert bis jetzt gut, darum hab ich gedacht ich share mal code ausschnitte für diejenigen die ein ähnliches problem haben:

Kurzfassung:
Man erstellt ein Automations objekt für den Server, in diesem Beispiel LogServer (bzw. ILogServer) PLUS ein Interface ILogServerPlugin.
In meinem beispiel enthält ILogServerPlugin ein readonly property "PluginName" und eine methode "OnLog(AMessage:WideString);

Um ein eigenes Plugin zu erstellen müssen Automations objekte das Interface "ILogServerPlugin" implementieren und ihre ProgID im Schlüsse des Server objekts in der Registry eintragen.
( ich habe die Registry gewählt, man kann natürlich auch ein IniFile nutzen oder sonstwas, wichtig ist, dass Server die ProgID der Plugins von irgendwo her bekommt)


Die Interfaces sehen grob so aus (aufs minimum reduziert):

Delphi-Quellcode:
  ILogServer = interface(IDispatch)
    procedure Log(const AMessage: WideString); safecall;
    function Get_InstalledPlugIns: WideString; safecall;
    property InstalledPlugIns: WideString read Get_InstalledPlugIns;
  end;

  ILogServerPlugin = interface(IDispatch)
    function Get_PluginName: WideString; safecall;
    procedure OnLog(const AMessage: WideString); safecall;
    property PluginName: WideString read Get_PluginName;
  end;

Die Implementierung des Server Objekts sieht grob so aus:

Delphi-Quellcode:
  TLogServer = class(TAutoObject, ILogServer)
  private
    FPlugIns: TInterfaceList;
    procedure UnloadPlugIns();
  protected
    procedure Log(AMessage: WideString); safecall;
    function Get_InstalledPlugIns: WideString; safecall;
  public
    procedure Initialize; override;
    destructor Destroy; override;
  end;

Bei der Server implementierung habe ich eine eigene Factory von TAutoObjectFactory abgeleitet um die UpdateRegistry methode zu überschreiben.
Zweck davon ist, in der Registry einen neuen Schlüssel anzulegen der die ProgID's der installierten Plugins enthält.


Delphi-Quellcode:
 type
  TLogServerObjectFactory = class(TAutoObjectFactory)
  public
    procedure UpdateRegistry(Register: Boolean); override;
  end;
Die implementierung sieht so aus:

Delphi-Quellcode:
procedure TLogServerObjectFactory.UpdateRegistry(Register: Boolean);
var
  R: TRegistry;
begin
  inherited;

  if Register then // beim registrieren des DCOM Servers schlüssel anlegen
  begin
    R := TRegistry.Create;
    try
      R.CreateKey('\Software\LogServer\PlugIns');
    finally
      R.Free;
    end;
  end else
  begin // schlüssel löschen beim "unregistrieren"
    R := TRegistry.Create;
    try
      R.DeleteKey('\Software\LogServer\PlugIns');
    finally
      R.Free;
    end;
  end;
end;
Im Initalization teil muss man nun die Standard Factory mit der eigenen Klasse ersetzen:

Delphi-Quellcode:
initialization
  TLogServerObjectFactory.Create(ComServer, TLogger, CLASS_Logger,
    ciMultiInstance, tmApartment);

Um die PlugIns zu laden iteriere ich durch die Registry schlüssel, kreiere ein Objekt anhand des Schlüsselnamens(=ProgID),
und lege das Objekt in eine TInterfaceList (=FPlugIns).
(LoadPlugins wird im Create bzw. Initialization Aufruf des ServerObjekte aufgerufen),


Delphi-Quellcode:
procedure TLogServer.LoadPlugIns;
var
  i: integer;
  r: TRegistry;
  pList: TStringList;
  P: IInterface;
begin
 r := TRegistry.Create;
  try
    if r.OpenKeyReadOnly('\Software\LogServer\PlugIns') then
    begin
      if r.HasSubKeys then
      begin
        pList := TStringList.Create;
        r.GetKeyNames(pList);
        for I:=0 to pList.Count-1 do
        begin
          P := CreateOleObject(pList[I]); // kreiere Plugin Objekt anhand der ProgID (bsp: 'MyPlugin.MyPlugin')
          FPlugIns.Add(P);
        end;
      end;
    end;
  finally
    R.Free;
  end;
end;
Um die Funktionen der Plugins aufzurufen iteriere ich durch meine Interface liste, speichere das Interface in einem OleVariant und rufe die Funktion auf
( Dieser Teil ist zugegebenermassen nicht so elegant, da ich späte bindung nutze. Habe es mit casten des Interfaces zu ILogServerPlugin versucht, aber kriegte immer Fehlermeldung mit
"Schnittstelle nicht unterstützt", vielleicht hat einer von euch ja einen Tip?)
In dieser Funktion gebe ich die namen aller installierten plugins zurück. Die Methode OnLog funktioniert auf die gleiche weise (iterieren, aufrufen).

Delphi-Quellcode:
function TLogServer.Get_InstalledPlugIns: WideString;
var
  I: Integer;
  PlugInObj: OleVariant;
begin
  if FPlugIns.Count > 0 then
  begin
    for I:=0 to FPlugIns.Count-1 do
    begin
      try
        PlugInObj := FPlugIns.Items[I] as IDispatch;
        Result := Result + PlugInObj.PlugInName+#13;
        VarClear(PlugInObj);
      except
        //
      end;
    end;
  end;
end;

// CLIENT bzw. PLUGIN

Die Implementierung des Plugins ist ziemlich einfach. Neues Automationsobjekt erstellen das von ILogServerPlugin ableitet, es registrieren (dem Server bekannt machen) und Methoden implementieren.
Dazu auch hier eine neue Klasse von TAutoObjectFactory (TPluginFactory) ableiten und UpdateRegistry überschreiben:

Delphi-Quellcode:
procedure TPlugInFactory.UpdateRegistry(Register: Boolean);
var
  R: TRegistry;
begin
  inherited;
  if Register then // beim registrieren der activex library progid dem Server bekanntmachen
  begin
    R := TRegistry.Create;
    R.OpenKey('\Software\LogServer\PlugIns\'+ProgID),True);
    R.Free;
  end else
  begin
    R := TRegistry.Create; // schlüssel löschen bei "unregistrierung"
    try
      R.DeleteKey('\Software\LogServer\PlugIns\'+ProgID));
    finally
      R.Free;
    end;
  end;
end;

...

initialization
  TPlugInFactory.Create(ComServer, TFileLogPlugin, Class_FileLogPlugin,
    ciMultiInstance, tmApartment);
Ich hoffe ich habs einigermassen verständlich rübergebracht. Vielleicht hilft es ja jemandem.

Gruss
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#5

Re: Plug-ins realisieren für (D)COM Server

  Alt 14. Jul 2008, 17:30
Das was du da gemacht hast, ist zwar nicht falsch, aber Microsoft hat für den Zweck der Plugins extra sogenanne COM-Categories vorgesehen.
Ein Plugin registiert sich (also seine GUID) in einer bestimmten COM-Categorie.
Sowohl der Anwendung, als auch dem Plugin muss die GUID der COM-Categorie bekannt sein.
Die COM-Categorie hat neben der GUID auch eine Bezeichnung (auf Wunsch auch in versch. Sprachen).

In einer DLL können durchaus mehrere Plugin Co-Klassen enthalten sein und sich für eine oder auch mehrere COM-Categorien registrieren.
Wenn man's richtig macht, dann wird beim Registieren einer ActiveX-DLL nicht nur die DLL und deren Co-Klassen registiert sondern auch die Plugin-Klassen werden registriert.
Beim EntRegistrieren wird dies automatisch rückgängig gemacht.

Wenn man dieses System benützt, braucht man selbst in der Registry gar nichts eintragen.
Das Tool OLEView kann übrigens alle COM-Categorien und damit registrierte Co-Klassen anzeigen.
Die "Desktop Bands" und "Interner Explorer Browser Bands" basieren z.B. auch auf COM-Categorien.
Angehängte Dateien
Dateityp: pas comcat_156.pas (6,7 KB, 12x aufgerufen)
Andreas
  Mit Zitat antworten Zitat
SyntaxError

Registriert seit: 19. Jun 2008
16 Beiträge
 
Delphi 2006 Enterprise
 
#6

Re: Plug-ins realisieren für (D)COM Server

  Alt 14. Jul 2008, 17:58
Danke für die Unit und den Tip mit den Categories. Ich werde mir das in dem Fall genauer anschauen.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:31 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz