Wie können verschiedene Prozesse untereinander kommunizieren?

Reticent

Erfahrenes Mitglied
Hallo zusammen,


habe leider in der Suche nichts passendes gefunden.

Habe folgende Schwierigkeit. Ich habe eine Anwendung programmiert, die mehrere eigene Controls erstellen kann. Jedes kontrol startet eine EXE (auch von mir progr.). Sie starten jeweils einige Threads (momentan Backgroundworkers). Jetzt soll jede gestartene EXE mit dem entsprechenden Control kommunizieren. Jedes Control warten ständig auf eine Meldung von der EXE. Praktisch Meldungen wie "OK", "Nich OK", "Belegt", "Gefundene Nummer : ..." usw. Habe es über Dateie gelöst, aber es läuft instabil. Die Dateizugriffe werden nicht rechtzeitig befreit und es kommt zur Kollisionen.

Kann mir jemand Tips geben? Es geht bestimmt irgendwie mit Threads, aber wie kann ich auf einen Thread zugreifen, der aus einem anderen Prozess gestartet wurde?
Oder gibt es andere Möglichkeiten?


Bin dankbar für jede Hilfe
 
Danke schön niggo,

dotNET-Remoting, WCF passen nicht.

Aber die Sockets. Die kann man doch auch local benutzen. Stimmts?

Sind sie denn sicher und schnell genug? habe noch nie damit gearbeitet.
Nicht, dass ich es programmiere und nachher änliche Probleme wie mit Dateien habe.
 
ähm, ist denn in meinem Fall die Verwendung von Process-Klassen und SendMessage sinnvoll? Oder vielleicht die Anwendungsdomänen könnten das Problem vereinfachen. Hat jemand schon erfahrungen in diesen Bereichen?

Was ist am einfachsten zu implementieren? Oder doch die Sockets?
 
So, ich habe mich entschloßen alles mithilfe von Process-Klasse zu lösen.

Jetzt habe ich allerdings Schwierigkeiten mit Nachrichtenaustausch. Ich möchte mit SendMessage(..) alle nötige Meldungen an den entsprechenden Prozess senden.
Nur wie fange ich die Meldungen ab?
Mit StandartOutput wirds wohl nicht gehen, oder? Soll man hier lieber die Sache mit protected override void WndProc(ref Message m) und WM_COPYDATA anwenden?

Kennt sich jemand aus?
 
Eine nützliche Ergänzung

So,

die Lösund oben ist toll, funktioniert aber nur für gleiche Assembys!

In meinem Fall wollte ich zwei (der mehr) Anwendungen starten und sie untereinander kommunizieren lassen. Hm.. Problem war, dass die Assamblys außerhalb der jeweiligen Anwendungsdomäne nicht gefunden werden konnte. Lösung -> in die Assemblyversion manuel eingreifen. Dazu die CopyData-Class um folgendes erweitern:
Code:
        sealed class OverrideBinder : SerializationBinder
        {
            public override Type BindToType(string assemblyName, string typeName)
            {
                /*
                        // For each assemblyName/typeName that you want to deserialize to
                        // a different type, set typeToDeserialize to the desired type.
                        String oldAssem = "specify old full assembly name here";
                        String oldType = "MyClassName";

                        if (assemblyName == oldAssem && typeName == oldType) 
                        {
                            // To use a type from a different assembly version, 
                            // change the version number.
                            // To do this, uncomment the following line of code.
                            // assemblyName = assemblyName.Replace("1.0.0.0", "2.0.0.0");

                            // To use a different type from the same assembly, 
                            // change the type name.
                            // typeName = "Version2Type";
                        }

                */

                // in my case I only want to override the old assembly/version imprinted in the serialized data with the current assembly/version info so that I can deserialize into the same type, so ...
                assemblyName = Assembly.GetExecutingAssembly().FullName;
                Type typeToDeserialize = null;

                // The following line of code returns the type.
                typeToDeserialize = Type.GetType(String.Format("{0}, {1}", typeName, assemblyName));

                return typeToDeserialize;
            }
        }

und dann WinProc so erweitern:
Code:
		protected override void WndProc (ref System.Windows.Forms.Message m )
		{
			if (m.Msg == WM_COPYDATA)
			{
				COPYDATASTRUCT cds = new COPYDATASTRUCT();
				cds = (COPYDATASTRUCT) Marshal.PtrToStructure(m.LParam, typeof(COPYDATASTRUCT));
				if (cds.cbData > 0)
				{
                    byte[] data = new byte[cds.cbData];				
					Marshal.Copy(cds.lpData, data, 0, cds.cbData);
                    MemoryStream stream = new MemoryStream(data);
                    BinaryFormatter b = new BinaryFormatter();
                    // Allows us to manually control type-casting based on assembly/version and type name
                    b.Binder = new OverrideBinder(); 
                    CopyDataObjectData cdo = (CopyDataObjectData)b.Deserialize(stream);

                    if (channels.Contains(cdo.Channel))
					{
						DataReceivedEventArgs d = new DataReceivedEventArgs(cdo.Channel, cdo.Data, cdo.Sent);
						OnDataReceived(d);
						m.Result = (IntPtr) 1;
					}
				}
			}
			else if (m.Msg == WM_DESTROY)
			{
				// WM_DESTROY fires before OnHandleChanged and is
				// a better place to ensure that we've cleared 
				// everything up.
				channels.OnHandleChange();
				base.OnHandleChange();
			}
			base.WndProc(ref m);
		}
 
Zuletzt bearbeitet:
Zurück