![]() |
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:
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.
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; 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: ![]() Vielen Dank schon mal für Eure Hilfe :wink: MfG Delphi-Apostel |
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 |
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
Dieses Thema wurde von "Christian Seehase" von "Programmieren allgemein" nach "Sonstige Fragen zu Delphi" verschoben.
Falsche Sparte, da delphispezifisch |
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 |
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? |
AW: Zugriff auf einen COM-Server aus einem Delphi-Dienst
Zitat:
Sinnvoll ist es erstmal raus zu bekommen ob die IDE oder das OS das Problem verursacht. |
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 ![]() 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: ![]() 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 |
AW: Zugriff auf einen COM-Server aus einem Delphi-Dienst
Zitat:
Zitat:
![]() |
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 ![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:39 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz