Forum: PC-Programmierung C# COM mutex single app: Rückgabe des laufenden Objekts.


von Peter (Gast)


Lesenswert?

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

von Günter R. (muntablues)


Lesenswert?

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,

von Sebastian L. (Gast)


Lesenswert?


von Peter (Gast)


Lesenswert?

@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?

von Günter R. (muntablues)


Lesenswert?

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

von Peter (Gast)


Lesenswert?

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

von Günter R. (muntablues)


Lesenswert?

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

von __tom (Gast)


Lesenswert?

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.

von Günter R. (muntablues)


Lesenswert?

__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!

von Peter (Gast)


Lesenswert?

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

von Günter R. (muntablues)


Lesenswert?

Meines Erachtens kann alles was serialisierbar ist, über WCF hin und her 
geschickt werden. Wenn dein Interface das kann, ist es ansich kein 
Problem.

von Peter (Gast)


Lesenswert?

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

von Günter R. (muntablues)


Lesenswert?

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...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.