سؤال

I'll try and simplify the problem I'm having. Firstly, I'd like to do this is C# but I'd be perfectly fine with any solution.

There's a console application running in a CMD window on a machine that spits out a new line of text every so often. This application is extremely unstable and sometimes freezes, but the window is still responsive so Windows has no idea.

I want to be able to read the contents of this screen so I can restart the process if there hasn't been an update within a certain threshold. I can do the logic no problem, but how can I tell if the screen has any new data?

I was thinking of screen shotting the window and comparing A to B. I know how to do the screen shots but I was looking for something a bit more elegant and to be honest, something that's not as resource intensive as taking a screen shot (The system is quite taxed whilst this application is running).

The application is launched via a .bat script which is why it resides in a CMD window (though obviously the process itself is accessible).

Thank you for any help and ideas.

هل كانت مفيدة؟

المحلول

Another way to receive console output is attach to the cmd process:

var poList= Process.GetProcesses().Where(process => process.ProcessName.Contains("cmd"));
var a = poList.First();
//FreeConsole();//if you use console application you must free self console
AttachConsole((uint) a.Id);
var err=Marshal.GetLastWin32Error();
var ptr=GetStdHandle(-11);

SMALL_RECT srctReadRect= new SMALL_RECT
{
    Top = 0,Left = 0,Bottom = 1,Right = 79
};
CHAR_INFO[,] chiBuffer = new CHAR_INFO[2,80]; // [2][80]; 
COORD coordBufSize= new COORD
{
     X = 2,Y = 80
};
COORD coordBufCoord = new COORD
{
   X = 0,
   Y = 0
};
bool fSuccess; 
fSuccess = ReadConsoleOutput( ptr,chiBuffer,coordBufSize,chiBuffer coordBufCoord,ref srctReadRect);

all pinvoke functions can be copied form PInvike ConsoleFunctions Let me know if you need mode detailed information

نصائح أخرى

If you able to start batch file from C# wrapper application, create process via C# app:

    Process proc = new Process();
    proc.StartInfo = new ProcessStartInfo("d:\\batch.bat")
    {
        RedirectStandardOutput = true,
        UseShellExecute = false
    };
    bool updated = false;
    Timer waitTimer= new Timer(state =>
    {
        if (!updated)
        {
            proc.Kill();
            return;
        }
        updated = false;

    });
    waitTimer.Change(1000, 1000);
    proc.Start();
    while (! proc.StandardOutput.EndOfStream)
    {
        var line = proc.StandardOutput.ReadLine();
        updated = true;
        Console.WriteLine(line);
    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top