#StackBounty: #c# #rest #process #output Why Process.Start produces ansi escape codes

Bounty: 500

I have a strange problem when using Systemd.Diagnostics.Process (on a linux system).

Something outputs ansi escape sequences each time a Process is started.
The sequence is <ESC>[?1h<ESC>= (DECCKM, DECKPAM), but that isn’t produced by the called program, I used pwd here, but the sequence is created with any program, too.

The sequence seems to be produced outside of the process, as the standard and error output streams can’t fetch it.

And the strange thing is, it only occurs after I started a web host!

I build a minimal code example.

using System;
using System.Diagnostics;
using System.Threading;

using Microsoft.Extensions.Hosting;

class Program
{
    static int count;
    static void Main(string[] args)
    {
        CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();

        execTest();

        Host.CreateDefaultBuilder().Build().RunAsync(cancellationTokenSource.Token);
        Thread.Sleep(2000);

        execTest();
        cancellationTokenSource.Cancel();
        Thread.Sleep(2000);

        execTest();
    }

    private static void execTest()
    {
        for (var i = 0; i < 3; i++)
        {
            executeCommand("pwd");
            Console.WriteLine($"Exectest {++count}");
        }
    }

    static void executeCommand(string cmd)
    {
        var process = new Process();
        process.StartInfo.FileName = cmd;
        process.StartInfo.RedirectStandardOutput = true;
        process.StartInfo.RedirectStandardError = true;
        process.Start();
        process.WaitForExit();
    }
}

To see the effect you need a special logging, piping or redirection disables the effect.
And the escape sequences are invisible when xterm interprets them.

Therefore I use script -c myTestProg output.log; cat -A output.log

In the output you can see, that the first three ExecuteTests works as expected, but Exectest 4 to 9 produces this unexpected output.

Exectest 1
Exectest 2
Exectest 3
^[[?1h^[=^[[40m^[[32minfo^[[39m^[[22m^[[49m: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
^[[40m^[[32minfo^[[39m^[[22m^[[49m: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Production
^[[40m^[[32minfo^[[39m^[[22m^[[49m: Microsoft.Hosting.Lifetime[0]
      Content root path: /home/jeb/xx/csharp-test
^[[?1h^[=Exectest 4
^[[?1h^[=Exectest 5
^[[?1h^[=Exectest 6
^[[40m^[[32minfo^[[39m^[[22m^[[49m: Microsoft.Hosting.Lifetime[0]
      Application is shutting down...
^[[?1h^[=Exectest 7
^[[?1h^[=Exectest 8
^[[?1h^[=Exectest 9

My main problem is that my program uses Microsoft.Hosting and calls a Process each second, that results in flooding my log files.
Even when I disable the output logging of the Host by

.ConfigureLogging(loggingBuilder =>
{
  loggingBuilder.ClearProviders();
});

the problem persists.

What causes the output and how to avoid or suppress it?
Where is the relation between a System.Diagnostics.Process and Microsoft.Extensions.Hosting?

PS: The sequence is produces after Process.Start() and the call program ends, but before the WaitForExit is called, tested with some Thread.Sleep(100)


Get this bounty!!!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.