Laden...

.Net Remoting

Erstellt von attaÄhh vor 18 Jahren Letzter Beitrag vor 18 Jahren 1.967 Views
A
attaÄhh Themenstarter:in
78 Beiträge seit 2004
vor 18 Jahren
.Net Remoting

Hallo,
ich habe ein kleine Frage zu der Funktionsweise von .NET Remoting. Und zwar geht es dabei um die Kommunikation

Ich habe eine Hostanwendung diese kennt eine Dll von meiner "businesslogic". Die auszuführende Datei der Hostanwendung und die dll liegen in dem selben Verzeichniss. Ich starte den Client, registriere den channel rufe Methoden auf etc. Alles läuft einwandfrei.

Nun starte ich den Host anders. Die dll liegt in einem Unterverzeichniss der auszuführenden Datei also nicht mehr in dem selben.
Ich starte den Client, er registriert sich anscheinend und bei einem Methodenaufruf bekomme ich die Meldung das das Assembly meiner Bl nicht gefunden wurde.

Meine Frage ist wozu braucht der Client diese dll, müsste doch eigendlich genügen wenn der Host die kennt. Oder im zweiten Schritt wie ich dem client sagen kann das er auch in anderen Ordner nach der dll suchen soll..

brauche Hilfe!!!

mfg attaÄhh

P
939 Beiträge seit 2003
vor 18 Jahren

Ein Client benötigt eine Dll mit den Server-Typen, die er verwendet. Anders herum verhält es sich genauso, der Server benötigt eine Dll mit den Client-Typen.

Am besten du legst dir eine Dll mit Interface-Typen für Client und Server an. Die Dll wird sowohl dem Client als auch dem Server mitgegeben. Selbst definierte Parameter-Typen, die in den Interfaces verwendet werden, gehören auch in diese Dll. Dann sollte es wieder funktionieren.

Ansonsten lies dir auch mal die Beiträge zu Remoting hier im Board durch. Es war schon häufiger Thema und es wurden gute Tipps gegeben.

Gruss
Pulpapex

137 Beiträge seit 2005
vor 18 Jahren

Dieses Tutorial könnte helfen:

http://www.csharphelp.com/archives/archive191.html

A
attaÄhh Themenstarter:in
78 Beiträge seit 2004
vor 18 Jahren

Hi,
ich muss leider sagen das ich noch immer verständnissprobleme habe.

Pulpaplex, was meinst du mit

"Am besten du legst dir eine Dll mit Interface-Typen für Client und Server an."?

hast du vielleicht ein Beispiel wie dies aussehen könnte? hab überhaupt keine vorstellung X(

mfg atta...

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo attaÄhh,

in Remoting mit Win32-Anwendung ist es zwar nicht mit Interfaces gemacht (was schöner wäre), aber dafür findest du einen kompletten Programmrahmen.

herbivore

P
939 Beiträge seit 2003
vor 18 Jahren

Wie gesagt einfach mal im Board suchen.

Der Thread hier ist glaube ich ganz informativ (wenn du den von herbivore durch hast):
Remote-Event Fehlermeldung

Es geht darum, dass die Client-Anwendung nicht den kompletten Codebestand der Server-Anwendung lokal haben muss. Kann man so lösen, indem der Client nicht direkt auf die Server-Klassen zugreift, sondern nur über Server-Interfaces. Dadurch müssen clientseitig nur die Server-Interfaces verfügbar sein, aber nicht die Klassen.

Gruss
Pulpapex

A
attaÄhh Themenstarter:in
78 Beiträge seit 2004
vor 18 Jahren

Hallo Leute,

Ich habe mich die letze Woche nochmals intensiv mit .NET Remoting beschäfting, bin die von euch vorgeschlagenen Samples durchgegangen was mir sehr behilflich war...

Leider konnte ich den ursprünglichen Fehler aber nicht dadurch beheben.
ist zwar ein bischen länger aber guckt euch den doch mal bitte an

..vielleicht hatte ja einer von euch das selbe prob und könnte mir weiterhelfen.

************** Ausnametext **************
System.IO.FileNotFoundException: Datei- oder Assemblyname 'Programdetector' oder eine Abhänigkeit davon wurde nicht gefunden.
Dateiname: Programdetector

Server stack trace:
at System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, Boolean isStringized, Evidence assemblySecurity, Boolean throwOnFileNotFound, Assembly locationHint, StackCrawlMark& stackMark)
at System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Boolean stringized, Evidence assemblySecurity, StackCrawlMark& stackMark)
at System.Reflection.Assembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark)
at System.Reflection.Assembly.Load(String assemblyString)
at System.Runtime.Remoting.RemotingConfigInfo.LoadType(String typeName, String assemblyName)
at System.Runtime.Remoting.RemotingConfigInfo.GetServerTypeForUri(String URI)
at System.Runtime.Remoting.RemotingConfigHandler.GetServerTypeForUri(String URI)
at System.Runtime.Remoting.RemotingServices.GetServerTypeForUri(String URI)
at System.Runtime.Remoting.Channels.BinaryServerFormatterSink.ProcessMessage(IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, IMessage& responseMsg, ITransportHeaders& responseHeaders, Stream& responseStream)

Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at RIS.ProgramDetector.Interfaces.IProgDetector.GetApplications()
at ResxProgrammanager.crtlProgramresxHandler.FillGrid() in s:#projekte#aktuelle\resxprogrammanager\crtlprogramresxhandler.cs:line 446
at ResxProgrammanager.Form1.barMain_ToolClick(Object sender, ToolClickEventArgs e) in s:#projekte#aktuelle\resxprogrammanager\resxprogrammanager.cs:line 376
at Infragistics.Win.UltraWinToolbars.UltraToolbarsManager.OnToolClick(ToolClickEventArgs e)
at Infragistics.Win.UltraWinToolbars.UltraToolbarsManager.FireEvent(ToolbarEventIds id, EventArgs e)
at Infragistics.Win.UltraWinToolbars.ToolBase.OnToolClick()
at Infragistics.Win.UltraWinToolbars.ButtonToolUIElement.DoClickProcessing(MouseEventArgs e)
at Infragistics.Win.UltraWinToolbars.ButtonToolUIElement.OnMouseUp(MouseEventArgs e)
at Infragistics.Win.ControlUIElementBase.ProcessMouseUp(Object sender, MouseEventArgs e)
at System.Windows.Forms.Control.OnMouseUp(MouseEventArgs e)
at Infragistics.Win.UltraWinToolbars.UltraToolbarsDockArea.OnMouseUp(MouseEventArgs e)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

=== Pre-bind state information ===
LOG: DisplayName = Programdetector
(Partial)
LOG: Appbase = S:\TestApplication\
LOG: Initial PrivatePath = NULL
Calling assembly : (Unknown).
===

LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Post-policy reference: Programdetector
LOG: Attempting download of new URL file:///S:/TestApplication/Programdetector.DLL.
LOG: Attempting download of new URL file:///S:/TestApplication/Programdetector/Programdetector.DLL.
LOG: Attempting download of new URL file:///S:/TestApplication/Programdetector.EXE.
LOG: Attempting download of new URL file:///S:/TestApplication/Programdetector/Programdetector.EXE.

mfg atta

P
939 Beiträge seit 2003
vor 18 Jahren

Wahrscheinlich verwendest du immer noch Typen, die auf Clientseite nicht vorhanden sind. Welche Typen liefert der Aufruf von RIS.ProgramDetector.Interfaces.IProgDetector.GetApplications zurück oder in welchen Typ castest du? Poste mal den Code der ResxProgrammanager.crtlProgramresxHandler.FillGrid-Methode.

Nochmal: alle Interfaces und alle Parameter und Rückgabetypen der Interfaces müssen sich in einer Assembly befinden, die beim Client und beim Server lokal verfügbar ist. Am besten legst du dir eine Solution/Combine mit drei Projekten an: Client, Interfaces, Server. Client und Server haben Referenzen/Verweise auf das Interfaces-Projekt, es darf aber keine Projekt-Referenzen direkt zwischen Client und Server geben.

Gruss
Pulpapex

A
attaÄhh Themenstarter:in
78 Beiträge seit 2004
vor 18 Jahren

Die Methode GetApplications liefert eine Arraylist mit einem von mir erzeugtem struct ProgramInfo zurück.
Dieses struct ist aber in meinem Interface bekannt welches ja auf Client und Serverseite vorliegt.

Die Methode FillGrid macht nichts anderes als die Daten auszulesen, in ein dataset zu schreiben und anschließen das grid damit zu füllen

public void FillGrid()
{
ArrayList al = PDInterface.GetApplications();

DataSet dsApps = new DataSet();
dsApps.Tables.Add("Applications");

// Spalten werden angelegt
dsApps.Tables[0].Columns.Add("ProgramID");
dsApps.Tables[0].Columns.Add("Name");
dsApps.Tables[0].Columns.Add("Versionnumber");
...

this.gridApplications.DataSource = dsApps;
for(int i=0;i<al.Count;i++)
{
dsApps.Tables[0].Rows.Add(new object[8]);
dsApps.Tables[0].Rows[i][0] = ((ProgramInfo)al[i]).ProgramID;
dsApps.Tables[0].Rows[i][1] = ((ProgramInfo)al[i]).Name;
dsApps.Tables[0].Rows[i][2] = ((ProgramInfo)al[i]).Versionnumber;
...
}
this.gridApplications.DataSource = dsApps;
}

Wobei in der ersten Zeile "ArrayList al = PDInterface.GetApplications();" gleich mein Fehler auftritt.

PDInterface sieht wie folgt aus:

namespace RIS.ProgramDetector.Interfaces
{
#region Datentyp Programminfo
[Serializable]
public struct ProgramInfo
{
public Guid ProgramID; // Eindeutiger Identifikator des Programms
public string Name; // Name des Programms
public string Versionnumber; // Versionsnummer der Programms	
...
}
#endregion
public interface IProgDetector
{
void AddApplication(ProgramInfo pi);
ProgramInfo GetApplication(Guid ProgramID);
ArrayList GetApplications();
void RemoveApplication(Guid ProgramID);
string GetBackupPath();
}

Wie gesagt, es stutz mich ein bischen da es läuft wenn ich den Host als Konsolenanwendung ausführe. Wenn ich ihn aber als plugin starte nicht mehr...

mfg atta

P
939 Beiträge seit 2003
vor 18 Jahren

Auf den zweiten Blick sehe ich jetzt im StackTrace, dass der Fehler auf Serverseite auftritt (der StackTrace ganz oben, danach folgt der StackTrace auf Clientseite). Der Client ruft GetApplications auf. Auf Serverseite soll dann für den Aufruf das registrierte Serviceobjekt geladen und instanziiert werden. Und der Type wird wohl nicht gefunden.

Also das registrierte Serviceobjekt oder ein anderer, verwendeter Type kann auf Serverseite nicht geladen werden. Assembly Programdetector.dll wird nicht gefunden, glaube ich.

Hast du die Projekt-Referenzen zwischen Client- und Server-Projekt schon entfernt?

Gruss
Pulpapex

A
attaÄhh Themenstarter:in
78 Beiträge seit 2004
vor 18 Jahren

Ja,
es gibt keine Referenz zwischen Client und Host.

Du hast recht, das ist das Problem der kann die Programdetecor.dll nicht finden.

Er sucht diese dll ja in

S:/TestApplication/

die befindet sich aber in s:/testapplication/plugin/
welcher Ordner von ihm nicht durchsucht wird. Wenn ich die dll in das Verzeichniss kopiere wo er sie will läufts. So leicht kann ich es mir aber leider nicht machen da die "base" die dlls in dem pluginverzeichniss erwartet.

Was könnte ich denn noch verwenden ausser Remoting mit welcher Methode ich mit möglichts geringem aufwand eine Server und Clientseite schreiben kann. COM+ vielleicht - kenne mich da noch nicht so aus??