Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

Dateiassoziation: Neue Dateinamen an die laufende Anwendung übergeben

Moderationshinweis von herbivore (26.04.2006 - 08:30)

Dies ist ein Thread, auf den aus der FAQ verwiesen wird. Bitte keine weitere Diskussion, sondern nur wichtige Ergänzungen und diese bitte knapp und präzise. Vielen Dank!

Fabian
myCSharp.de - Member

Avatar #avatar-1590.jpg


Dabei seit:
Beiträge: 1.985
Herkunft: Dortmund

Themenstarter:

Dateiassoziation: Neue Dateinamen an die laufende Anwendung übergeben

beantworten | zitieren | melden

Hallo Forum,

ich habe jetzt für meine Anwendung eine Dateiassoziation erstellt. Ich habe eine .ndp-Datei, die über meine Anwendung import wird. Wenn ich jetzt diese Datei doppelt anklicke, startet sich auch meine Anwendung und der Dateiname wird übergeben. Das klappt soweit auch alles gut.

Jetzt möchte ich aber nicht, dass meine Anwenung bei dem Doppelklick noch mal gestartet wird, wenn sie vorher schon geöffnet wurde. Kann man das irgendwie erreichen, dass der geöffneten Anwendung dann die Datei übergeben wird?


Danke und Gruß,
Fabian
"Eine wirklich gute Idee erkennt man daran, dass ihre Verwirklichung von vornherein ausgeschlossen erscheint." (Albert Einstein)

Gefangen im magischen Viereck zwischen studieren, schreiben, lehren und Ideen umsetzen…

Blog: www.fabiandeitelhoff.de
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo Fabian,

also um das Starten der zweiten Instanz wirst du wohl nicht herum kommen, aber du kannst dort erkennen, dass es die zweite Instanz ist (siehe: mehrere Programminstanzen verhindern? ) und dann der ersten Instanz die Parameter der zweiten Instanz schicken. Jetzt musst du nur noch eine Lösung für das Verschicken von einer Anwendung zur anderen finden - ich habe da gerade ein blackuot. (Mit Win32-PostMsg gehts auf jeden Fall, aber es wird bessere Lösungen geben).

HTH

herbivore
private Nachricht | Beiträge des Benutzers
swordfish
myCSharp.de - Member



Dabei seit:
Beiträge: 58
Herkunft: Österreich

beantworten | zitieren | melden

hmm gibts vielleicht sowas wie das singelton pattern aus java in c#??? damit könnte man das ja machen.

mfg
wer fehler findet, darf sie behalten
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo Fabian,

das Senden von Daten von einer Instanz einer Anwendung an eine andere Instanz, geht unter Win32 ganz einfach mit PostMsg (ggf. unter Nutzung von shared mem) und empfangen werden die Daten in der Windowprozedur, wie alle anderen (System-)Nachrichten auch. Den WindowHandle, an den man senden muss, kriegt man in der Win32-Main-Funktion quasi gleich mitgeliefert.

Nun hat mich selber interessiert, wie man das unter .NET hinbekommt. Was dem Win32-Vorgehen ähnlichsten sieht und wohl auch ist, ist die Verwendung der Klasse MessageQueue. Allerdings muss dafür eine extra Komponente installiert werden. Schade!

Nun sollte aber die Kommunikation zwischen Anwendungen unter .NET eigentlich ja ganz einfach sein, das geht ja alleine aus dem Namen .NET hervor. Also habe ich mich auf .NET-Remoting gestürzt. Nun gut, ich finde das .NET-Remoting nach meiner Beschäftigung damit nicht so prickelnd, aber ich habe die Kommunikation hinbekommen.

Das folgende Programm kann man mehrfach starten. Die beim Start übergebenen Kommandozeilenargumemte werden in der TextBox der ersten Instanz angezeigt. Weitere Instanzen beenden sich nach dem Senden der Argumente an die erste Instanz sofort wieder.

[EDIT]Weiter unten gibt es ein Codebeispiel für .NET 2.0, das bevorzugt verwendet werden sollte.[/EDIT]


using System;
using System.Windows.Forms;
using System.Drawing;

using System.Threading;

using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

//*****************************************************************************
public class MyWindow : Form
{
   //--------------------------------------------------------------------------
   private TextBox tb;

   //==========================================================================
   public MyWindow (String strAllArgs)
   {
      Control ctrlCurr;

      //-----------------------------------------------------------------------
      Text = "Test";
      Size = new Size (220 + Size.Width - ClientSize.Width,
                        70 + Size.Height - ClientSize.Height);

      //-----------------------------------------------------------------------
      ctrlCurr = tb = new TextBox ();
      ctrlCurr.Location = new Point (10,10);
      ctrlCurr.Size = new Size (200, 50);
      ctrlCurr.Text = strAllArgs;
      Controls.Add (ctrlCurr);
   }

   //==========================================================================
   public void SetNewArgs (String strAllArgs)
   {
      tb.Text = strAllArgs;
   }

}

//*****************************************************************************
// Objekte dieser Klasse können von Ferne benutzt werden
//*****************************************************************************
public class ArgsReceviver : MarshalByRefObject {

   //==========================================================================
   // Diese wird in der ersten Instanz ausgeführt, aber von der weiteren
   // Instanz aufgerufen. Die Übergebenen Werte an das Hauptfenster
   // weitergegeben.
   //==========================================================================
   public void SetNewArgs (String strAllArgs) {
      App.MainForm.SetNewArgs (strAllArgs);
   }
}

//*****************************************************************************
abstract class App
{
   //--------------------------------------------------------------------------
   private static Mutex pobjMutex = null;
   private static MyWindow frmMain = null;

   //==========================================================================
   public static MyWindow MainForm
   {
      get {
         return frmMain;
      }
   }

   //==========================================================================
   public static int Main (string [] astrArg)
   {
      //-----------------------------------------------------------------------
      // Kommunikationsparameter
      //-----------------------------------------------------------------------
      String strUniqueName = "4e1a0b12-57e2-4f50-ac2c-573358fdc599"; // unbedingt durch eine eigene GUID ersetzen
      int    iUniquePort   = 8082;
      String strURLClient = "tcp://localhost:" + iUniquePort + "/" + strUniqueName;
      String strURLService = strUniqueName;

      //-----------------------------------------------------------------------
      // Argumente zu eienm langen String zusammenfügen
      //-----------------------------------------------------------------------
      String strAllArgs = "";
      foreach (String strArg in astrArg) {
         strAllArgs += strArg + " ";
      }
      strAllArgs = strAllArgs.Trim ();

      //-----------------------------------------------------------------------
      // Feststellen, ob wir erste oder weitere Instanz sind
      //-----------------------------------------------------------------------
      bool pobjIOwnMutex = false;
      pobjMutex = new Mutex (true, strUniqueName, out pobjIOwnMutex);
      if (pobjIOwnMutex) {
         //-----------------------------------------------------------------------
         // Als erste Instanz erzeugen wir den Server/Service-Part
         //-----------------------------------------------------------------------
         ChannelServices.RegisterChannel (new TcpChannel (iUniquePort));
         RemotingConfiguration.ApplicationName = strUniqueName;
         RemotingConfiguration.RegisterWellKnownServiceType (
            typeof (ArgsReceviver),
            strURLService,
            WellKnownObjectMode.SingleCall
         );

         //-----------------------------------------------------------------------
         // Erzeugen und öffnen des Hauptfensters
         //-----------------------------------------------------------------------
         frmMain = new MyWindow (strAllArgs);
         Application.Run (frmMain);

      } else {
         //-----------------------------------------------------------------------
         // Als weitere Instanz erzeugen wir den Client-Part
         //-----------------------------------------------------------------------
         RemotingConfiguration.RegisterWellKnownClientType (
            typeof (ArgsReceviver),
            strURLClient
         );

         //-----------------------------------------------------------------------
         // Und senden die Argumente an den Server/Service-Part
         //-----------------------------------------------------------------------
         ArgsReceviver argrecv = new ArgsReceviver ();
         argrecv.SetNewArgs (strAllArgs);
      }

      return 0;
   }
}
[EDIT]Die GUID 4e1a0b12-57e2-4f50-ac2c-573358fdc599 ist nur ein Beispiel und muss bei der Übernahme des Codes unbedingt durch eine eigene GUID ersetzt werden.[/EDIT]

[EDIT]Weiter unten gibt es ein Codebeispiel für .NET 2.0, das bevorzugt verwendet werden sollte.[/EDIT]
Da ich selber keine Erfahrungen mit dem .NET-Remoting habe, bin ich an Rückmeldungen zu möglichen Verbesserungen oder Fallstricken interessiert. Insbesondere stört mich, dass man eine Port verbrät. Gibt es keine Möglichkeit, statt eines TcpChannels oder HttpChannels irgendeinen speichergebundenen Kanal zu verwenden (RPC oder Named Pipes o.ä.)?

HTH

herbivore

PS: Wenn ich die Mutex-Variable nicht als static-Member sondern als lokale Varible in Main deklariert hätte, würde jede Inzanz denken, sie wäre die erste (sprich die bestehende Mutex der ersten Instanz wird nicht gefunden oder - was zu vermuten steht - exisitiert dann nicht mehr).
private Nachricht | Beiträge des Benutzers
Fabian
myCSharp.de - Member

Avatar #avatar-1590.jpg


Dabei seit:
Beiträge: 1.985
Herkunft: Dortmund

Themenstarter:

beantworten | zitieren | melden

Hallo herbivore,

oha, dass ist ja doch wesentlich komplizierter als ich dachte. Aber trotzdem vielen Dank für das Beispiel. Werde mir das mal genauer ansehen.


Gruß,
Fabian
"Eine wirklich gute Idee erkennt man daran, dass ihre Verwirklichung von vornherein ausgeschlossen erscheint." (Albert Einstein)

Gefangen im magischen Viereck zwischen studieren, schreiben, lehren und Ideen umsetzen…

Blog: www.fabiandeitelhoff.de
private Nachricht | Beiträge des Benutzers
DeveloperX
myCSharp.de - Member



Dabei seit:
Beiträge: 462
Herkunft: .at/ooe&stmk

beantworten | zitieren | melden

Hallo zusammen!

Könnte man nicht einfach versuchen, ein Remote-Server-Objekt zu erstellen um festzustellen ob man die 1. instanz ist oder nicht? Wenns klappt, macht man im Programm weiter, und wenns nicht klappt, erstellt man ein Proxy-Objekt und sendet die Daten an die 1. Instanz.

Dann würde man sich das mit dem Mutex sparen.

mfg
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo DeveloperX,

das könnte man machen, aber dann muss man unterscheiden, ob das Erstellen nicht geklappt hat, weil der Server schon läuft oder weil ein anderer Fehler aufgetreten ist.

Mutex sind zur Synchronistation von Prozessen (und Threads) gedacht. Daher ist das schon genau das Richtige. Viel Aufwand ist es auch nicht. Und mit Semaphoren zu arbeiten kann man nicht früh genug lernen, wenn man mit Nebenläufigkeit arbeitet. :-)

herbivore
private Nachricht | Beiträge des Benutzers
LosWochos
myCSharp.de - Member



Dabei seit:
Beiträge: 14

beantworten | zitieren | melden

Hallo,

Ich fände oben stehenden Code eigentlich auch recht charmant um das Problem Anderen Process maximieren / Wiederherstellen / in der Vordergrund bringen zu lösen. Es gibt nur 2 Sachen die mich etwas "stören" oder wo ich skeptisch bin.

1. Ich verbrate einen extra TCPPort dafür, mit entsprechenden Folgen (Warnung von Personal Firewalls [=> Skepsis des Users], Gefahr dass gerade ein anderes Programm diesen Port nutzt) ?
2. Ich nutze localhost zur Kommunikation, gibt das nicht Probleme auf Terminal Servern? Bei Terminal Servern habe ich ja das Problem, dass ich nicht den kompletten Rechner, sondern nur die aktuelle Benutzersession ansprechen darf. Ähnliches gilt übrigens auch für Windows XP mit schneller Benutzerumschaltung.

Hat mit den oben stehenden Punkten jemand Erfahrung? Ich stecke im Remoting leider noch nicht so drin. So weit ich weiß gibt es ja auch noch andere Pipes als TCP Kommunikation, gibt es da vielleicht welche die sich mehr anbieten?

Gruß,
Flo
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo LosWochos,

um die Dinge, die dich stören, abzustellen, habe ich in Programm on Top den Code ja schon entsprechend geändert.

herbivore
private Nachricht | Beiträge des Benutzers
LosWochos
myCSharp.de - Member



Dabei seit:
Beiträge: 14

beantworten | zitieren | melden

Hi herbivore,
Zitat
Original von herbivore
um die Dinge, die dich stören, abzustellen, habe ich in Programm on Top den Code ja schon entsprechend geändert.

#region Kleinlaut
Oh
#endregion

Danke

Gruß,
LosWochos
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo zusammen,
Zitat
Gibt es keine Möglichkeit, statt eines TcpChannels oder HttpChannels irgendeinen speichergebundenen Kanal zu verwenden (RPC oder Named Pipes o.ä.)?
mit .NET 2.0 gibt es IpcChannel, der genau das leistet.

herbivore
private Nachricht | Beiträge des Benutzers
svenson
myCSharp.de - Member



Dabei seit:
Beiträge: 8.746
Herkunft: Berlin

beantworten | zitieren | melden

Für Remoting gibt es auch Named Pipes als Transer Channel.
private Nachricht | Beiträge des Benutzers
der Marcel
myCSharp.de - Member

Avatar #avatar-1860.gif


Dabei seit:
Beiträge: 564
Herkunft: Dresden

Beispiel für .Net2.0 unter Verwendung von IPC

beantworten | zitieren | melden

Hallo zusammen!

Um herbivores Fingerzeig auf IpcChannel in .Net2.0 zu komplettieren, habe ich sein Remoting-Beispiel von TCP auf IPC umgerüstet.
Ein Problem der Kommunikation zwischen Server/Client über TCP ist, dass es dabei desöfteren zu Komplikationen mit Virenscannern und Firewalls kommen kann. Der selbe Fehler, welcher im Beitrag AccessViolationException bei Remoting mit Windows-.Net-Dienst/Konsolenanwendung aufgetaucht ist, zeigte sich auch bei herbivores ursprünglichem .Net1.1-Beispiel. Man musste das Programm nur dreimal hintereinander starten, um im Zusammenspiel mit dem Internet-Wächer des Virenscanners eine AccessViolationException zu erreichen. Als adäquate Alternative zum Abschalten des Virenscanners bietet sich in .Net2.0 daher IpcChannel an, da es nicht über das Netzwerk arbeitet, sondern das prozessübergreifende Kommunikatonssystem von Windows verwendet.

Nun das Beispiel für .Net2.0:

using System;
using System.Windows.Forms;
using System.Drawing;

using System.Threading;

using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Ipc;

//*****************************************************************************
public class MyWindow : Form
{
    //--------------------------------------------------------------------------
    private TextBox tbx;

    //==========================================================================
    public MyWindow()
    {
        Control ctrlCurr;
        
        //-----------------------------------------------------------------------
        Text = "Test";
        ClientSize = new Size(220, 70);

        //-----------------------------------------------------------------------
        ctrlCurr = tbx = new TextBox();
        ctrlCurr.Location = new Point(10, 10);
        ctrlCurr.Size = new Size(200, 50);
        Controls.Add(ctrlCurr);
        CreateHandle();
    }

    //==========================================================================
    public void SetNewArgs(String[] astrArg)
    {
        //-----------------------------------------------------------------------
        // Argumente zu einem langen String zusammenfügen
        //-----------------------------------------------------------------------
        String strAllArgs = "";
        foreach (String strArg in astrArg)
        {
            strAllArgs += strArg + " ";
        }
        strAllArgs = strAllArgs.Trim();

        BeginInvoke((MethodInvoker)delegate() { tbx.Text = strAllArgs; });
    }

}

//*****************************************************************************
// Objekte dieser Klasse können von Ferne benutzt werden
//*****************************************************************************
public class ArgsReceiver : MarshalByRefObject
{

    //==========================================================================
    // Diese wird in der ersten Instanz ausgeführt, aber von der weiteren
    // Instanz aufgerufen. Die übergebenen Werte an das Hauptfenster
    // weitergegeben.
    //==========================================================================
    public void SetNewArgs(String[] astrArg)
    {
        App.MainForm.SetNewArgs(astrArg);
    }
}

//*****************************************************************************
abstract class App
{
    //--------------------------------------------------------------------------
    private static Mutex pobjMutex = null;
    private static MyWindow frmMain = null;

    //==========================================================================
    public static MyWindow MainForm
    {
        get
        {
            return frmMain;
        }
    }

    //==========================================================================
    public static int Main(string[] astrArg)
    {
        //-----------------------------------------------------------------------
        // Kommunikationsparameter
        //-----------------------------------------------------------------------
        String strUniqueName = "215f73e4-c820-4b3c-8f90-3f7e6616ee59"; // unbedingt durch eine eigene GUID ersetzen
        String strUniquePortName = "sdfsdfsdfs";
        String strURLClient = "ipc://" + strUniquePortName + "/" + strUniqueName;
        String strURLService = strUniqueName;

        //-----------------------------------------------------------------------
        // Feststellen, ob wir erste oder weitere Instanz sind
        //-----------------------------------------------------------------------
        bool pobjIOwnMutex = false;
        pobjMutex = new Mutex(true, strUniqueName, out pobjIOwnMutex);
        if (pobjIOwnMutex)
        {
            //-----------------------------------------------------------------------
            // Als erste Instanz erzeugen wir den Server/Service-Part
            //-----------------------------------------------------------------------
            ChannelServices.RegisterChannel(new IpcChannel(strUniquePortName), false);
            RemotingConfiguration.ApplicationName = strUniqueName;
            RemotingConfiguration.RegisterWellKnownServiceType(
               typeof(ArgsReceiver),
               strURLService,
               WellKnownObjectMode.SingleCall
            );

            //-----------------------------------------------------------------------
            // Erzeugen und öffnen des Hauptfensters
            //-----------------------------------------------------------------------
            frmMain = new MyWindow();
            frmMain.SetNewArgs(astrArg);
            Application.Run(frmMain);

        }
        else
        {
            //-----------------------------------------------------------------------
            // Als weitere Instanz erzeugen wir den Client-Part
            //-----------------------------------------------------------------------
            RemotingConfiguration.RegisterWellKnownClientType(
               typeof(ArgsReceiver),
               strURLClient
            );

            //-----------------------------------------------------------------------
            // Und senden die Argumente an den Server/Service-Part
            //-----------------------------------------------------------------------
            ArgsReceiver argrecv = new ArgsReceiver();
            argrecv.SetNewArgs(astrArg);
        }

        return 0;
    }
}

[EDIT=herbivore]Die GUID 215f73e4-c820-4b3c-8f90-3f7e6616ee59 ist nur ein Beispiel und muss bei der Übernahme des Codes unbedingt durch eine eigene GUID ersetzt werden.[/EDIT]

@svenson: Es ist gut möglich, das IPC NamedPipes implementiert. Meinst du das damit?

Viel Erfolg damit!
der Marcel

EDIT: Neuen Code eingefügt. herbivore hat daran noch einige Optimierungen aus der ursprünglichen Version vorgenommen.
:] :DDer größte Fehler eines modernen Computers sitzt meist davor :]
private Nachricht | Beiträge des Benutzers
dutop
myCSharp.de - Member



Dabei seit:
Beiträge: 103
Herkunft: Kempten, Allgäu

beantworten | zitieren | melden

Hallo, die "abstract class App" verwirrt mich. Soll die die normale "static class Program" ersetzen? (Die ist doch normal? Oder IDE-Abhängig?) Oder ist App einfach eine neue Klasse? Aber wer ruft dann Main() auf?

Ich kapier einfach nicht, was sie machen soll.
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo dutop,
Zitat
Hallo, die "abstract class App" verwirrt mich. Soll die die normale "static class Program" ersetzen?
das Programm habe ich noch für 1.1 geschrieben. Da gab es noch keine Static-Klassen. In 2.0 benutze ich static class App.
Zitat
(Die ist doch normal? Oder IDE-Abhängig?)
Das ist IDE-abhängig. Ich benutze kein VS, sondern schreibe den Code von Hand. Man ist dabei vällig frei, den Klassennamen und die Modifier (abstract, static, public, internal) nach Belieben zu wählen.
Zitat
Oder ist App einfach eine neue Klasse?
Ja, na klar ist es eine neue Klasse.
Zitat
Aber wer ruft dann Main() auf?
Die Laufzeitumgebung. In welcher Klasse sich die Main-Methode befindet, ist der Laufzeitumgebung völlig egal.
Zitat
Ich kapier einfach nicht, was sie machen soll.
Sie soll einfach nur eine Rahmen für die Main-Methode geben. So wie die Klasse gestaltet ist, entspricht sie meinen Vorstellungen von gutem Design. Aber Design ist immer auch ein Stück Geschmachssache.

Ich hoffe ich konnte das damit klarstellen. Da dies ein Thread ist, auf den aus den FAQ verwiesen wird, sollten wir das nicht ausdiskutieren, um den Thread schlank zu halten. Mach im Zweifel einen neuen Thread auf.

herbivore
private Nachricht | Beiträge des Benutzers
xxxprod
myCSharp.de - Experte

Avatar #avatar-2329.gif


Dabei seit:
Beiträge: 1.378
Herkunft: Österreich\Wien

beantworten | zitieren | melden

Ich hab das ganze jetzt mal probiert, da ich das Beispiel gut gebrauchen kann. Bin beim debuggen auf einen eventuellen Fehler gestoßen:

Wenn ich die erste App im Debug Modus laufen lasse, und eine andere mit Parametern dazu starte kommt folgende Meldung:
Zitat
Cross-thread operation not valid: Control '' accessed from a thread other than the thread it was created on.

Ist das jetzt bei dem Beispiel übersehen worden oder einfach nur nicht implementiert, dass man aus einem anderen Thread auf Controls nicht zugreifen darf?
private Nachricht | Beiträge des Benutzers
progger
myCSharp.de - Member

Avatar #avatar-2094.gif


Dabei seit:
Beiträge: 1.271
Herkunft: Nähe von München

beantworten | zitieren | melden

Hallo xxxprod,

Das ist grundsätzlich so und hat nichts mit dem Beispiel hier zu tun. Höchstwahrscheinlich hast du einen Fehler in deinem eigenen Code gemacht. Schau dir am besten mal den FAQ-Beitrag [FAQ] Controls von Thread aktualisieren lassen (Invoke-/TreeView-Beispiel) an.

Gruß,
Thomas
A wise man can learn more from a foolish question than a fool can learn from a wise answer!
Bruce Lee

Populanten von Domizilen mit fragiler, transparenter Außenstruktur sollten sich von der Translation von gegen Deformierung resistenter Materie distanzieren!
Wer im Glashaus sitzt, sollte nicht mit Steinen werfen.
private Nachricht | Beiträge des Benutzers
xxxprod
myCSharp.de - Experte

Avatar #avatar-2329.gif


Dabei seit:
Beiträge: 1.378
Herkunft: Österreich\Wien

beantworten | zitieren | melden

Es war mir bekannt das man Threads bei Form zugriffen nicht mischen darf. Ich hab auch nur dieses Beispiel hier 1:1 kopiert und nichts verändert.

Dieser Fehler tritt komischerweise nur beim debuggen auf, aber nicht wenn ich 2x die App direkt aufrufe.
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo xxxprod,

ich denke, wenn du das .NET 2.0 Beispiel verwendest, sollte das Problem nicht auftreten, richtig?

herbivore
private Nachricht | Beiträge des Benutzers
xxxprod
myCSharp.de - Experte

Avatar #avatar-2329.gif


Dabei seit:
Beiträge: 1.378
Herkunft: Österreich\Wien

beantworten | zitieren | melden

Stimmt du hast recht. Hab zuerst dein 1.1 beispiel probiert, und erst später die neuere Version entdeckt, aber nicht gedacht das die änderungen so gravierend waren.
private Nachricht | Beiträge des Benutzers
langalaxy
myCSharp.de - Member

Avatar #avatar-1914.gif


Dabei seit:
Beiträge: 664

beantworten | zitieren | melden

Hallo zusammen,

ich beschäftige mich im Moment mit WCF und habe versucht die Vorgehensweise der Parameterübergabe mit Hilfe von WCF zu realisieren. Für Kritik bin ich gerne offen

Bitte beachtet, das ihr .NET 3 für das Beispiel benötigt und deshalb min. Windows XP SP2 vorhanden sein muss.

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.ServiceModel.Channels;
using System.ServiceModel;

namespace SingleConsole
{
    /// <summary>
    /// Service contract
    /// </summary>
    [ServiceContract]
    interface IArgsReceiver
    {
        [OperationContract]
        void PassArgs(string[] args);
    }

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    class Program : IArgsReceiver
    {
        /// <summary>
        /// Mutex
        /// </summary>
        private static Mutex _mutex = null;
        /// <summary>
        /// Named Pipe Binding
        /// </summary>
        private static Binding _binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.Transport);
        /// <summary>
        /// IPC Adresse
        /// </summary>
        private static string _pipeName = @"net.pipe://localhost/{B19E75EF-1F5E-4e09-A0FF-5650879AF497}";

        static void Main(string[] args)
        {
            bool _owningMutex = false;

            _mutex = new Mutex(true, "{5D40EBFD-0645-4685-88F4-175A8EFE59D2}", out _owningMutex);

            if ( _owningMutex )
            {
                // Erzeuge Host für Service
                ServiceHost host = new ServiceHost(typeof(Program));
                
                // Erstellen des Named Pipe Endpunkts
                host.AddServiceEndpoint(typeof(IArgsReceiver), _binding, _pipeName);

                // Anfrage von außen akzeptieren
                host.Open();

                Console.WriteLine("Press any key to continue...");
                Console.Read();

                host.Close();
            }
            else
            {
                try
                {
                    // Erzeugen eines Kanals, über den mit dem Service kommuniziert wird
                    IArgsReceiver proxy = ChannelFactory<IArgsReceiver>.CreateChannel(_binding, new EndpointAddress(_pipeName));

                    // Methode aufrufen und Kanal entsorgen
                    using ( proxy as IDisposable )
                    {
                        proxy.PassArgs(args);
                    }
                }
                catch ( CommunicationException exc )
                {
                    Console.WriteLine(exc.Message);
                }
            }
        }

        #region IArgsReceiver Member

        public void PassArgs(string[] args)
        {
            ConsoleColor def = Console.ForegroundColor;

            Console.ForegroundColor = ConsoleColor.Green;

            foreach ( string arg in args )
            {
                Console.WriteLine("### foreign argument |\t{0}",arg);
            }

            Console.ForegroundColor = def;
        }

        #endregion
    }
}
private Nachricht | Beiträge des Benutzers