Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi COM Out of Process Server mit einem oder keinem Client (https://www.delphipraxis.net/192663-com-out-process-server-mit-einem-oder-keinem-client.html)

Peter1999 9. Mai 2017 15:44

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

himitsu 9. Mai 2017 16:00

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?

nahpets 9. Mai 2017 16:02

AW: COM Out of Process Server mit einem oder keinem Client
 
Gibt es bei Deinem COM-Server sowas wie
Delphi-Quellcode:
ConnectKind := ckNewInstance;
?

http://www.delphisources.ru/pages/fa...t/LiB0123.html

http://www.informit.com/articles/art...30494&seqNum=5

http://docs.embarcadero.com/products...r_Connect.html

http://etutorials.org/Programming/ma...mation+Server/

Peter1999 9. Mai 2017 16:12

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.

Peter1999 9. Mai 2017 18:52

AW: COM Out of Process Server mit einem oder keinem Client
 
Zitat:

Zitat von nahpets (Beitrag 1370771)
Gibt es bei Deinem COM-Server sowas wie
Delphi-Quellcode:
ConnectKind := ckNewInstance;
?

Wenn ich das richtig verstanden habe, wird ConnectKind dort aber Client-seitig gesetzt. Auf die Clients habe ich aber leider keinen Einfluss.

Peter1999 9. Mai 2017 18:57

AW: COM Out of Process Server mit einem oder keinem Client
 
Zitat:

Zitat von himitsu (Beitrag 1370769)
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?

An sowas hatte ich auch schon gedacht. Ich habe leider keine Ahnung, wie ich herausbekmme, ob schon ein Client verbunden ist. Einen Counter habe ich da nicht finden können. Gibt es da einen?

nahpets 9. Mai 2017 18:58

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.

Peter1999 9. Mai 2017 19:32

AW: COM Out of Process Server mit einem oder keinem Client
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von nahpets (Beitrag 1370814)
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.

Ja, genau das brauche ich. Und ich muss es wie gesagt am Server umsetzen, weil die Clients nicht von mir stammen.
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.

nahpets 9. Mai 2017 20:01

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:
initialization
  if ParamCount = 0 then begin
    TAutoObjectFactory.Create(ComServer, TTestClass, Class_TestClass,
      ciSingleInstance, tmSingle);
  end;
end.
Das könnte dann gehen, wenn man den Server nur als Programm nutzen will, immer mit irgendeinem Parameter aufruft.

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:
initialization
  if ParamStr(0) = 'Server.exe' then begin
    TAutoObjectFactory.Create(ComServer, TTestClass, Class_TestClass,
      ciSingleInstance, tmSingle);
  end;
end.
Keine Ahnung, welcher administrative Aufwand dann entsteht, um sicherzustellen, dass die Anwender dann nicht mehr Server.exe starten, sondern Anwender.exe.

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:
{$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.
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.

Ok, irgendwie ist da alles nicht so das Wahre, aber vielleicht hilft es ja so als Idee für 'ne vernünftige Lösung.

Peter1999 10. Mai 2017 08:43

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:
  if (ParamCount >= 1) and (ParamStr(1) = '-Embedding') then
    TAutoObjectFactory.Create(ComServer, TTestClass, Class_TestClass,
      ciSingleInstance, tmSingle);
Also nochmal danke für die Denkanstöße.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:55 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