Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Zugriff auf einen COM-Server aus einem Delphi-Dienst (https://www.delphipraxis.net/82541-zugriff-auf-einen-com-server-aus-einem-delphi-dienst.html)

DelphiApostel 15. Dez 2006 11:19


Zugriff auf einen COM-Server aus einem Delphi-Dienst
 
Hallo ihr Lieben,

ich habe ein Problem beim Zugriff auf einen selbstgeschriebenen COM-Server aus einem Delphi-Dienst heraus:

1) ich habe einen "out-of-process" COM-Server (EXE-Datei) erstellt mit einer kleinen Funktion, die einfach nur eine Meldung in einer Memo-Box ausgibt.

2) danach erstellte ich einen Windows-Dienst (COM-Client) und hab dann die Typbibliothek importiert (Unit erstellt)

3) bei Bedarf wird dann im Dienst das entsprechende Interface (Objekt) erzeugt und die Funktion des COM-Servers (der Schnittstelle) aufgerufen.
Quellcode des COM-Clients (wie ihr sehen könnt, habe ich unterschiedliche Varianten ausprobiert):

Delphi-Quellcode:
procedure SendMsg(Nachricht:PChar);
var
 MyListener:ITDA_Listener;
 //MyListener:TTDA_Listener;
 hr: HRESULT;
begin
  CoInitialize(nil);
  OleInitialize(nil);
  //MyListener:=CreateCOMObject(Class_TDA_Listener) as ITDA_Listener;
  //MyListener:=CoTDA_Listener.Create;
  //MyListener:=TTDA_Listener.Create(nil);
  hr := CoCreateInstance(Class_TDA_Listener, nil, CLSCTX_LOCAL_SERVER, IID_ITDA_Listener, MyListener);
  MyListener.SendMsg('HALLO');
  //FreeAndNil(MyListener);
  CoUnInitialize;
  OleUnInitialize;
end;
Dabei wird keine Fehlermeldung angezeigt. Das Objekt (Interface) wird auch richtig erzeugt. Nur wird auf dem COM-Server keine Meldung in der Memo-Box angezeigt.

Wenn ich jetzt die gleichen Anweisungen in einer normalen EXE-Datei (Anwendung) ausführe, dann klappt das auch. Ich bekomme dann einen neuen Eintrag in der Memo-Box.
Woran liegt das? Gibt es irgendwelche Einschränkungen, die ich nicht beachtet habe? Der Dienst läuft unter dem gleichen Admin-Konto, wie die COM-Server Applikation auch.

Der COM-Server ist ein Programm (in meinem Fall Listener.exe), welches alle Events/Ereignisse des Windows-Dienstes (COM-Client) in der Memo-Box anzeigt. Damit ich keine Textdateien (Log-Dateien) oder überflüssige Event-Log Einträge erstellen muss...

Weitere Informationen zu meinem COM-Server:
- Instantiierung: mehrere Instanzen
- Threading-Modell: Apartment
- Schnittstelle ist als "Ole-Automatisierung" deklariert


Quellcode des COM-Servers:
Delphi-Quellcode:
unit InterfaceListener;

{$WARN SYMBOL_PLATFORM OFF}

interface

uses
  Windows, ActiveX, Classes, ComObj, Listener_TLB, StdVcl;

type
  TTDA_Listener = class(TTypedComObject, ITDA_Listener)
  protected
    function SendMsg(const WMsgText: WideString): HResult; stdcall;
    {ITDA_Listener-Methoden hier deklarieren}
  end;

implementation

uses ComServ,Hauptunit;


function TTDA_Listener.SendMsg(const WMsgText: WideString): HResult;
begin
   Form1.Nachrichten.Lines.Add(WMsgText);
end;


initialization
  TTypedComObjectFactory.Create(ComServer, TTDA_Listener, Class_TDA_Listener,
    ciMultiInstance, tmApartment);
end.

PS.: damit es kein Ärger gibt: die gleiche Frage habe ich auch in diesem Forum gestellt:
http://www.delphi-forum.de/topic_Zug...nst_67670.html

Vielen Dank schon mal für Eure Hilfe :wink:
MfG
Delphi-Apostel

JonnyGuitar 15. Dez 2006 16:35

Re: Zugriff auf einen COM-Server aus einem Delphi-Dienst
 
servus,

habe genau diese problemstellung versucht zu lösen, ohne erfolg.
habe mir das buch vom a. kosch über com zugelegt, brachte mich auch nicht weiter.

ein nettes mitglied dieses forum brachte mich dann auf die svcom komponenten, mit diesen sollte das möglich sein. ich habe dann kurz mit der trial rumexperimentiert, leider auch erfolglos, was aber natürlich auch an meiner blödheit liegen kann.

also in meinen augen geht das nicht, aber natürlich lasse ich mich gerne vom gegenteil überzeugen :)


mfg Jonny

Bernhard Geyer 15. Dez 2006 16:47

Re: Zugriff auf einen COM-Server aus einem Delphi-Dienst
 
Wieso ist den der Dienst der COM-Client? Sinnvoller wäre doch der Dienst als COM-Server (Mithilfe von SvCOM).

Wieso wird denn überhaupt COM genommen. Ich würde z.B. über Sockets die Daten austauschen.

DP-Maintenance 16. Dez 2006 13:42

DP-Maintenance
 
Dieses Thema wurde von "Christian Seehase" von "Programmieren allgemein" nach "Sonstige Fragen zu Delphi" verschoben.
Falsche Sparte, da delphispezifisch

DelphiApostel 18. Dez 2006 10:07

Re: Zugriff auf einen COM-Server aus einem Delphi-Dienst
 
Guten Morgen,

also ich habe mir jetzt auch ein Buch bestellt... ("Delphi COM Programming" von Eric Harmon) - für 50 EUR! Ich hoffe, dass ich das Geld jetzt nicht umsonst ausgegeben habe :?

Zurück zum Thema:
der Windows-Dienst besitzt bereits einen Indy TCP-Server. Ich will jetzt nicht jedes mal, wenn eine Event-Meldung ausgegeben werden soll, beim Dienst einen neuen IdTCP-Client erzeugen, Port auf dem Listener öffnen und eine Verbindung zum "Listener TCP-Server" herstellen. Das dauert viel zu lange und verursacht unnötige CPU-Last. Der Dienst kann ruhig die Event-Meldungen verschicken, egal ob der Listener läuft oder nicht. Ich glaube, dass das nur mit COM-Möglich ist...

Zur Info: der Windows-Dienst läuft auf dem Server. Es gibt viele GUI-Clients auf den Workstations, die sich mit diesem Server verbinden und verschiedene Informationen austauschen. Deswegen werden viele Event-Meldungen auch Zeitgleich ausgegeben/erzeugt (was auch dazu führen wird, dass auf dem Windows-Dienst mehrere TCP-Clients parallel/zeitgleich erzeuget werden müssen - nicht gut...)

Was man wirklich machen könnte ist, den Dienst als COM-Server zu deklarieren. Das Listener-Programm übergibt einfach seine Callback-Schnittstelle an den COM-Server, der dann die Event-Meldungen an diese Callback-Funktion schickt.
Wie es aussieht, ist eine IPC-Kommunikation zwischen einem Dienst und einer GUI-Anwendung nur in dieser Konstellation möglich.
Ich werde das jetzt so ausprobieren und nachher hier berichten, ob es geklappt hat oder nicht.

Vielen Dank an die, die mich bei meinem Problem unterstützen :thumb:

MfG
Delphi-Apostel

Bernhard68 2. Mär 2011 12:30

AW: Zugriff auf einen COM-Server aus einem Delphi-Dienst
 
Es ist zwar nun ein paar Jahre her, aber ich bin auch auf der Suche nach der Lösung dieses Problems.

Architektur:
1. Anwendung A (exe) als COM-Server
2. DLL als COM-Client
3a. Anwendnung B verwendet DLL um mit Anwendung A zu kommunizieren.
3b. Dienst (TService) verwendet DLL um mit Anwendung A zu kommunizieren.

Während die ganze Geschichte unter XP mit BCB5 problemlos lief,
bringe ich es unter Win7 mit ECB2010 nicht mehr ans Laufen.
3.a funktioniert auch unter Win7 tadellos, 3b nicht.

Wenn ich über den Dienst, auch wenn er im Administrator-Benutzerkonto läuft,
in der DLL "CoCreateInstance" aufrufe, bekomme ich den Fehlerwert "-2147221008" zurück.

Hat jemand diese Problem lösen können?

Bernhard Geyer 2. Mär 2011 12:45

AW: Zugriff auf einen COM-Server aus einem Delphi-Dienst
 
Zitat:

Zitat von Bernhard68 (Beitrag 1085346)
Während die ganze Geschichte unter XP mit BCB5 problemlos lief,
bringe ich es unter Win7 mit ECB2010 nicht mehr ans Laufen.

Was passsiert bei BCB5 unter Win7 bzw. bei ECB2010 unter XP?
Sinnvoll ist es erstmal raus zu bekommen ob die IDE oder das OS das Problem verursacht.

Bernhard68 2. Mär 2011 13:08

AW: Zugriff auf einen COM-Server aus einem Delphi-Dienst
 
Unter Win7 (wohl ab Vista) sind keine interaktiven Dienste mehr erlaubt.
Interaktive Dienste lassen sich zwar noch im Objektinspektor zur Klasse TService und in der Service Management Console (Dienste) noch konfigurieren, sind aber wohl nicht mehr erlaubt.
Möglicherweise ist das, das Problem?!

Im Thread Programm von Dienst starten lassen (Jetzt aber wirklich mal) wird das Thema auch diskutiert, hat mir aber noch nicht weitergeholfen.

Ich will ja, das der Dienst über COM (DLL realisiert COM-Client) den COM-Server (die Anwendung) ausführt, damit niemand sich am Rechner anmelden muss, um die Anwendung zu starten.


Noch ein Querverweis zu diesem Problem: Windows-Dienst als COM-Client. Geht das überhaupt???

In der COM-Client-DLL ist der Aufruf wie folgt (ist zwar C++, dürfte aber wohl nichts zur Sache tun, oder?):

...
Delphi-Quellcode:
Mk_tlb::TCOMIMK_Main comobj;
       
HRESULT hr = CoCreateInstance( Mk_tlb::CLSID_MK_Main, // {82031DB1-8955-4731-9AF6-08121F2331AB}
                  NULL,
                  CLSCTX_LOCAL_SERVER, // CLSCTX_ALL geht auch
                  Mk_tlb::IID_IMK_Main, // {D676B71E-0ACF-427A-A40E-23CCDECDFA29}
                  (void**)
                  &comobj );

bool ok = SUCCEEDED( hr ); //  Fehler -2147221008
...

Assarbad 2. Mär 2011 13:23

AW: Zugriff auf einen COM-Server aus einem Delphi-Dienst
 
Zitat:

Zitat von Bernhard68 (Beitrag 1085346)
2. DLL als COM-Client

Dies wird üblicherweise in COM als Proxy bezeichnet.

Zitat:

Zitat von Bernhard68 (Beitrag 1085346)
Wenn ich über den Dienst, auch wenn er im Administrator-Benutzerkonto läuft,
in der DLL "CoCreateInstance" aufrufe, bekomme ich den Fehlerwert "-2147221008" zurück.

Der Hexadezimalwert ist interessanter: 800401F0. 8 am Anfang sagt uns daß es ein Fehler ist (es ist schließlich in COM immer ein HRESULT). Da das obere Word nicht 8007 ist, ist dies auch kein Win32-Fehler. Da hilft nur der Weg über MSDN-Library durchsuchenFormatMessage um dem Fehler eine sinnvolle Beschreibung zu entlocken ;)

Bernhard68 2. Mär 2011 13:51

AW: Zugriff auf einen COM-Server aus einem Delphi-Dienst
 
Danke für die Idee mit FormatMessage, Assarbad. manchmal sieht man den Wald vor lauter Bäumen nicht mehr.

Die Fehlermeldung 800401F0 "CoInitialize wurde nicht aufgerufen.\r\n" ist da leider auch nicht Zielführend. Schade.

Im Thread Windows-Dienst als COM-Client. Geht das überhaupt??? wurde eine evt. fehlende Berechtigung zur Ausführung von COM-Objekten erwähnt. Eine Gruppe zur Berechtigung für DCOM habe ich gefunden, aber das ist nicht was ich suche, oder doch?


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:49 Uhr.
Seite 1 von 2  1 2      

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