Laden...

Remoting mit Win32-Anwendung

Erstellt von Matrix-NTN vor 18 Jahren Letzter Beitrag vor 18 Jahren 6.038 Views
M
Matrix-NTN Themenstarter:in
267 Beiträge seit 2005
vor 18 Jahren
Remoting mit Win32-Anwendung

Hallo zusammen,

Habe mich mal mit dem Remoting befasst so und nun habe ich eine anwendung: Client, DLL und Server mit dem Client rufe ich in der dll eine funktion auf die macht dann z.B.: Console.Writeline("Blabla");

Dann kommt das bei der Server Console auch an...

Aber wie mache ich es wenn ich möchte das der mir das ganze in eine Textbox schreibt oder eine listbox?

Mfg
Tobias

No Risk, No Fun

M
Matrix-NTN Themenstarter:in
267 Beiträge seit 2005
vor 18 Jahren

Fragen wir mal andersherum:

Ich möchte habe zwei anwendungen und möchte gerne, das die beiden anwendungen komuniezieren können aber nicht in form von Text sondern ich möchte im Prinzip sagen können:

Wenn ich bei Form1 auf den Button Klicke führe eine funktion von Form2 aus.
Und dann führt Form2 die Funktion aus und sendet den Return wert zurück an Form1.

So aber dann kommt noch was erschwerendes hinzu das ganze sollte über netzwerk also TCP oder so was laufen...

IP des rechners ist dem Programm bekannt...

mFg
Tobias

No Risk, No Fun

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo Matrix-NTN,

der Code in Dateiassoziation macht genau was du willst:

Aufruf im dem einen Prozess passiert hier:


argrecv.SetNewArgs (strAllArgs);

Aufgerufene Methode im anderen Prozess ist die:


public void SetNewArgs (String strAllArgs) 

Wenn die Methode eine Rückgabewert hätten,


public int SetNewArgs (String strAllArgs) 

dann würdest du den an der Aufrufstelle geliefert bekommen.


int iRet = argrecv.SetNewArgs (strAllArgs);

herbivore

M
Matrix-NTN Themenstarter:in
267 Beiträge seit 2005
vor 18 Jahren

Ja aber bei dir ist es in der Selben datei ich habe aber zwei verschiedene Dateien.

So dann kann ich nicht so einfahc sagen Datei.Funktionvondatei2(String) die wissen ja nichts voneinander...

No Risk, No Fun

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo Matrix-NTN,

dann du kannst/musst du meinen Code in drei Teile auseinander reißen. Den Server-Teil A, den Client-Teil B und die gemeinsam benutzen Sachen C. Aus C wird eine DLL, die von A und B benutzt wird.

herbivore

M
Matrix-NTN Themenstarter:in
267 Beiträge seit 2005
vor 18 Jahren

Ja aber so kann ich trotzdem nicht sage DLL benutze funktion von Programm a

No Risk, No Fun

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo Matrix-NTN,

warum nicht? Ich sehe keinen Grund, warum das nicht gehen sollte.

herbivore

M
Matrix-NTN Themenstarter:in
267 Beiträge seit 2005
vor 18 Jahren

Das erklärste mir bitte Mal

Zeig mir bitte einen kleinen besipielcode dann probier ich das mal aus aber meines wissens geht das nicht...
Wie auch die DLL weis ja nicht was es für funktionen in den programmen gibt...

mfg
tobias

No Risk, No Fun

6.862 Beiträge seit 2003
vor 18 Jahren

Sicher das du das mit dem Remoting richtig verstanden hast?

http://www.csharpfriends.com/Articles/getArticle.aspx?articleID=62

Hier ist nen Link wo das Remote Object in ner Dll steht. Ist zwar auch nur wieder ne Konsole, aber es besteht doch kein Unterschied ob du auf die Konsole schreibst, oder irgend ne andere Funktion aufrufst, musst dir halt nur richtig zusammenbasteln. Könntest des Remoteobject am besten als Interface realisieren und dann im Server richtig implementieren so das die entsprechenden Serverfunktionen aufgerufen werden. Und im Client brauchst dann nur des Interface aus der Dll kennen.

Baka wa shinanakya naoranai.

Mein XING Profil.

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo Matrix-NTN,

ich würde mal sagen so (und um Missverständnissen vorzubeugen, es läuft bei mir auch). So wie ichs auf die Schnelle gemacht habe, geht es allerdings nicht mit einer DLL, sondern man muss common.cs sowohl mit dem Client als auch mit dem Server übersetzen, wobei beim Server SW_SERVER definiert sein muss.

client.cs


using System;

using System.Threading;

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

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

   //==========================================================================
   public static int Main (string [] astrArg)
   {
      //-----------------------------------------------------------------------
      // 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, ArgsReceviver.strUniqueName, out pobjIOwnMutex);
      if (pobjIOwnMutex) {
         //--------------------------------------------------------------------
         // Hups, der Server-L„uft nicht
         //--------------------------------------------------------------------
      } else {
         //--------------------------------------------------------------------
         // Als weitere Instanz erzeugen wir den Client-Part
         //--------------------------------------------------------------------
         RemotingConfiguration.RegisterWellKnownClientType (
            typeof (ArgsReceviver),
            ArgsReceviver.strURLClient
         );

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

      return 0;
   }
}

server.cs


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;
   }

}

//*****************************************************************************
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)
   {
      //-----------------------------------------------------------------------
      // 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, ArgsReceviver.strUniqueName, out pobjIOwnMutex);
      if (pobjIOwnMutex) {
         //--------------------------------------------------------------------
         // Als erste Instanz erzeugen wir den Server/Service-Part
         //--------------------------------------------------------------------
         ChannelServices.RegisterChannel (new TcpChannel (ArgsReceviver.iUniquePort));
         RemotingConfiguration.ApplicationName = ArgsReceviver.strUniqueName;
         RemotingConfiguration.RegisterWellKnownServiceType (
            typeof (ArgsReceviver),
            ArgsReceviver.strURLService,
            WellKnownObjectMode.SingleCall
         );

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

      } else {
         //--------------------------------------------------------------------
         // Hups, es l„uft schon ein Server
         //--------------------------------------------------------------------
      }

      return 0;
   }
}

common.cs


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;

//*****************************************************************************
// 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) {
      #if SW_SERVER
         App.MainForm.SetNewArgs (strAllArgs);
      #endif
   }

   //-----------------------------------------------------------------------
   // Kommunikationsparameter
   //-----------------------------------------------------------------------
   public const String strUniqueName = "fhxrbjksiu";
   public const int    iUniquePort   = 8082;
   public readonly static String strURLClient = "tcp://localhost:" + iUniquePort + "/" + strUniqueName;
   public const String strURLService = strUniqueName;
}

HTH

herbivore

P
939 Beiträge seit 2003
vor 18 Jahren

Es kann schon Schwierigkeiten geben, wenn die Serverseite eine GUI haben soll.

Das Problem ist, dass eine Server-Klasse als WellKnownObject registriert wird. Stellt ein Client das erste Mal eine Verbindung her, wird ein Server-Objekt instanziiert. Wo, weiss man nicht. Man bekommt keine Referenz zum lokalen Objekt. Deshalb kann die Server-Anwendung es auch nicht nehmen und zum Beispiel eine Form in einer Eigenschaft setzen, damit das Server-Objekt Zugriff auf die Form bekommt. Die Form-Eigenschaft remote zugreifbar zu machen, ist auch nicht Sinn der Sache.

Eine Lösung ist: die GUI-Anwendungen argieren beide als Client. Eine der GUI-Anwendungen hostet zusätzlich noch den Server. Und der Server übernimmt nur die Kommunikation zwischen den Clients.

Ich sehe gerade wie herbivore es macht, mit einer statischen Variablen, die die Form hält. Das ist natürlich auch ne Lösung.

Gruss
Pulpapex

M
Matrix-NTN Themenstarter:in
267 Beiträge seit 2005
vor 18 Jahren

Also ich habs bei mir mal laufen lassen irgendwie geht da nichts...

Benutze halt #Develop...
hoffe das stört net.

Ich habe halt 2 Win anwendungen und die sollen sich gegenseiteig was in die listboxen oder so eintragen ich möchte nicht einfach strings senden und dann parst das programm den string durch was es machen soll, dann kann ich ja gleich ne Socket verbindung machen...

Mfg
Tobias

No Risk, No Fun

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo Matrix-NTN,

naja, wie gesagt, bei mir läuft es. Ich kenne #Develop nicht, aber warum sollte es nicht gehen. Trotzdem kommt hier mal mein makefile.

call: server.exe client.exe

server.exe: $*.cs common.cs
    csc $** /D:SW_SERVER

client.exe: $*.cs common.cs
    csc $**

Die Zeilen also in eine Datei 'makefile' kopieren und in dem Verzeichnis, wo auch die .cs-Dateien stehen, ablegen. Auf der Kommandozeile (Eingabeaufforderung) in dieses Verzeichnis wechseln und aufrufen:

X:\Programme\Microsoft.NET\SDK\v1.1\Bin\sdkvars.bat
nmake

X: ist das Laufwerk auf dem sich dein Ordner Programme befindet. Wahlweise natürlich X:\Programme\Microsoft.NET\SDK\v2.0\Bin\sdkvars.bat.

So (#Develop) oder so (Kommandozeile) solltest du es jetzt aber eigentlich selber hinbekommen.

HTH

herbivore

PS: Natürlich erst server.exe starten und dann client.exe und bei letzterem nicht vergessen, irgendwelche Argumente anzugeben, sonst sieht man nichts.

M
Matrix-NTN Themenstarter:in
267 Beiträge seit 2005
vor 18 Jahren

Sorry aber mit Makefiles hatte ich nocht nicht wirklich viel am hut habe es aber dennoch proibiert...

Nun bekomme ich folgende meldung:

nmake unterst³tzt keine Unicode/utf8-Dateien

An was kann das liegen?

Der inhalt ist genau wie du oben geschrieben hast

Mfg
Tobias

No Risk, No Fun

M
Matrix-NTN Themenstarter:in
267 Beiträge seit 2005
vor 18 Jahren

Ok es hat nun fuktioniert...

Nun noch ne frage für was ist das Flag SW_Server beim Makefile?

No Risk, No Fun

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo Matrix-NTN,

das Flag steuert die Übersetzung von common.cs. Im Code findest du es wieder. Ohne das Flag würde die Compilierung des Clients auf einen Fehler laufen, weil der Client die verwendetet statische Eigenschaft nicht besitzt.

herbivore