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?
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...
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.
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...
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.
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;
}
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.
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...
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:
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.