Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. How to redirect WriteFile func writes to console

How to redirect WriteFile func writes to console

Scheduled Pinned Locked Moved C / C++ / MFC
tutorialquestioncsharpwpfhelp
21 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Offline
    L Offline
    Lukasz Gesieniec
    wrote on last edited by
    #1

    I have a problem with redirect console app output and input. The problem is that any example I found does not work for me. I want to develop WPF GUI for a console app. This is the example code to redirect output: ProcessStartInfo start = new ProcessStartInfo(); start.FileName = "C:\\myapp.exe"; // Specify exe name. start.UseShellExecute = false; start.RedirectStandardOutput = true; using (Process process = Process.Start(start)) { using (StreamReader reader = process.StandardOutput) { string result = reader.ReadToEnd(); Console.Write(result); } } So I did some reverse engineering on the console app and I found that this app is compiled using Microsoft Visual C 6.0. The app uses WriteFile to output to the console and first argument passed to the function equals 7. I wrote the example code: #include "stdafx.h" #include int main() { AllocConsole(); HANDLE hStdout; HANDLE hStdout2 = (HANDLE)0x00000007; char s[] = "Hello world !\r\n"; char s2[] = "Hello world !CONOUT\r\n"; char s3[] = "test\r\n"; DWORD dwBytesWritten; HANDLE hScreenBuffer = CreateFileA("CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); hStdout = GetStdHandle(STD_OUTPUT_HANDLE); // hStdout equals 7 after this call WriteFile(hStdout2, s3, (DWORD)strlen(s3), &dwBytesWritten, NULL); //prints always to console WriteFile((HANDLE)0x00000007, s3, (DWORD)strlen(s3), &dwBytesWritten, NULL); //prints always to console WriteFile(hStdout, s, (DWORD)strlen(s), &dwBytesWritten, NULL); //can be redirected; example TestCON.exe > test.txt WriteFile(hScreenBuffer, s2, (DWORD)strlen(s2), &dwBytesWritten, NULL);//prints always to console FreeConsole(); return 0; } I do not understand why this: WriteFile(hStdout, s, (DWORD)strlen(s), &dwBytesWritten, NULL); (hStdout equals 7 checked by debuger) is redirected using my above example code or TestCON.exe > test.txt but this WriteFile((HANDLE)0x00000007, s3, (DWORD)strlen(s3), &dwBytesWritten, NULL); is printed always on the console. Any suggestions how can I redirect any output to my GUI app?

    L 1 Reply Last reply
    0
    • L Lukasz Gesieniec

      I have a problem with redirect console app output and input. The problem is that any example I found does not work for me. I want to develop WPF GUI for a console app. This is the example code to redirect output: ProcessStartInfo start = new ProcessStartInfo(); start.FileName = "C:\\myapp.exe"; // Specify exe name. start.UseShellExecute = false; start.RedirectStandardOutput = true; using (Process process = Process.Start(start)) { using (StreamReader reader = process.StandardOutput) { string result = reader.ReadToEnd(); Console.Write(result); } } So I did some reverse engineering on the console app and I found that this app is compiled using Microsoft Visual C 6.0. The app uses WriteFile to output to the console and first argument passed to the function equals 7. I wrote the example code: #include "stdafx.h" #include int main() { AllocConsole(); HANDLE hStdout; HANDLE hStdout2 = (HANDLE)0x00000007; char s[] = "Hello world !\r\n"; char s2[] = "Hello world !CONOUT\r\n"; char s3[] = "test\r\n"; DWORD dwBytesWritten; HANDLE hScreenBuffer = CreateFileA("CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); hStdout = GetStdHandle(STD_OUTPUT_HANDLE); // hStdout equals 7 after this call WriteFile(hStdout2, s3, (DWORD)strlen(s3), &dwBytesWritten, NULL); //prints always to console WriteFile((HANDLE)0x00000007, s3, (DWORD)strlen(s3), &dwBytesWritten, NULL); //prints always to console WriteFile(hStdout, s, (DWORD)strlen(s), &dwBytesWritten, NULL); //can be redirected; example TestCON.exe > test.txt WriteFile(hScreenBuffer, s2, (DWORD)strlen(s2), &dwBytesWritten, NULL);//prints always to console FreeConsole(); return 0; } I do not understand why this: WriteFile(hStdout, s, (DWORD)strlen(s), &dwBytesWritten, NULL); (hStdout equals 7 checked by debuger) is redirected using my above example code or TestCON.exe > test.txt but this WriteFile((HANDLE)0x00000007, s3, (DWORD)strlen(s3), &dwBytesWritten, NULL); is printed always on the console. Any suggestions how can I redirect any output to my GUI app?

      L Offline
      L Offline
      leon de boer
      wrote on last edited by
      #2

      It's in just about every AllocConsole example on the net

      AllocConsole(); //Allocate a console
      freopen("CONIN$", "r", stdin); // Redirect standard in
      freopen("CONOUT$", "w", stdout); // Redirect standard out
      freopen("CONOUT$", "w", stderr); // Redirect standard error
      setbuf(stdout, NULL); // Clear the buffer from standard out

      You may want to use the new freopen_s etc calls to avoid the warning. CONIN$ and CONOUT$ are the console input and outputs associated to your program as distinct from the standard handles. You may also care to read about console handles versus standard handles Console Handles - Windows Console | Microsoft Docs[^] That will give you the more modern way to do it via SetStdHandle and you should understand it now.

      In vino veritas

      L 1 Reply Last reply
      0
      • L leon de boer

        It's in just about every AllocConsole example on the net

        AllocConsole(); //Allocate a console
        freopen("CONIN$", "r", stdin); // Redirect standard in
        freopen("CONOUT$", "w", stdout); // Redirect standard out
        freopen("CONOUT$", "w", stderr); // Redirect standard error
        setbuf(stdout, NULL); // Clear the buffer from standard out

        You may want to use the new freopen_s etc calls to avoid the warning. CONIN$ and CONOUT$ are the console input and outputs associated to your program as distinct from the standard handles. You may also care to read about console handles versus standard handles Console Handles - Windows Console | Microsoft Docs[^] That will give you the more modern way to do it via SetStdHandle and you should understand it now.

        In vino veritas

        L Offline
        L Offline
        Lukasz Gesieniec
        wrote on last edited by
        #3

        The problem is that I have only binary version console app that writes directly to the console. Can you show me more completed code because maybe I miss something?

        L 2 Replies Last reply
        0
        • L Lukasz Gesieniec

          The problem is that I have only binary version console app that writes directly to the console. Can you show me more completed code because maybe I miss something?

          L Offline
          L Offline
          leon de boer
          wrote on last edited by
          #4

          That isn't a problem you have redirected the standard file handle to the windows console created. Try to read the console handles document and understand what is happening. Visual studio does exactly that it executes a windows binary file and redirects the output to the console plane that is in visual studio. Your binary file will use standard input/output and it's been redirected up to your console window. You can also directly redirect spawned child applications Creating a Child Process with Redirected Input and Output (Windows)[^] That is if you want to do something like shellexecute a program and grab the output.

          In vino veritas

          1 Reply Last reply
          0
          • L Lukasz Gesieniec

            The problem is that I have only binary version console app that writes directly to the console. Can you show me more completed code because maybe I miss something?

            L Offline
            L Offline
            leon de boer
            wrote on last edited by
            #5

            here see if this helps It executes IPConfig and executes command.com to display a directory all redirected up to the windows console.

            #include
            #include
            #include
            #include
            #include

            using namespace std;

            FILE* OutStream;
            FILE* InStream;
            FILE* ErrStream;

            /*---------------------------------------------------------------------------
            Application handler.
            ---------------------------------------------------------------------------*/
            LRESULT CALLBACK GUIDemoHandler (HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
            switch (Msg) {
            case WM_CREATE:
            AllocConsole(); //Allocate a console
            freopen_s(&InStream, "CONIN$", "r", stdin); // Redirect standard in
            freopen_s(&OutStream, "CONOUT$", "w", stdout); // Redirect standard out
            freopen_s(&ErrStream, "CONOUT$", "w", stderr); // Redirect standard error
            break;
            case WM_DESTROY: // WM_DESTROY MESSAGE
            FreeConsole();
            PostQuitMessage(0); // Post quit message
            break;

            	default: return DefWindowProc(Wnd, Msg, wParam, lParam);	// Default handler
            };// end switch case
            return 0;
            

            }

            int SystemCapture(
            TCHAR* CmdLine, //Command Line
            TCHAR* CmdRunDir, //set to '.' for current directory
            uint32_t& RetCode) //Return Exit Code
            {
            int Success;
            SECURITY_ATTRIBUTES security_attributes;
            HANDLE stdout_rd = INVALID_HANDLE_VALUE;
            HANDLE stdout_wr = INVALID_HANDLE_VALUE;
            PROCESS_INFORMATION process_info = { 0 };
            STARTUPINFO startup_info = { 0 };
            thread stdout_thread;

            security\_attributes.nLength = sizeof(SECURITY\_ATTRIBUTES);
            security\_attributes.bInheritHandle = TRUE;
            security\_attributes.lpSecurityDescriptor = nullptr;
            
            if (!CreatePipe(&stdout\_rd, &stdout\_wr, &security\_attributes, 0) ||
            	!SetHandleInformation(stdout\_rd, HANDLE\_FLAG\_INHERIT, 0)) {
            	return -1;
            }
            
            startup\_info.cb = sizeof(STARTUPINFO);
            startup\_info.hStdInput = 0;
            startup\_info.hStdOutput = stdout\_wr;
            startup\_info.hStdError = 0;
            
            if (stdout\_rd)
            	startup\_info.dwFlags |= STARTF\_USESTDHANDLES;
            
            Success = CreateProcess(
            	nullptr,
            	CmdLine,
            	nullptr,
            	nullptr,
            	TRUE,
            	0,
            	nullptr,
            	CmdRunDir,
            	&startup\_info,
            	&process\_info
            );
            CloseHandle(stdout\_wr);
            
            if (!Success) {
            	CloseHandle(process\_info.hProcess);
            	CloseHandle(process\_info.hThread);
            	CloseHandle(stdout\_rd);
            	return -4;
            }
            else {
            	CloseHandle(process\_info.hT
            
            L 1 Reply Last reply
            0
            • L leon de boer

              here see if this helps It executes IPConfig and executes command.com to display a directory all redirected up to the windows console.

              #include
              #include
              #include
              #include
              #include

              using namespace std;

              FILE* OutStream;
              FILE* InStream;
              FILE* ErrStream;

              /*---------------------------------------------------------------------------
              Application handler.
              ---------------------------------------------------------------------------*/
              LRESULT CALLBACK GUIDemoHandler (HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
              switch (Msg) {
              case WM_CREATE:
              AllocConsole(); //Allocate a console
              freopen_s(&InStream, "CONIN$", "r", stdin); // Redirect standard in
              freopen_s(&OutStream, "CONOUT$", "w", stdout); // Redirect standard out
              freopen_s(&ErrStream, "CONOUT$", "w", stderr); // Redirect standard error
              break;
              case WM_DESTROY: // WM_DESTROY MESSAGE
              FreeConsole();
              PostQuitMessage(0); // Post quit message
              break;

              	default: return DefWindowProc(Wnd, Msg, wParam, lParam);	// Default handler
              };// end switch case
              return 0;
              

              }

              int SystemCapture(
              TCHAR* CmdLine, //Command Line
              TCHAR* CmdRunDir, //set to '.' for current directory
              uint32_t& RetCode) //Return Exit Code
              {
              int Success;
              SECURITY_ATTRIBUTES security_attributes;
              HANDLE stdout_rd = INVALID_HANDLE_VALUE;
              HANDLE stdout_wr = INVALID_HANDLE_VALUE;
              PROCESS_INFORMATION process_info = { 0 };
              STARTUPINFO startup_info = { 0 };
              thread stdout_thread;

              security\_attributes.nLength = sizeof(SECURITY\_ATTRIBUTES);
              security\_attributes.bInheritHandle = TRUE;
              security\_attributes.lpSecurityDescriptor = nullptr;
              
              if (!CreatePipe(&stdout\_rd, &stdout\_wr, &security\_attributes, 0) ||
              	!SetHandleInformation(stdout\_rd, HANDLE\_FLAG\_INHERIT, 0)) {
              	return -1;
              }
              
              startup\_info.cb = sizeof(STARTUPINFO);
              startup\_info.hStdInput = 0;
              startup\_info.hStdOutput = stdout\_wr;
              startup\_info.hStdError = 0;
              
              if (stdout\_rd)
              	startup\_info.dwFlags |= STARTF\_USESTDHANDLES;
              
              Success = CreateProcess(
              	nullptr,
              	CmdLine,
              	nullptr,
              	nullptr,
              	TRUE,
              	0,
              	nullptr,
              	CmdRunDir,
              	&startup\_info,
              	&process\_info
              );
              CloseHandle(stdout\_wr);
              
              if (!Success) {
              	CloseHandle(process\_info.hProcess);
              	CloseHandle(process\_info.hThread);
              	CloseHandle(stdout\_rd);
              	return -4;
              }
              else {
              	CloseHandle(process\_info.hT
              
              L Offline
              L Offline
              Lukasz Gesieniec
              wrote on last edited by
              #6

              Thank you for the example code. The effect is that output from my console app is redirected when this app quits, but not when this app is running.

              L 2 Replies Last reply
              0
              • L Lukasz Gesieniec

                Thank you for the example code. The effect is that output from my console app is redirected when this app quits, but not when this app is running.

                L Offline
                L Offline
                leon de boer
                wrote on last edited by
                #7

                Your statement is also somewhat nonsensical in that when my sample app quits it destroys the console you wouldn't see it (see WM_DESTROY). So I can only assume you mean your app you are running wont display until it exits???? So are you wanting live output keeping the app alive ??? You will have to spawn the thread before the call at the moment the program is CreateProcess Process output That is the app must complete it's setup to deal with normal DOS like command files. If it doesn't complete then the app will still be on the screen so why do you want it redirected to the console?????

                In vino veritas

                1 Reply Last reply
                0
                • L Lukasz Gesieniec

                  Thank you for the example code. The effect is that output from my console app is redirected when this app quits, but not when this app is running.

                  L Offline
                  L Offline
                  leon de boer
                  wrote on last edited by
                  #8

                  Okay so this spawns the thread before it executes the command passed in. It should spit the console even if the command doesn't terminate, which I still find strange.

                  #include
                  #include
                  #include
                  #include

                  FILE* OutStream;
                  FILE* InStream;
                  FILE* ErrStream;

                  struct execData {
                  TCHAR* CmdLine;
                  TCHAR* CmdRunDir;
                  PROCESS_INFORMATION process_info;
                  STARTUPINFO startup_info;
                  };

                  struct execData data = { 0 };

                  /*---------------------------------------------------------------------------
                  Application handler.
                  ---------------------------------------------------------------------------*/
                  LRESULT CALLBACK GUIDemoHandler (HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
                  switch (Msg) {
                  case WM_CREATE:
                  AllocConsole(); //Allocate a console
                  freopen_s(&InStream, "CONIN$", "r", stdin); // Redirect standard in
                  freopen_s(&OutStream, "CONOUT$", "w", stdout); // Redirect standard out
                  freopen_s(&ErrStream, "CONOUT$", "w", stderr); // Redirect standard error
                  break;
                  case WM_DESTROY: // WM_DESTROY MESSAGE
                  if (data.process_info.hProcess) TerminateProcess(data.process_info.hProcess, 0);
                  FreeConsole();
                  PostQuitMessage(0); // Post quit message
                  break;

                  	default: return DefWindowProc(Wnd, Msg, wParam, lParam);	// Default handler
                  };// end switch case
                  return 0;
                  

                  }

                  DWORD WINAPI ExecThreadFunction(LPVOID lpParam)
                  {
                  int Success;
                  struct execData* data = (struct execData*)lpParam;
                  Success = CreateProcess(
                  nullptr,
                  data->CmdLine,
                  nullptr,
                  nullptr,
                  TRUE,
                  0,
                  nullptr,
                  data->CmdRunDir,
                  &data->startup_info,
                  &data->process_info
                  );

                  if (!Success) {
                  	CloseHandle(data->process\_info.hProcess);
                  	CloseHandle(data->process\_info.hThread);
                  	return -4;
                  }
                  else {
                  	CloseHandle(data->process\_info.hThread);
                  }
                  
                  WaitForSingleObject(data->process\_info.hProcess, INFINITE);
                  
                  CloseHandle(data->process\_info.hProcess);
                  
                  data->process\_info.hProcess = 0;
                  return (0);
                  

                  }

                  int SystemCapture(
                  TCHAR* CmdLine, //Command Line
                  TCHAR* CmdRunDir) //set to '.' for current directory
                  {
                  SECURITY_ATTRIBUTES security_attributes;

                  data.CmdLine = CmdLine;
                  data.CmdRunDir = CmdRunDir;
                  security\_attributes.nLength = sizeof(SECURITY\_ATTRIBUTES);
                  security\_attributes.bInheritHandle = TRUE;
                  security\_attributes.lpSecurityDescriptor = nullptr;
                  data.startup\_info.cb = sizeof(STARTUPINFO);
                  data.startup\_info.hStdInput = 0;
                  data.startu
                  
                  L 2 Replies Last reply
                  0
                  • L leon de boer

                    Okay so this spawns the thread before it executes the command passed in. It should spit the console even if the command doesn't terminate, which I still find strange.

                    #include
                    #include
                    #include
                    #include

                    FILE* OutStream;
                    FILE* InStream;
                    FILE* ErrStream;

                    struct execData {
                    TCHAR* CmdLine;
                    TCHAR* CmdRunDir;
                    PROCESS_INFORMATION process_info;
                    STARTUPINFO startup_info;
                    };

                    struct execData data = { 0 };

                    /*---------------------------------------------------------------------------
                    Application handler.
                    ---------------------------------------------------------------------------*/
                    LRESULT CALLBACK GUIDemoHandler (HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
                    switch (Msg) {
                    case WM_CREATE:
                    AllocConsole(); //Allocate a console
                    freopen_s(&InStream, "CONIN$", "r", stdin); // Redirect standard in
                    freopen_s(&OutStream, "CONOUT$", "w", stdout); // Redirect standard out
                    freopen_s(&ErrStream, "CONOUT$", "w", stderr); // Redirect standard error
                    break;
                    case WM_DESTROY: // WM_DESTROY MESSAGE
                    if (data.process_info.hProcess) TerminateProcess(data.process_info.hProcess, 0);
                    FreeConsole();
                    PostQuitMessage(0); // Post quit message
                    break;

                    	default: return DefWindowProc(Wnd, Msg, wParam, lParam);	// Default handler
                    };// end switch case
                    return 0;
                    

                    }

                    DWORD WINAPI ExecThreadFunction(LPVOID lpParam)
                    {
                    int Success;
                    struct execData* data = (struct execData*)lpParam;
                    Success = CreateProcess(
                    nullptr,
                    data->CmdLine,
                    nullptr,
                    nullptr,
                    TRUE,
                    0,
                    nullptr,
                    data->CmdRunDir,
                    &data->startup_info,
                    &data->process_info
                    );

                    if (!Success) {
                    	CloseHandle(data->process\_info.hProcess);
                    	CloseHandle(data->process\_info.hThread);
                    	return -4;
                    }
                    else {
                    	CloseHandle(data->process\_info.hThread);
                    }
                    
                    WaitForSingleObject(data->process\_info.hProcess, INFINITE);
                    
                    CloseHandle(data->process\_info.hProcess);
                    
                    data->process\_info.hProcess = 0;
                    return (0);
                    

                    }

                    int SystemCapture(
                    TCHAR* CmdLine, //Command Line
                    TCHAR* CmdRunDir) //set to '.' for current directory
                    {
                    SECURITY_ATTRIBUTES security_attributes;

                    data.CmdLine = CmdLine;
                    data.CmdRunDir = CmdRunDir;
                    security\_attributes.nLength = sizeof(SECURITY\_ATTRIBUTES);
                    security\_attributes.bInheritHandle = TRUE;
                    security\_attributes.lpSecurityDescriptor = nullptr;
                    data.startup\_info.cb = sizeof(STARTUPINFO);
                    data.startup\_info.hStdInput = 0;
                    data.startu
                    
                    L Offline
                    L Offline
                    Lukasz Gesieniec
                    wrote on last edited by
                    #9

                    I am checking it using test app with WriteFile function and it works. But I will check it using target app tomorrow because it needs some hardware to work. Thanks

                    1 Reply Last reply
                    0
                    • L leon de boer

                      Okay so this spawns the thread before it executes the command passed in. It should spit the console even if the command doesn't terminate, which I still find strange.

                      #include
                      #include
                      #include
                      #include

                      FILE* OutStream;
                      FILE* InStream;
                      FILE* ErrStream;

                      struct execData {
                      TCHAR* CmdLine;
                      TCHAR* CmdRunDir;
                      PROCESS_INFORMATION process_info;
                      STARTUPINFO startup_info;
                      };

                      struct execData data = { 0 };

                      /*---------------------------------------------------------------------------
                      Application handler.
                      ---------------------------------------------------------------------------*/
                      LRESULT CALLBACK GUIDemoHandler (HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
                      switch (Msg) {
                      case WM_CREATE:
                      AllocConsole(); //Allocate a console
                      freopen_s(&InStream, "CONIN$", "r", stdin); // Redirect standard in
                      freopen_s(&OutStream, "CONOUT$", "w", stdout); // Redirect standard out
                      freopen_s(&ErrStream, "CONOUT$", "w", stderr); // Redirect standard error
                      break;
                      case WM_DESTROY: // WM_DESTROY MESSAGE
                      if (data.process_info.hProcess) TerminateProcess(data.process_info.hProcess, 0);
                      FreeConsole();
                      PostQuitMessage(0); // Post quit message
                      break;

                      	default: return DefWindowProc(Wnd, Msg, wParam, lParam);	// Default handler
                      };// end switch case
                      return 0;
                      

                      }

                      DWORD WINAPI ExecThreadFunction(LPVOID lpParam)
                      {
                      int Success;
                      struct execData* data = (struct execData*)lpParam;
                      Success = CreateProcess(
                      nullptr,
                      data->CmdLine,
                      nullptr,
                      nullptr,
                      TRUE,
                      0,
                      nullptr,
                      data->CmdRunDir,
                      &data->startup_info,
                      &data->process_info
                      );

                      if (!Success) {
                      	CloseHandle(data->process\_info.hProcess);
                      	CloseHandle(data->process\_info.hThread);
                      	return -4;
                      }
                      else {
                      	CloseHandle(data->process\_info.hThread);
                      }
                      
                      WaitForSingleObject(data->process\_info.hProcess, INFINITE);
                      
                      CloseHandle(data->process\_info.hProcess);
                      
                      data->process\_info.hProcess = 0;
                      return (0);
                      

                      }

                      int SystemCapture(
                      TCHAR* CmdLine, //Command Line
                      TCHAR* CmdRunDir) //set to '.' for current directory
                      {
                      SECURITY_ATTRIBUTES security_attributes;

                      data.CmdLine = CmdLine;
                      data.CmdRunDir = CmdRunDir;
                      security\_attributes.nLength = sizeof(SECURITY\_ATTRIBUTES);
                      security\_attributes.bInheritHandle = TRUE;
                      security\_attributes.lpSecurityDescriptor = nullptr;
                      data.startup\_info.cb = sizeof(STARTUPINFO);
                      data.startup\_info.hStdInput = 0;
                      data.startu
                      
                      L Offline
                      L Offline
                      Lukasz Gesieniec
                      wrote on last edited by
                      #10

                      This code is working. Now I will try to analyze outputs and build GUI. I am not sure if can I use the code in C# WPF application. If not I will try to build GUI using Win API starting from your examples. Thank you.

                      L 1 Reply Last reply
                      0
                      • L Lukasz Gesieniec

                        This code is working. Now I will try to analyze outputs and build GUI. I am not sure if can I use the code in C# WPF application. If not I will try to build GUI using Win API starting from your examples. Thank you.

                        L Offline
                        L Offline
                        leon de boer
                        wrote on last edited by
                        #11

                        It's a simple background worker thread it will work without issue in a C# WPF application. How to: Use a Background Worker[^] Inside the worker thread you want a standard command execute

                        static void runCommand() {
                        //* Create your Process
                        Process process = new Process();
                        process.StartInfo.FileName = "cmd.exe";
                        process.StartInfo.Arguments = "/c yourfile.exe";
                        process.StartInfo.UseShellExecute = false;
                        process.StartInfo.RedirectStandardOutput = true;
                        process.StartInfo.RedirectStandardError = true;
                        //* Set your output and error (asynchronous) handlers
                        process.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);
                        process.ErrorDataReceived += new DataReceivedEventHandler(OutputHandler);
                        //* Start process and handlers
                        process.Start();
                        process.BeginOutputReadLine();
                        process.BeginErrorReadLine();
                        process.WaitForExit();
                        }
                        static void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine) {
                        //* Do your stuff with the output (write to console/log/StringBuilder)
                        Console.WriteLine(outLine.Data);
                        }

                        In vino veritas

                        L 1 Reply Last reply
                        0
                        • L leon de boer

                          It's a simple background worker thread it will work without issue in a C# WPF application. How to: Use a Background Worker[^] Inside the worker thread you want a standard command execute

                          static void runCommand() {
                          //* Create your Process
                          Process process = new Process();
                          process.StartInfo.FileName = "cmd.exe";
                          process.StartInfo.Arguments = "/c yourfile.exe";
                          process.StartInfo.UseShellExecute = false;
                          process.StartInfo.RedirectStandardOutput = true;
                          process.StartInfo.RedirectStandardError = true;
                          //* Set your output and error (asynchronous) handlers
                          process.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);
                          process.ErrorDataReceived += new DataReceivedEventHandler(OutputHandler);
                          //* Start process and handlers
                          process.Start();
                          process.BeginOutputReadLine();
                          process.BeginErrorReadLine();
                          process.WaitForExit();
                          }
                          static void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine) {
                          //* Do your stuff with the output (write to console/log/StringBuilder)
                          Console.WriteLine(outLine.Data);
                          }

                          In vino veritas

                          L Offline
                          L Offline
                          Lukasz Gesieniec
                          wrote on last edited by
                          #12

                          I do simple test and problem is the same as before. Only when console app quits OutputHandler is executed and then I can read every line by line that app prints during running. Furthermore, it seems that StandardInput is not redirected because click on the button does not quit the app. App quits when 'e' key is pressed in the console window.

                          public partial class MainWindow : Window
                          {
                              Process process = new Process();
                          
                              public MainWindow()
                              {
                                  InitializeComponent();
                                  runCommand();
                              }
                          
                              private void button\_Click(object sender, RoutedEventArgs e)
                              {
                                  textBox.Text += "test\\r\\n";
                                  process.StandardInput.Write('e');
                              }
                          
                              void runCommand()
                              {
                                  //\* Create your Process
                                  
                                  process.StartInfo.FileName = "c:\\\\ConsoleApp.exe";
                                  process.StartInfo.Arguments = ".";
                                  process.StartInfo.UseShellExecute = false;
                                  process.StartInfo.RedirectStandardOutput = true;
                                  process.StartInfo.RedirectStandardError = true;
                                  process.StartInfo.RedirectStandardInput = true;
                                  //\* Set your output and error (asynchronous) handlers
                                  process.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);
                                  process.ErrorDataReceived += new DataReceivedEventHandler(OutputHandler);
                                  
                                  //\* Start process and handlers
                                  process.Start();
                                  process.BeginOutputReadLine();
                                  process.BeginErrorReadLine();
                                  //            process.WaitForExit();
                              }
                              void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
                              {
                                  //\* Do your stuff with the output (write to console/log/StringBuilder)
                                  Console.WriteLine(outLine);
                              }
                          }
                          
                          L 2 Replies Last reply
                          0
                          • L Lukasz Gesieniec

                            I do simple test and problem is the same as before. Only when console app quits OutputHandler is executed and then I can read every line by line that app prints during running. Furthermore, it seems that StandardInput is not redirected because click on the button does not quit the app. App quits when 'e' key is pressed in the console window.

                            public partial class MainWindow : Window
                            {
                                Process process = new Process();
                            
                                public MainWindow()
                                {
                                    InitializeComponent();
                                    runCommand();
                                }
                            
                                private void button\_Click(object sender, RoutedEventArgs e)
                                {
                                    textBox.Text += "test\\r\\n";
                                    process.StandardInput.Write('e');
                                }
                            
                                void runCommand()
                                {
                                    //\* Create your Process
                                    
                                    process.StartInfo.FileName = "c:\\\\ConsoleApp.exe";
                                    process.StartInfo.Arguments = ".";
                                    process.StartInfo.UseShellExecute = false;
                                    process.StartInfo.RedirectStandardOutput = true;
                                    process.StartInfo.RedirectStandardError = true;
                                    process.StartInfo.RedirectStandardInput = true;
                                    //\* Set your output and error (asynchronous) handlers
                                    process.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);
                                    process.ErrorDataReceived += new DataReceivedEventHandler(OutputHandler);
                                    
                                    //\* Start process and handlers
                                    process.Start();
                                    process.BeginOutputReadLine();
                                    process.BeginErrorReadLine();
                                    //            process.WaitForExit();
                                }
                                void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
                                {
                                    //\* Do your stuff with the output (write to console/log/StringBuilder)
                                    Console.WriteLine(outLine);
                                }
                            }
                            
                            L Offline
                            L Offline
                            leon de boer
                            wrote on last edited by
                            #13

                            Yes because you didn't put it in a worker thread :-) You need runCommand() to be in a worker thread .. it has to execute in the background so you can keep the WPF framework running in the foreground. Look back at the windows code I had to do the same thing the CreateProcess(...) is inside a function which is spawned into it's own thread via CreateThread. Unfortunately I don't use C# enough to know the code for making a worker thread off the top of my head. I actually don't have the WPF framework installed on my VisualStudio at the moment to work it out. Basically however we can describe it 1.) everything in runCommand() needs to go inside the worker thread start function .. when the thread starts it runs the app 2.) When the app finishes or your WPF app finishes you need to close the worker thread (LOOK at WM_DESTROY on the windows code) So basically this worker thread will be chugging along in the background running the app but your program comes back to you to continue on to run the WPF framework. So you job is to work out how to make a WPF worker thread and incorporate the code :-)

                            In vino veritas

                            1 Reply Last reply
                            0
                            • L Lukasz Gesieniec

                              I do simple test and problem is the same as before. Only when console app quits OutputHandler is executed and then I can read every line by line that app prints during running. Furthermore, it seems that StandardInput is not redirected because click on the button does not quit the app. App quits when 'e' key is pressed in the console window.

                              public partial class MainWindow : Window
                              {
                                  Process process = new Process();
                              
                                  public MainWindow()
                                  {
                                      InitializeComponent();
                                      runCommand();
                                  }
                              
                                  private void button\_Click(object sender, RoutedEventArgs e)
                                  {
                                      textBox.Text += "test\\r\\n";
                                      process.StandardInput.Write('e');
                                  }
                              
                                  void runCommand()
                                  {
                                      //\* Create your Process
                                      
                                      process.StartInfo.FileName = "c:\\\\ConsoleApp.exe";
                                      process.StartInfo.Arguments = ".";
                                      process.StartInfo.UseShellExecute = false;
                                      process.StartInfo.RedirectStandardOutput = true;
                                      process.StartInfo.RedirectStandardError = true;
                                      process.StartInfo.RedirectStandardInput = true;
                                      //\* Set your output and error (asynchronous) handlers
                                      process.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);
                                      process.ErrorDataReceived += new DataReceivedEventHandler(OutputHandler);
                                      
                                      //\* Start process and handlers
                                      process.Start();
                                      process.BeginOutputReadLine();
                                      process.BeginErrorReadLine();
                                      //            process.WaitForExit();
                                  }
                                  void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
                                  {
                                      //\* Do your stuff with the output (write to console/log/StringBuilder)
                                      Console.WriteLine(outLine);
                                  }
                              }
                              
                              L Offline
                              L Offline
                              leon de boer
                              wrote on last edited by
                              #14

                              If you want a total guess looking at the MSDN reference and your code but ignoring the exit problem ;-)

                              using System.Threading;
                              new Thread(() =>
                              {
                              Thread.CurrentThread.IsBackground = true;
                              runCommand();
                              }).Start();

                              L 1 Reply Last reply
                              0
                              • L leon de boer

                                If you want a total guess looking at the MSDN reference and your code but ignoring the exit problem ;-)

                                using System.Threading;
                                new Thread(() =>
                                {
                                Thread.CurrentThread.IsBackground = true;
                                runCommand();
                                }).Start();

                                L Offline
                                L Offline
                                Lukasz Gesieniec
                                wrote on last edited by
                                #15

                                Running runCommand() from new Thread didn't help. I can read all outputs after console app quits. It is harder to build GUI using WinAPI than using WPF but WinAPI code works.

                                L 1 Reply Last reply
                                0
                                • L Lukasz Gesieniec

                                  Running runCommand() from new Thread didn't help. I can read all outputs after console app quits. It is harder to build GUI using WinAPI than using WPF but WinAPI code works.

                                  L Offline
                                  L Offline
                                  leon de boer
                                  wrote on last edited by
                                  #16

                                  Okay the problem is console.writeline is blocking C# test.net » Using Process.Start to capture console output[^] .net - Does Console.WriteLine block? - Stack Overflow[^] You can use one of the methods or Console.Out.WriteLineAsync("..."); if available. For us old timers it's actually faster to build a GUI with the API than with the WPF framework :-)

                                  In vino veritas

                                  L 1 Reply Last reply
                                  0
                                  • L leon de boer

                                    Okay the problem is console.writeline is blocking C# test.net » Using Process.Start to capture console output[^] .net - Does Console.WriteLine block? - Stack Overflow[^] You can use one of the methods or Console.Out.WriteLineAsync("..."); if available. For us old timers it's actually faster to build a GUI with the API than with the WPF framework :-)

                                    In vino veritas

                                    L Offline
                                    L Offline
                                    Lukasz Gesieniec
                                    wrote on last edited by
                                    #17

                                    OK, I know what you mean :) For me, it is easier to use WPF because I am embedded system engineer. I am from embedded world and I do not know Windows internals. That is why I am asking a lot of (stupid) questions. After reading several articles I supposed that redirect output and develop GUI app should be easier :) Now I know that my strange console app does not use standard printf function :((

                                    L 1 Reply Last reply
                                    0
                                    • L Lukasz Gesieniec

                                      OK, I know what you mean :) For me, it is easier to use WPF because I am embedded system engineer. I am from embedded world and I do not know Windows internals. That is why I am asking a lot of (stupid) questions. After reading several articles I supposed that redirect output and develop GUI app should be easier :) Now I know that my strange console app does not use standard printf function :((

                                      L Offline
                                      L Offline
                                      leon de boer
                                      wrote on last edited by
                                      #18

                                      The obvious question is can you not simply replace the program communicating with a proper windows code or is it a private format they won't disclose. Just saying it would be faster, cleaner and less code than what you are doing now :-)

                                      In vino veritas

                                      L 1 Reply Last reply
                                      0
                                      • L leon de boer

                                        The obvious question is can you not simply replace the program communicating with a proper windows code or is it a private format they won't disclose. Just saying it would be faster, cleaner and less code than what you are doing now :-)

                                        In vino veritas

                                        L Offline
                                        L Offline
                                        Lukasz Gesieniec
                                        wrote on last edited by
                                        #19

                                        Yes, it is a private closed format. Another way to communicate with the console app is passing command line arguments:

                                        MyApp.exe -Iinput.txt -Ooutput.txt

                                        where in the input.txt file in each line is a key command (e - exits the program, other keys do some actions): l f m c o e in the output.txt file, the program saves its output. Even something like this works: MyApp.exe -OCON - prints output to console twice. But problem is the same. If I monitor the output file, the content appears after app quits (e command in input file)

                                        P 1 Reply Last reply
                                        0
                                        • L Lukasz Gesieniec

                                          Yes, it is a private closed format. Another way to communicate with the console app is passing command line arguments:

                                          MyApp.exe -Iinput.txt -Ooutput.txt

                                          where in the input.txt file in each line is a key command (e - exits the program, other keys do some actions): l f m c o e in the output.txt file, the program saves its output. Even something like this works: MyApp.exe -OCON - prints output to console twice. But problem is the same. If I monitor the output file, the content appears after app quits (e command in input file)

                                          P Offline
                                          P Offline
                                          Peter_in_2780
                                          wrote on last edited by
                                          #20

                                          This smells to me of buffering. I'm guessing your app doesn't call flush() or equivalent on its output file, so the output is buffered until the explicit or implicit close() call at termination. If you can make your app output lots of data, you will probably see it appear in chunks, which will be whatever buffer size is used. The reason it works on the console is that console drivers do not buffer. I have no idea if you can suppress buffering in your redirection, but if you could, my 2c says that would solve your problem. Good luck! Peter

                                          Software rusts. Simon Stephenson, ca 1994. So does this signature. me, 2012

                                          L 1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • World
                                          • Users
                                          • Groups