![]() |
COM Out of Process Server mit einem oder keinem Client
Hallo an alle,
ich habe folgende Aufgabe zu lösen: Ich habe eine Anwendung, die es gestattet, mittels Automatisierungsobjekt diverse Aufgaben auszuführen. Der so entstandene COM-Server wird mittels ciSingleInstance und tmSingle erzeugt. Damit bekomme ich, wie gewünscht, mit jedem neuen Client auch eine neue Instanz meines COM-Servers. Soweit so gut. Das Problem ist nur, dass es auch laufende Instanzen meiner Anwendung gibt, die vom Anwender gestartet wurden. Diese Instanzen besitzen logischerweise keinen Client und sollen auch keinen bekommen. Wenn nun aber ein Client einen COM-Server anfordert, so erzeugt er sich keine neue Instanz, solange noch manuell gestartete Instanzen verfügbar sind, sondern verbindet sich mit einer dieser bestehenden Instanzen. Wie sage ich nun also meinem COM-Server, dass jeder Client sich wirklich in jedem Fall eine neue Instanz des COM-Servers erzeugen soll, auch wenn es noch laufende Instanzen ohne Client gibt? Kann man vielleicht irgenwo einen RefCount manuell von 0 auf 1 setzen, damit die manuell gestartete Instanz als "verbunden" gilt, o.ä. . Ich wäre für eure Hilfe wirklich dankbar. VG Peter |
AW: COM Out of Process Server mit einem oder keinem Client
Wieso startet jemand deinen Server?
Oder hast du etwa eine Client-Anwendung, in der auch der Server eingebaut ist? In diesem Fall könnte man das doch bestimmt trennen und schon starten die User auch nicht mehr manuell solche Instanzen. :stupid: PS: Der COM-Server als eine Anwendung und die eigentliche Anwendung wird dann via IPC vom Server gesteurt, aber nur die Instanz, welcher der Server selber gestartet hat. Oder ganz böse ... wurde eine Anwendung manuell gestartet, dann verbindet sie sich zu sich selber und blockiert so diese Server-Instanz, bzw. kann man den COM-Server nicht einfach deaktivieren, wenn er nicht genutzt wird? |
AW: COM Out of Process Server mit einem oder keinem Client
Gibt es bei Deinem COM-Server sowas wie
Delphi-Quellcode:
?
ConnectKind := ckNewInstance;
![]() ![]() ![]() ![]() |
AW: COM Out of Process Server mit einem oder keinem Client
Vielleicht noch ein Versuch der Erklärung:
Ich habe eine Anwendung, die verschiedene Dinge ausrechnet. Das geschieht normalerweise durch einen Anwender, der die Anwendung startet, ursprünglich ganz ohne COM. Daher die Instanzen ohne einen COM-Client. Nun gibt es aber auch andere Anwendungen, die automatisch mit meinem Programm diese Rechnungen durchführen sollen. Damit sie das können, habe ich der Anwendung ein Automatisierungsobjekt verpasst. Meine Anwendung ist somit für die externen Programme erreichbar. Nun startet also der Nutzer einige Instanzen und weitere Instanzen sollen via COM-Automatisierung automatisch von externen Programmen erzeugt werden. Wie gesagt, das funktioniert auch soweit. Mittels ciSingleInstance als Instanziierung erzeugen die Clients sich alle ihre jeweils eigene Instanz. Nur eben nicht, wenn ein Nutzer zuvor andere Instanzen des Programms gestartet hat, die (bisher) über keinen Client verfügen und auch keinen bekommen sollen. Dann werden diese manuell gestarteten Instanzen von den COM-Clients in Beschlag genommen, statt eine neue Instanz zu erzeugen. |
AW: COM Out of Process Server mit einem oder keinem Client
Zitat:
|
AW: COM Out of Process Server mit einem oder keinem Client
Zitat:
|
AW: COM Out of Process Server mit einem oder keinem Client
Der Client muss aber (so wie ich das verstehe) sagen:
"Ich will eine eigene Instanz für mich." Oder: "Gibt mir irgendeine Instanz, auch wenn sie schon von wem anders benutzt wurde oder wird." Ansonsten müsste ja der Server, nachdem er aufgerufen wurde, sagen: "Hallo Du, mich darfts Du nicht nutzen, such Dir jemand anderes." Keine Ahnung, ob sich das in diesem (oder ähnlichem) Sinne umsetzen lässt. |
AW: COM Out of Process Server mit einem oder keinem Client
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Ich hatte nur gehofft, es gibt eine Möglichkeit, sowas der TypeLib mitzugeben, damit Windows das automatisch macht, ähnlich dem ciSingleInstance. Das funktioniert ja so mit dem einen Client, es fehlt aber noch die Variante kein Client. Ich habe auch mal ein Minmalbeispiel angehängt, falls das hilft das Problem zu erklären. |
AW: COM Out of Process Server mit einem oder keinem Client
Keine Ahnung, ob ich jetzt Blödsinn schreibe, versuche es trotzdem mal:
In Unit2 wird in initialization was gemacht, das, so wie ich das verstehe, für den Server, der als Server arbeiten soll, wesentlich ist. Wäre es irgendwie möglich, dann, wenn der Server "nur als normales Programm" laufen soll, diesen Teil nicht auszuführen? Bin da jetzt erstmal ganz naiv:
Delphi-Quellcode:
Das könnte dann gehen, wenn man den Server nur als Programm nutzen will, immer mit irgendeinem Parameter aufruft.
initialization
if ParamCount = 0 then begin TAutoObjectFactory.Create(ComServer, TTestClass, Class_TestClass, ciSingleInstance, tmSingle); end; end. Weitere Alternative, wenn auch unelegant. Es gibt von der Exe zwei Versionen, die sich nur durch den Namen unterscheiden. Also nach dem Kompilieren wird halt eine Kopie der EXE erstellet. Wir hätten dann z. B. copy Server.exe Anwender.exe In Unit2 fragen wir dann den Dateinamen ab:
Delphi-Quellcode:
Keine Ahnung, welcher administrative Aufwand dann entsteht, um sicherzustellen, dass die Anwender dann nicht mehr Server.exe starten, sondern Anwender.exe.
initialization
if ParamStr(0) = 'Server.exe' then begin TAutoObjectFactory.Create(ComServer, TTestClass, Class_TestClass, ciSingleInstance, tmSingle); end; end. Gebe ja zu: Elegant sind diese Vorschläge gewiss nicht. Unit2 wird ja nur in Server.dpr eingebunden. Die über einen Kompilerschalter einbinden.
Delphi-Quellcode:
Durch Nutzung des Compilerschalters bekommt man zwei gleichnamige Exen, bei denen man dann aber sicherstellen muss, dass der Anwender nicht die falsche aufruft. Sie müssten also zumindest an unterschiedlichen Stellen liegen. Und wenn dann beide im Suchpfad liegen, gewinnt die, die zuerst gefunden wird. Auch äußerst unelegant.
{$DEFINE ComServer}
program Server; uses Vcl.Forms, Unit1 in 'Unit1.pas' {Form1}, Project1_TLB in 'Project1_TLB.pas', {$IFDEF ComServer} Unit2 in 'Unit2.pas' {TestClass: CoClass}; {$ENDIF} {$R *.TLB} {$R *.res} begin Application.Initialize; Application.MainFormOnTaskbar := True; Application.CreateForm(TForm1, Form1); Application.Run; end. Ok, irgendwie ist da alles nicht so das Wahre, aber vielleicht hilft es ja so als Idee für 'ne vernünftige Lösung. |
AW: COM Out of Process Server mit einem oder keinem Client
Vielen Dank, letztlich ist es doch relativ einfach zu lösen, mit genau einer Zeile Quelltext. Es reicht wirklich, wenn man beim manuellen Start des Servers die Erzeugzung des Automatisierungsobjektes verhindert. Das geht ganz einfach, da man über den Paramstr[1] mittels "-Embedding" darüber informiert wird, wenn eine Anwendung von einem COM-Client gestartet wird.
Delphi-Quellcode:
Also nochmal danke für die Denkanstöße.
if (ParamCount >= 1) and (ParamStr(1) = '-Embedding') then
TAutoObjectFactory.Create(ComServer, TTestClass, Class_TestClass, ciSingleInstance, tmSingle); |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:33 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