Wenn ich mich nicht irre, werden von der ListBox zur Textausgabe die ToString-Methoden der Objekte benutzt. Du musst nur sicherstellen, dass die ToString-Methoden oder Objekte das ausgeben, was du möchtest.
Einen string kannst du einfach durch Add hinzufügen.
Mit dem, was du geschrieben hast, klappt es. Wie sieht denn dein Lösungsansatz aus um es auch auf andersprachigen OS zum Laufen zu bekommen? Spontan würde ich sagen, dass ich mir die Gruppennamen aus der Registry oder WMI hole.
Der IPC-Zugriff wird zwar jetzt nicht mehr verweigert, aber ich bin jetzt auf client seite (kein dienst) auf ein weiteres Problem gestoßen. Und zwar möchte ich eine Methode der Konsolenandwenung beim Event des Remote-Objektes registrieren. Bei eben dieser Registrierung kommt eine SecurityException
Zitat
SecurityException
Der Typ System.DelegateSerializationHolder und die davon abgeleiteten Typen (z.B. System.DelegateSerializationHolder) dürfen in dieser Sicherheitsebene nicht deserialisiert werden.
Hast jemand eine Idee, wie ich an diese Sicherheitsebene komme?
der Marcel
EDIT: Habe jetzt noch folgende Eigenschaften vom provider gesetzt:
Sollen wir das Programm für dich schreiben?
Mir scheint es so, als wenn du dir erst ein paar Grundlagen zu C# (z.B. im guide to C#) aneignen solltest. Dann könntest du die guten Erläuterungen von Noodles umsetzen.
Wo steht denn diese Klasse? auf jeden Fall in einem anderen namespace.
Das ist aber das normale Vorgehen: Assembly referenzieren und namespace evtl. per using einbinden (schau mal im VS --> dein Projekt --> Verweise nach, kannst du mit Menü Projekt --> Verweis hinzufügen hinzufügen, für ein beispiel der using-Direktive: das VS fügt einige usings automatisch am Dateianfang ein)
Ich kenne keinen Weg eine Firewall zu umgehen. Der Sinn einer Firewall ist ja gerade, die Kanäle zu überwachen. Dürfte bestimmt auch von der Firewall abhängen, ob und wie man sie umgehen kann.
Bei meiner wird der gesamte Netzwerkverkehr überwacht (auch http)!
Danke für deine Antwort! Wenn ich wieder an der Entwicklungsumgebung bin, werde ich mir das anschauen. Klingt nach einer guten Lösung! Habe bisher die Kommunikationsrichtung umgedreht und versuche es mit Events zu lösen. Der Test steht aber noch aus. Gut anzunehmen, dass das selbe Problem auftritt
@Maddinel: Nein, das íst nicht so. List<T> ist eine generische Listenimplementierung. Der Vorteil der Generics (neu in .Net2.0) ist gerade der, das casten in object zu vermeiden.
@sebo: Habe es noch nicht ausprobiert, aber wenn es geht, dann so:
List<List<Channel>> test = new List<List<Channel>>();
Ich schreibe zur Zeit an einem Windows-Dienst und habe mir gedacht, per Remoting kommende Exceptions in einer Konsolenanwendung ausgeben zu lassen. Die Kommunikation läuft über IPC. Es wird dabei remote eine Methode der Konsolenanwendung aufgerufen, welcher das Exception-Objekt übergeben wird. Der Windows-Dienst ist dabei der Client und die Konsolenanwendung der Server.
Wenn der Client-Code in einer normalen Anwendung steht, funktioniert er super. Das selbe bringt aber als Windows-Dienst eine RemotingException mit dem Hinweis zutage, dass der Zugriff aud den IPC-Port verweigert wurde.
Es dürfte an Sicherheitseinstellungen liegen, aber ich finde keinen Ansatz an dieser Stelle weiterzukommen. Kann sich das jemand von euch erklären?
Zur Ergänzung den betreffenden Code:
ChannelServices.RegisterChannel(new IpcChannel(), true);
RemotingConfiguration.RegisterWellKnownClientType(typeof(RemoteObject), "ipc://exConsole/exRemote");//Registrierung als Remote-Typ
RemoteObject remote = new RemoteObject();
remote.ShowException(new Exception("Test"));// an dieser Stelle kommt die Exception, wenn dies ein Windows dienst ist, sonst nicht
Original von LaTino
Nicht ganz. Zwangsvorschau nur, wenn ein Beitrag erschienen ist. Also in ca. 2% aller Fälle, eher weniger.
Das erlebe ich schon etwas häufiger. So in etwa 30% der Fälle würde ich das schon schätzen. Daher bin ich dann auch auf die Idee dazu gekommen.
Irgendwelche Extra-Klicks würde ich da auch nicht bevorzugen, weil es nervtötend ist, wenn man nur eine kurze Antwort schreiben möchte. Daher würde ich die Variante bevorzugen, wie sie Rainbird angesprochen hat. Ein kleiner dezenter Hinweis beim Aufrufen der Antwort-Seite, keine Popups u.ä.. Vielleicht nur ein kleines Symbol, so dass die Information, dass man nicht der einzigste ist, vermittelt wird.
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.
Mit meinem Vorschlag meinte ich nur einen Hinweis darauf. Keine erzwungene Vorschau-Seite, mit der man die Bedienung umständlicher macht. Was selbstverständlich ein Problem wäre, ist, wenn der User auf Antworten geht und dann myCsharp verlässt. So hätte man während eines Timeouts dennoch den Hinweis, obwohl eigentlich doch niemand mehr antwortet.
So wie ich den Code interpretieren kann, steht dieser nicht in der 2. Form, sondern in der auf den Click auf ein MenuItem aufgerufenen Methode, welche die 2. Form aufrufen soll. Demzufolge müsstest du auf Form 1 zeichnen.
Besser könntest du auch gleich schreiben:
Form_Gezogene_Monitor anzeigen_Gezogene_Monitor = new Form_Gezogene_Monitor();
Ich würde dir auch dazu raten, erst noch etwas die Grundlagen zu C# und objektorientierter Programmierung durchzuarbeiten (in einem Buch, mindestens jedoch den guide to C#)