Hallo,
ich habe ein Problem, an dem ich mir langsam die Zähne ausbeiße:
In einer C# Klassenbibliothek (.NET4.5) habe ich einen Konstruktor, der
ein Winforms Fenster aufmacht. Das Ganze ist COM-Visible und kann auch
schon instantziert werden (z.B. PHP Javascript VBA etc...):
<?php
$obj = new COM("MyPhpTest.PhpTest");
echo $obj->AddString("hallo welt");
Ich möchte gerne, dass das COM-Objekt Systemübergreifend nur 1x
instanziert werden kann (sozusagen Singleton). Deshalb habe ich einen
Mutex eingebaut. Das funktioniert auch soweit. Es wird zu Beginn
geprüft, ob der Mutex existiert. Wenn nicht wird einer angelegt und das
Fenster erstellt. Wenn nicht, dann wird die Anwendung verlassen, weil ja
bereits gestartet.
Und genau da liegt mein Problem. Ich möchte gerne, dass wenn der Mutex
existiert, dann auch die Referenz zum Winform hergestellt wird und ich
dann im Programm fortfahren kann.
Hat da jemand eine Idee?
Viele Grüße,
Peter
Ich würde den Umweg über WCF machen.
Du hast einen Server (also dein Winforms Proggi) und der stellt ein WCF
Service zur Verfügung. Weiters wird beim Starten dieser Exe eine Mutex
gesetzt.
Dann brauchst eine einfach Dll die COM visible ist und das WCF Service
zur Exe auf macht. Wird die Dll initialisiert, schaust du ob der Mutex
noch frei ist und startest ggfls. den Server. Danach öffnest du den WCF
Channel und kannst mit der Dll umgehen, als gäbe es den Server gar
nicht.
Ich mache solche Spielereien bei ein zwei Projekten und es klappt sehr
gut. Aufpassen muss man nur bei den Timeouts des WCF Channels und bei
Exceptions.
So denn,
@Günter: So in der Art habe ich es auch schon mal gemacht. Hatte damals
kein wcf, sondern named pipes. was mir da nicht so gefaellt, ist dass
ich jedes kommando schicken muss. mir wuerde der direkte zugriff ueber
com auf das objekt und dessen methoden besser gefallen. sonst muss man
immer alles durchreichen. was es eh schon gibt.
@Sebastian. Also den Artikel habe ich auch gesehen. aber er gibt mir
keinen aufschluss darueber, wie ich beim 2ten aufruf die referenz zum
ersten aufruf zurueckgebe.
hat noch jemand eine idee?
Ich weiß ja nicht wie das bei den named pipes gelaufen ist, aber bei WCF
definiert man zuerst ein Interface mit den Funktionalitäten und das wird
auf beiden Seiten eingebaut.
Bei der Exe ist die Business Logic die die Arbeit erledigt und die Dll
ist eigentlich nur das Abbild des Interfaces.
Somit gehts kaum einfacher und das WCF inkl. Mutex braucht max. 30
Zeilen Code... Aber du wirst eine Lösung finden gg
Hallo Günter,
ich habe mir gestern noch ein paar Takte WCF reingezogen. Das sieht echt
so aus, als würde das ein guter Weg sein.
Weißt Du in etwa wie das dann mit dem "Overload" bei der Kommunikation
abläudt. Sollte ja doch etwas langsamer sein, als über COM (rein aus
meinem ersten Verständnis heraus.).
Und wie sieht es mit Firewalls aus. Wenn ich auf dem Client bleibe,
könnte ich es dann auch mit Firewall-Themen zu Kämpfen haben?
Wie sieht es am Ende bei der Installation eines solchen Konstrukts aus.
Kann man das relativ einfach installieren?
Viele Grüße,
Peter
Im Normalfall, merkst du das nicht, dass es über WCF läuft. Einzig beim
ersten Aufruf geht ein wenig mehr Zeit drauf. Ich habe das ganze für
eine sehr große Relais Steuerung realisiert. Sprich man kann bei der
Server Applikation mit schauen welche Relais gerade gesetzt sind und die
Client Dlls schicken die Daten über WCF. Man merkt hier keine merkliche
Verzögerung.
Firewall kann ein Thema sein, aber ich glaub man kann den Piort auch
angeben. Musst selber schauen.
Ich machs so. Die Client Dll wird auf den Rechner kopiert und danach per
regasm auf COM registriert (wirst du auch müssen). Die Exe (also der
Server) kopiere ich auch auf den Rechner und hinterlege in der Registry
den Pfad.
Beim initialisieren der Dll schau ich ob der Mutex frei ist, und wenn ja
wird in der Registry der Pfad zur Server Exe geholt und das Ding
gestartet. Ggfls. kannst du aber die Exe auch einfach an den selben Ort
legen wie dei Dll ist, dann kannst du dir Registry sparen. Falls der
Mutex aber "besetzt" ist öffne ich nur den WCF zum Server.
Good luck gg
Peter schrieb:> Und wie sieht es mit Firewalls aus. Wenn ich auf dem Client bleibe,> könnte ich es dann auch mit Firewall-Themen zu Kämpfen haben?
WCF kann zwar über TCP/IP Nachrichten austauschen, muss aber nicht, man
könnte genauso gut Named-Pipes verwenden. Für den Code darüber ist der
Transport nicht sichtbar, man kann das also auch später noch umstellen.
__tom schrieb:> Peter schrieb:>> Und wie sieht es mit Firewalls aus. Wenn ich auf dem Client bleibe,>> könnte ich es dann auch mit Firewall-Themen zu Kämpfen haben?>> WCF kann zwar über TCP/IP Nachrichten austauschen, muss aber nicht, man> könnte genauso gut Named-Pipes verwenden. Für den Code darüber ist der> Transport nicht sichtbar, man kann das also auch später noch umstellen.
Ach ja, so mach ich das auch. Hab grad geschaut... Dann gehts an der
Firewall vorbei!
Hallo noch mal ihr zwei und gerne auch andere,
kann man über WCF eigenlich auch fluent interfaces umsetzen?
http://de.wikipedia.org/wiki/Fluent_Interface
Das würde ich nämlich am aller liebsten machen wollen...
Viele Grüße,
Peter
Habs gerade getestet: Fluent Interface funktioniert auch.
Zur Vollständigkeit:
In Visual Studio Express 2012 gibt es ein Online-Sample-Projekt: "WCF
Non Administrator", das dann auch noch über named pipes kommuniziert und
keine Admin-Rechte benötigt.
Das Einzige was ich noch etwas unschön finde ist, dass er beim ersten
Client-Start so ca. 2 Sekunden braucht. Ist das normal?
Viele Grüße,
Peter
Peter schrieb:> Das Einzige was ich noch etwas unschön finde ist, dass er beim ersten> Client-Start so ca. 2 Sekunden braucht. Ist das normal?>> Viele Grüße,> Peter
2 Sekunden find ich relativ lang, aber ja es dauert eine gewisse Zeit,
das hab ich auch. Kommt zwischendurch bei mir auch immer wieder mal vor,
wenn sehr lange nichts über den WCF gegangen ist.
Habe aber kein Problem damit und bin dem "Problem" darum nicht nach
gegangen...