0

I'm trying to redirect the output from a third party terminal (accoreconsole.exe). The output is redirected to a richtextbox.

If I manually type in the accoreconsole.exe from cmd I see the whole output but when I try to start it from my project it's stops at the first letter of the first row.

The first row where the output stops at letter R:

Redirect stdout (file: C:\Users\Marcus\AppData\Local\Temp\accc207883).

When I send something like "ipconfig" it work as it should. I tried to send the output to a .txt file and that worked. But when I tried to apply the text from the .txt file to my textbox it stops at the same letter (R). If I manually opend the .txt file and just save it I can apply it to the textbox.. Wierd?

Any ideas? :) Thanks!

Manually from cmd:

Microsoft Windows [Version 10.0.19043.1348]
(c) Microsoft Corporation. All rights reserved.

C:\Users\Marcus>"C:\Program Files\Autodesk\AutoCAD 2018\accoreconsole.exe"
Redirect stdout (file: C:\Users\Marcus\AppData\Local\Temp\accc207883).
AcCoreConsole: StdOutConsoleMode: processed-output: enabled,auto
AutoCAD Core Engine Console - Copyright 2017 Autodesk, Inc.  All rights reserved. (O.72.0.0)

Execution Path:
C:\Program Files\Autodesk\AutoCAD 2018\accoreconsole.exe

Version Number: O.72.0.0 (UNICODE)

Usage:
AcCoreConsole.exe [/i <input dwg>] /s <script>[/product <product>] [/l <language>] [/isolate <userid> <userDataFolder>] [/readonly] [/p[rofile] <profile>]

Example:
AcCoreConsole.exe /i 8th_floor.dwg /s test.scr /l en-US

C:\Users\Marcus>

Output from my project:

Microsoft Windows [Version 10.0.19043.1348]
(c) Microsoft Corporation. All rights reserved.

C:\Users\Marcus\source\repos\Test_Read_Console_Live\Test_Read_Console_Live\bin\Debug>"C:\Program Files\Autodesk\AutoCAD 2018\accoreconsole.exe"
R

My project code:

using System;
using System.Diagnostics;
using System.Windows.Forms;

namespace Test_Read_Console_Live
{
    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            run();

        }

        public void run()
        {
            Process cmd = new Process()
            {
                StartInfo = new ProcessStartInfo("cmd")
                {
                    RedirectStandardInput = true,
                    RedirectStandardOutput = true,
                    UseShellExecute = false,
                    CreateNoWindow = true,
                    WindowStyle = ProcessWindowStyle.Hidden
                }
            };

            cmd.Start();
            cmd.StandardInput.WriteLine(@"""C:\Program Files\Autodesk\AutoCAD 2018\accoreconsole.exe""");

            cmd.StandardInput.Flush();
            cmd.StandardInput.Close();

            string output = cmd.StandardOutput.ReadToEnd();

            cmd.WaitForExit();
            cmd.Close();
            richTextBox1.Text = output;
        }
    }
}

  • The following may be useful: https://stackoverflow.com/questions/70300508/why-is-the-system-diagnostics-process-exited-event-firing-too-early?noredirect=1#comment124279594_70300508 – Tu deschizi eu inchid Dec 10 '21 at 22:18
  • I tried the code but it did not help. Exacly the same output unfortunately. Thanks anyway! – Marcus Öhman Dec 10 '21 at 22:47
  • Most of the time using "cmd" is unnecessary. In `StartInfo` set `FileName` to `C:\Program Files\Autodesk\AutoCAD 2018\accoreconsole.exe` rather than sending it as input. Look at the URL I mentioned above again, and you'll see how to set the `FileName` property. Then set `RedirectStandardInput = false;` See [ProcessStartInfo.FileName](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.processstartinfo.filename?view=net-6.0) for more information. – Tu deschizi eu inchid Dec 10 '21 at 22:56
  • Tried it but with no luck. The output is "R". – Marcus Öhman Dec 10 '21 at 23:01
  • If you need to use "cmd", the following may be helpful: https://stackoverflow.com/questions/66785877/missing-output-when-redirecting-standard-error-in-c-sharp-net-process/66787416#66787416 – Tu deschizi eu inchid Dec 10 '21 at 23:03
  • You may want to see if you can use the API: http://docs.autodesk.com/ACD/2010/ENU/AutoCAD%20.NET%20Developer%27s%20Guide/index.html – Tu deschizi eu inchid Dec 10 '21 at 23:13
  • @user9938 Tried it. It creates a .txt files in my temp folder with the correct output. But when I try to read "ReadAllText" it only shows "R". – Marcus Öhman Dec 10 '21 at 23:19
  • @user9938 About API. I'm unfortunately don't understand what it does. And I heard it cost money, am I wrong? – Marcus Öhman Dec 10 '21 at 23:21
  • Try `System.Diagnostics.Debug.WriteLine(output);` or you might try using `RichTextBox1.AppendText(output):` – Tu deschizi eu inchid Dec 10 '21 at 23:57
  • @user9938 Same problem with richTextBox1.AppendText(output); – Marcus Öhman Dec 11 '21 at 19:09

2 Answers2

0

Here is a snippet of code I had for calling a DOS-based command terminal program.

Whatever the "exeToRun" program is, such as your AcCoreConsole.exe, and

                var info = new ProcessStartInfo();
                // call the DOS command, ensure the path to 
                // your exe file being called.
                info.FileName = Path.Combine(Environment.CurrentDirectory, exeToRun);
                info.Arguments = stringOfCommandArguments;
                info.RedirectStandardInput = true;
                info.UseShellExecute = false;
                info.RedirectStandardOutput = true;
                info.RedirectStandardError = true;
                // dont "SHOW" the black popup window in background making things look
                // like popup, popup, popup for each call going out to device.
                info.WindowStyle = ProcessWindowStyle.Hidden;
                // the "CreateNoWindow" actually prevents the black DOS window from showing.
                info.CreateNoWindow = true;
                p.StartInfo = info;
                p.Start();

                var sb = new StringBuilder();
                try
                {
                    while (!p.StandardOutput.EndOfStream)
                        sb.AppendLine(p.StandardOutput.ReadLine());

                    while (!p.StandardError.EndOfStream)
                        sb.AppendLine(p.StandardError.ReadLine());
                }
                catch
                {
                    sb.AppendLine("Error/Timeout getting results of request.");
                }

So, after the process.Start, I did a loop of capturing both standardOutput and standardError streams that are part of the process object. Hopefully this can get you over the hump you are working on.

Now, in the string builder, I can assess, write out and debug for later assessment. You can split into your own capture, but again, hopefully just the piece(s) you may be missing.

DRapp
  • 47,638
  • 12
  • 72
  • 142
0

One can also use the dedicated event handlers to process the output and error streams asynchronously:

var startInfo = new ProcessStartInfo();
startInfo.FileName = "app.exe";
startInfo.UseShellExecute = false;
var p = new Process();
p.StartInfo = startInfo;

// Gather standard output in a string buffer
var outSb = new StringBuilder();
startInfo.RedirectStandardOutput = true;
p.OutputDataReceived += new DataReceivedEventHandler((sender, e) => { outSb.AppendLine(e.Data); });

// Gather standard error in a string buffer    
startInfo.RedirectStandardError = true;
var errSb = new StringBuilder();
p.ErrorDataReceived += new DataReceivedEventHandler((sender, e) => { errSb.AppendLine(e.Data); });
    
p.Start();
p.BeginOutputReadLine();
p.BeginErrorReadLine();
p.WaitForExit();

var allOutputLines = outSb.ToString();
var allErrorLines = errSb.ToString();
oli
  • 682
  • 1
  • 12
  • 21