Autor Beitrag
danielf
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1012
Erhaltene Danke: 24

Windows XP
C#, Visual Studio
BeitragVerfasst: Fr 18.06.10 08:30 
Hallo,

ich möchte auf einem Solaris Server ein Script ausführen um die Informationen der Scriptausgabe zu bekommen. Nach dem ich ein bisschen gegooglet habe bin ich auf sharpSSH gestoßen. Allerdings konnte ich keine Befehle absetzen. Deshalb hab ich weiter geschaut und versuche gerade die Umsetzung anhand von plink Aufruf.

Auf meiner Konsole funktioniert das fein:
Zitat:
C:\>"C:\Program Files\plink.exe" -load "application server" "echo blub"
blub


Wenn ich nun aber einen .NET Process starte und die StandardAusgabe auslesen möchte, bekomme ich den Fehler:
Unable to read from standard input: Das Handle ist ungültig. (Mit Arguments="-V"; (für Version) oder ohne Arguments funktioniert es wie gewünscht.

Code:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo = new ProcessStartInfo{
  FileName = @"C:\Program Files\plink.exe",

  Arguments = "-load \"application server\" \"echo blub\"",
  RedirectStandardError = true,
  RedirectStandardOutput = true,
  UseShellExecute = false
};


if (p.Start()) {
string error = p.StandardError.ReadToEnd();
string output = p.StandardOutput.ReadToEnd();

p.WaitForExit();
Console.WriteLine("Error: " + error);
Console.WriteLine("Output: " + output);
}
else { Console.WriteLine("could not start process"); }


Ich bin offen für andere Vorschläge. Wenn ihr mir bei diesem Fehler weiter helfen könnte wäre ich aber auch schonmal dankbar.

Gruß,
Daniel

PS: Habe keine passendere Sparte gefunden, da es sich mit mehreren überschnitten hat (IO&Netzwerk&Basistechnologie).

Edit: Zur Klarstellung ich bekomme keine Exception sondern im string error steht: Unable to read from standard input: Das Handle ist ungültig.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 18.06.10 08:50 
Der Fehler liegt denke ich nicht an deinem Auslesen, sondern daran, dass du keine Input-Pipe zur Verfügung stellt. Deshalb kann plink.exe auch nicht daraus lesen. Ich vermute einmal, dass man bei plink.exe weitere Eingaben machen kann, wenn du sagst, dass es um SSH geht.

user profile icondanielf hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden C#-Quelltext
1:
2:
string error = p.StandardError.ReadToEnd();
string output = p.StandardOutput.ReadToEnd();
Das kann einen Deadlock verursachen. Denn wenn der StandardOutput-Stream voll ist, wartet plink.exe, dass es da wieder hineinschreiben kann. Du aber wartest, dass der Fehler-Stream geschlossen wird.

Deshalb kann es sein, dass dann beide Seiten unendlich lange warten. Eine Ausweichmöglichkeit ist asynchron zu lesen, zumindest einen der beiden Streams.
danielf Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1012
Erhaltene Danke: 24

Windows XP
C#, Visual Studio
BeitragVerfasst: Fr 18.06.10 09:39 
Danke für die Antwort.

Es lag tatsächlich daran, dass ich den StandardInput nicht umgeleitet habe (RedirectStandardInput = true;).

Okay, das mit dem DeathLock war ich noch gar nicht so weit :) (hatte ja nur entweder oder und wenn der Stream nicht started, warted er auch nicht auf das ende von einem).
MSDN hat genau diesen Punkt aufgegriffen und ich werde es wohl auch so machen.
Zitat:
string output = p.StandardOutput.ReadToEnd();
string error = p.StandardError.ReadToEnd();
p.WaitForExit();

In this case, if the child process writes any text to standard error it will block the process, because the parent process cannot read from standard error until it has finished reading from standard output. However, the parent process will not read from standard output until the process ends. A recommended solution to this situation is to create two threads so that your application can read the output of each stream on a separate thread.


Generell würde ich mich aber noch für alternativ Vorschläge interessieren. Weil ich nur ungern ein externen Process starten will. Lieber wäre es mir im Code eingebetten. Aber soweit so gut :D

Vielen Dank und Gruß,