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