0

I have graphviz dot.exe file that I call with parameter -Tpng (output type is png, but I don't care if it is in png, bmp, or any other). I start it in C# code:

ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = path;
psi.UseShellExecute = false;
psi.Arguments = "-Tpng";
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = true;
psi.CreateNoWindow = true;
Process p = Process.Start(psi);

Then, I write input

p.StandardInput.WriteLine(input);

input is defined before, it's a string. Input is valid, tested manually.

Then, I need to read output that graphviz prints into standart output and parse it to Image.

I've tried to read memory stream, but I was either unable to read it, or, after reading, the memory stream was locked (threw exception when tried Image.FromStream(myMemoryStream);). I was able to load output to string

string output = "";
while (true)
{
     string newOutput = p.StandardOutput.ReadLine();
     output += newOutput;
     if (newOutput == String.Empty)
        break;
}

I've tried to parse this string as described in this answer, but it threw exception (string is not valid).

How can I get Image from the dot.exe output?

SoptikHa
  • 437
  • 4
  • 19
  • If it returns binary data reading it as an string will corrupt the result. – Gusman Nov 15 '17 at 19:17
  • Check this, it may help you: https://stackoverflow.com/questions/4143281/capturing-binary-output-from-process-standardoutput – Gusman Nov 15 '17 at 19:18
  • @Gusman Ok, thanks. How can I load the image? Loading it directly via `StandartOutput.BaseStream` takes eternity - loading the stream never ends. Used: `Image.FromStream(p.StandardOutput.BaseStream);` – SoptikHa Nov 15 '17 at 19:19
  • First of all, what do you write to Input? If you're sending also binary data it should be also corrupted. And second, read it like a file in blocks, there are thousands of examples. – Gusman Nov 15 '17 at 19:27
  • @Gusman I just write write string into standart input - `p.StandartInput.WriteLine(stringInput);`. The input is valid, and if I run the file via cmd with parameters `-Tpng -Otest`, new .png file is created, so I know, input is valid. When I do not write the parameter `-O...`, instead of saving to file, the stream is redirected to standart output. And I need to capture it. – SoptikHa Nov 15 '17 at 19:30
  • @Gusman One more thing - the output never ends. When I want to read output as string, there is no end of it, it just returns "" forever. The same with stream I try to read. `p.StandardOutput.EndOfStream` always returns, I'm not at end of stream yet. – SoptikHa Nov 15 '17 at 19:31
  • p.StandardOutput.EndOfStream always returns true or false? – Gusman Nov 15 '17 at 19:35
  • @Gusman it always returns false – SoptikHa Nov 15 '17 at 19:37
  • Then the process isn't terminating, it must be waiting something from the input. Redirect only standard input, let the system create the console window and check what's happening. – Gusman Nov 15 '17 at 19:39
  • Yes, you're right, it waits for another input. What can I do with it? Only read the response and exit when the response is over? Btw here is the part of output I get: `ÔŐŐ©QŁ€¬­J©RĄJţÍ›7dggËţ–¶ii=zýú5oßľ%•`... This is how the very long output looks. – SoptikHa Nov 15 '17 at 19:46
  • Well, you must provide the missing input and then read the stream, `Image.FromStream(p.StandardOutput.BaseStream)` should be enough. – Gusman Nov 15 '17 at 19:49
  • @Gusman Wait, how do you mean it? I do this: 1) I write to standart input 2) I try to read (and the reading state never ends). The program reads unlimited number of inputs untill closed manually. – SoptikHa Nov 15 '17 at 19:51
  • I don't know what you write when you execute it manually, so I have no clue... – Gusman Nov 15 '17 at 19:52
  • Just a guess, after writting to StandardInput close it, the program should consider the stream closing as the end of the input – Gusman Nov 15 '17 at 19:54
  • The program works this way: - I input some text. If it is valid, it throws back stream. If it is not valid (and it **is** valid), it throws back error message. After this, the program waits and just consumes and throws away all the input. – SoptikHa Nov 15 '17 at 19:54
  • @Gusman Do you mean like this? `p.StandardInput.WriteLine(input); p.Close(); return Image.FromStream(p.StandardOutput.BaseStream);` This throws exception, beacuse I try to read stream after the process is closed. When I try to read stream before the process is closed, the stream is infinitelly long. – SoptikHa Nov 15 '17 at 19:57
  • 1
    No, I mean `p.StandardInput.WriteLine(input); p.StandardInput.BaseStream.Close();` – Gusman Nov 15 '17 at 19:58
  • @Gusman It works! Thanks, you saved me :) You can write this as answer and I will mark it (after 5-10 minutes, or what is the cooldown for marking as best answer) – SoptikHa Nov 15 '17 at 20:00

1 Answers1

1

From the comments it seems the program is expecting the StandardInput to be finished before returning the content. Close the StandardInput to achieve it:

p.StandardInput.WriteLine(input); 
p.StandardInput.BaseStream.Close();
Gusman
  • 14,905
  • 2
  • 34
  • 50