Is it possible to log message to cmd.exe in C#/.Net?

后端 未结 5 2101
别跟我提以往
别跟我提以往 2021-01-05 19:19

Is it possible to log message from WinForms app to cmd.exe process started programmatically? I\'ve tried to do all kinds of variations of following code:

pri         


        
相关标签:
5条回答
  • 2021-01-05 19:37

    You have to insert a pause command after printing to the console.

    The process terminates as soon as the command is executing, resulting in the blink you see.

    0 讨论(0)
  • 2021-01-05 19:45

    You're in luck. I just solved this for a code generator toy project I had floating around here.

    Using AttachConsole or AllocConsole Win32 API's you can achieve the result, by just using System.Console.WriteLine (or Read, or Error.WriteLine etc) like you normally would.

    The following snippet figures out when a forms app was started from a Console window, and attaches to it's parent console; If that doesn't work, it will create it's own console, and remember to keep it open (so it doesn't vanish before the user can read the output, for example).

        [DllImport("kernel32.dll")] static extern bool AllocConsole();
        [DllImport("kernel32.dll")] static extern bool AttachConsole(int pw);
        private static bool _hasConsole, _keepConsoleOpen;
        static private void EnsureConsole()
        {
            _hasConsole      =  _hasConsole || AttachConsole(-1);
            _keepConsoleOpen = !_hasConsole || _keepConsoleOpen;
            _hasConsole      =  _hasConsole || AllocConsole();
        }
    
        [STAThread]
        private static void Main(string[] args)
        {
              EnsureConsole();
    
              // the usual stuff -- your program
    
              if (_keepConsoleOpen)
              {
                  Console.WriteLine("(press enter)...");
                  Console.Read();
              }
        }
    
    0 讨论(0)
  • 2021-01-05 19:53

    Not the final answer, but it should help at least a little:

    First of all, declare that process outside your Log routine so it doesn't go out of scope when you want to log more.

    Anyway I tried the following:

    Process process = Process.Start(new ProcessStartInfo("cmd.exe", "/K more") {
      UseShellExecute = false,
      RedirectStandardInput = true,
      RedirectStandardError = true,
      RedirectStandardOutput = false
    });
    
    private void button1_Click(object sender, EventArgs e) {
      Log("Button has been pressed");
      MessageBox.Show(process.StandardError.ReadToEnd());
    }
    
    private void Log(string message) {
      process.StandardInput.WriteLine(message);
    }
    

    After clicking the button, your app will hang (it's waiting for the console to close, ReadToEnd literally reads to the end). When you close the console you will get a messagebox with the error output:

    The handle is invalid.
    The handle is invalid.
    The handle is invalid.
    'Button' is not recognized as an internal or external command,
    operable program or batch file.
    The handle is invalid.
    The handle is invalid.
    

    It seems not to be possible to redirect only the input without redirecting the output when running CMD. I'm not sure why, maybe trying different commandline options will help. I also tried removing the More command and logging "dir" instead:

    Log("dir");
    

    The result was a bit scary:

    The handle is invalid.
    ...
    There is not enough space on the disk.
    The handle is invalid.
    The handle is invalid.
    

    Interesting I must say! Looks like you've opened a can of worms :-)

    0 讨论(0)
  • 2021-01-05 19:59

    I think if you build your project as a "Console Application", you get the console and can still open Windows forms. Create a new project of type "Console Application". Add a Windows Form to the project. In the Main function in Program.cs, instantiate and display the form using this code:

    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
    

    Am not sure if this is the ideal way to do it. But it works.

    0 讨论(0)
  • 2021-01-05 20:00

    As far as I know, I believe you get the CMD opened right. But as soon as the command has been executed the console terminates. Thats normal behaviour.

    If you execute a .bat/.cmd you could script more than one command and if you made a "pause" after the command, you should be able to see what happend before the console terminates.

    0 讨论(0)
提交回复
热议问题