Autor Beitrag
ooTheDomeoo
Hält's aus hier
Beiträge: 1



BeitragVerfasst: Do 27.08.09 14:32 
Hallo, ich habe folgendes Problem und komme einfach nicht mehr weiter.

Ich möchte einen externen Process aus .NET heraus starten und auf die Ausgabe warten. Die Ausgabe passiert asynchron. Damit ich auf entsprechende Aufgabeparameter warten und reagieren kann.

Problem dabei ist, das mein Programmfluss solange warten muss, bis das ergebnis da ist. Dies bekomme ich einfach nicht gelöst.


ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
   public class ProcessHandler
    {


        private System.Diagnostics.Process _cmd = null;
        public event EventHandler OutputEvent;
        public event EventHandler ErrorEvent;

        // Startparameter fuer Prozesse
        private string _processName = String.Empty;
        private string _processParameter = String.Empty;

        private string _lastOutputLine = String.Empty;
        public string LastOutputLine
        {
            get { return _lastOutputLine; }
            set { _lastOutputLine = value; }
        }


        private string _lastCommandLine = String.Empty;
        public string LastCommandLine
        {
            get { return _lastCommandLine; }
            set { _lastCommandLine = value; }
        }


        public string LastErrorLine
        {
            get { return _lastErrorLine; }
            set { _lastErrorLine = value; }
        }


        public ProcessHandler(string processName)
        {
            _processName = processName;

        }

        public ProcessHandler(string processName, string processParameter)
        {
            _processName = processName;
            _processParameter = processParameter; 

        }
        
        public void Start()
        {
            try
            {
                // Prozess erstellen
                _cmd = new System.Diagnostics.Process();
                _cmd.StartInfo.FileName = _processName;

                //optionale Processparameter
                if (!_processParameter.Equals(""))
                {
                    _cmd.StartInfo.Arguments = _processParameter;
                }

                // Input- / Output- und Errorstream initalisieren
                _cmd.StartInfo.RedirectStandardInput = true;
                _cmd.StartInfo.RedirectStandardOutput = true;
                _cmd.StartInfo.RedirectStandardError = true;

                // Einstellungen, damit Stream umgeleitet wird
                _cmd.StartInfo.CreateNoWindow = true;
                _cmd.StartInfo.UseShellExecute = false;

        
                // asynchronse Ausgabe der In- und Outputstreams
                _cmd.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(OutputDataHandler);
                _cmd.ErrorDataReceived += new System.Diagnostics.DataReceivedEventHandler(ErrorDataHandler);

                // Process starten
                _cmd.Start();
               _cmd.StandardInput.AutoFlush = true;
           
               // asynchrones Auslesen starten
               _cmd.BeginOutputReadLine();
               _cmd.BeginErrorReadLine();
         
            }
            catch(System.ComponentModel.Win32Exception)
            {
                throw new Exception("Der Prozess konnte nicht gestartet werden."); 
            }

        }


        public void Stop()
        {
            _cmd.Close();
            _cmd = null
        }


        // Fuehrt ein Shell Statement aus
        public void Execute(string command)
        {
            _lastCommandLine = command; 
            _cmd.StandardInput.WriteLine(command);
            _cmd.StandardInput.Flush(); // Flush scheint nicht zu gehen ...
        }



        private void OutputDataHandler(object sendingProcess, System.Diagnostics.DataReceivedEventArgs outLine)
        {
            if (!String.IsNullOrEmpty(outLine.Data))
            {
                // Event Analysieren
                // Ping analysieren per Regex ob erfolgreich oder nicht und an aufrufende Methode zurückgeben (wie)
               OnOutputEvent(EventArgs.Empty);
            }
        }


        private void ErrorDataHandler(object sendingProcess, System.Diagnostics.DataReceivedEventArgs errorLine)
        {
            if (!String.IsNullOrEmpty(errorLine.Data))
            {
                _lastErrorLine = errorLine.Data; 
            }
        }

    }



die Aufrufende Methode in einer andren Klasse würde z.B. so aussehen

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
private void Test()
{
  //... Programmcode   

   ProcessHandler cmd = new ProcesssHandler("cmd"); 
   cmd.Execute(ping 127.0.0.1); 
 
  // ... Programmcode der je nach Pingantwort reagiert ..... 


}



Mir stellen sich dabei folgende Problem:
- wie Warte ich mit dem Programmablauf auf das Ergebnis
- wie gebe ich das Ergebnis an die Aufrufende Methode zurück ....

(ping) ist nur ein Beispiel, ich will damit beliebige Programme steuern. ping dient zur zum testen

Ich hoffe ihr habt eine Idee für mich.

Moderiert von user profile iconChristian S.: Highlight- durch C#-Tags ersetzt
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: Do 27.08.09 16:08 
Hallo. Ich muss schon sagen. Dein Beitrag ist gefährdet mein Augelicht. ;) Für Code gibt es hier entsprechende Tags.

Aber zu deiner Frage. Da kann ich dir nur wärmstens die MSDNs empfehlen. Fort findest du unter anderem alle Member von Process. Also alle Eigenschaften und Methoden die die Klasse zu bieten. Sowie auch Details zu den einzelnen Membern. Unter anderem auch von WaitForExit. Mit WaitForExit kannst du laut msdns auf das Beenden deines Prozesses warten. Entweder so lange bis er geschlossen wurde oder eine gewisse Anzahl an Millisekunden. Denn wenn du so lange wartest bis die anderen Anwendung zu ist, dann kann es gut passieren, dass deine Anwendung Sekunden/Minuten nicht mehr reagiert. Wenn du aber nur eine gewisse Zeit wartest, dann könntest du dafür sorgen, dass deine Anwendung noch reagiert bzw wäre dein Programm noch in der Lage notfalls den anderen Prozess abzuschießen.

_________________
Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.