910514-如何将cmd框输出重定向到文本框? [英] 910514 - how can i redirect cmd box output into a textbox?

查看:97
本文介绍了910514-如何将cmd框输出重定向到文本框?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我如何才能将cmd框的输出重定向到文本框中,或者以某种方式在本机C ++中进行抓取,就像我们在使用cl.exe进行编译时在Visual Studio本身中看到的那样?
我不必等到命令完全执行后再显示输出.
我需要打开文本框,并且每当要通过命令行程序(或我想要选择的stderr)将某些内容复制到标准输出中时,输出都会自动重定向到文本框.

how can i redirect cmd box output into a textbox or grab it somehow in native C++, like what we see in Visual Studio itself while compiling with cl.exe?
i need not to wait until the command gets executed completely and then show the output.
i need to open the textbox and whenever something is to be copied into standard output by the command line program (or stderr which i want to be able to select), the output be redirected to the textbox automatically.

推荐答案

不是一个完整的解决方案,只是指针,而是:
-使用 CreateNamedPipe [ ^ ]
-使用 CreateProcess []运行控制台应用程序[ ^ ],请在 STARTUPINFO [ ReadFile [ ^ ]读取在线程或计时器等中传递到命名管道的所有内容,并将其提供给文本框

阅读MSDN链接以获取有关该方法的更多信息.随时问是否有问题.祝你好运.
Not a complete solution, just pointers, but:
-Create named pipe(s) with CreateNamedPipe[^]
-run the console application with CreateProcess[^], specifying your named pipe(s) in the STARTUPINFO[^] structure for hStdOutput and hStdError
-Use ReadFile[^] to read anything that gets delivered to the named pipe in a thread or in a timer or somesuch and feed it to the text box

Read the MSDN links for more info on the methods. Feel free to ask if there''s a question. Good luck.


小例子来演示如何捕获控制台输入.
要更新您的编辑,请执行以下操作:将捕获功能放入类对象中,并在应用程序窗口中使用计时器以周期性地更新到编辑控件.

最好的问候.

Little example to demonstrate capturing of console input.
To update your edit: put the capture functionallity into a class object and use a timer in your application window for cyclic update to the edit control.

Best regards.

#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <tchar.h>
#include <malloc.h>

#pragma comment(lib,"user32.lib")
#pragma comment(lib,"gdi32.lib")

WNDPROC __wndsuper = 0;
LRESULT FAR PASCAL __wndproc(HWND h,unsigned int m,WPARAM w,LPARAM l)
{
  switch(m)
  {
    case WM_CLOSE  : DestroyWindow(h); break;
    case WM_DESTROY: PostQuitMessage(0); break;
  }
  return CallWindowProc(__wndsuper,h,m,w,l);
}

HGLOBAL  CatchConsole(const TCHAR* exe,const TCHAR* param=0);

int FAR PASCAL _tWinMain(HINSTANCE h,HINSTANCE p,LPTSTR c,int sw)
{
  HWND    hwnd;
  HGLOBAL  hmem;
  MSG      msg;

  hmem = c && *c ? CatchConsole(c): CatchConsole(__TEXT("cmd.exe"),__TEXT("/c dir /s C:\\*.*"));
  if(!hmem) return 1;

  hwnd = CreateWindowEx(0,__TEXT("EDIT"),__TEXT("CatchConsole"),
    WS_OVERLAPPEDWINDOW|WS_HSCROLL|WS_VSCROLL|ES_MULTILINE|ES_AUTOVSCROLL|ES_AUTOHSCROLL|ES_WANTRETURN,
    CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,0,0,h,0);

  if(IsWindow(hwnd))
  {
    #if _WIN64
    __wndsuper = (WNDPROC)SetWindowLongPtr(hwnd,GWLP_WNDPROC,(LONG_PTR)__wndproc);
    #else
    __wndsuper = (WNDPROC)SetWindowLong(hwnd,GWL_WNDPROC,(LONG)__wndproc);
    #endif
    GlobalFree((HGLOBAL)SendMessage(hwnd,EM_GETHANDLE,0,0));
    SendMessage(hwnd,EM_SETHANDLE,(WPARAM)hmem,0);
    SendMessage(hwnd,WM_SETFONT,(WPARAM)GetStockObject(ANSI_FIXED_FONT),0);
    SendMessage(hwnd,WM_SETICON,ICON_BIG,(LPARAM)LoadIcon(0,IDI_ASTERISK));
    ShowWindow(hwnd,sw);
    while(GetMessage(&msg,0,0,0))
    {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }
  }
  return 0;
}

class CMemWrite // helper class
{
public:
  CMemWrite(){ _hmem=0;_seek=_size=0; }
  ~CMemWrite(){ if(_hmem) GlobalFree(_hmem); }
  
  HGLOBAL  Detach()
  {
    HGLOBAL h; return h=_hmem,_hmem=0,h;
  }

  void  Write(const char* lp,const unsigned int cb)
  {
    if(Grow((1+cb)*sizeof(TCHAR)))
    {
      TCHAR*        lpto = (TCHAR*)GlobalLock(_hmem);
      unsigned int  size;
      lpto += _seek / sizeof(TCHAR);
      size = (_size - _seek) / sizeof(TCHAR);
      if(sizeof(TCHAR)==sizeof(short))
        MultiByteToWideChar(CP_OEMCP,0,lp,cb,lpto,size);
      else
        memcpy(lpto,lp,cb);
      lpto[cb] = 0;
      _seek += cb*sizeof(TCHAR);
      GlobalUnlock(_hmem);
    }
  }

protected:
  int    Grow(const unsigned int add)
  {
    if(_size>=(_seek+add)) return 1;
    _size = 256 + ((_seek + add)<<1);
    _hmem = _hmem ? GlobalReAlloc(_hmem,_size,GMEM_MOVEABLE) : GlobalAlloc(GMEM_MOVEABLE,_size);
    return _hmem?1:0;
  }

private:
  HGLOBAL        _hmem;
  unsigned int  _size;
  unsigned int  _seek;
};

HGLOBAL  CatchConsole(const TCHAR* exe,const TCHAR* param)
{
  CMemWrite                write;
  STARTUPINFO              stari;
  PROCESS_INFORMATION      proci;
  int                      ok;
  TCHAR*                  command;
  size_t                  le,lp;
  SECURITY_ATTRIBUTES      sa;
  HANDLE                  hproc;
  HANDLE                  hRead,
                          hWrite;
  unsigned long            avail;
  unsigned long            read;
  char                    out[0x400];

  if(!exe) return 0;

  memset(&proci,0,sizeof(proci));
  memset(&stari,0,sizeof(stari));

  stari.cb              = sizeof(stari);
  stari.lpTitle         = __TEXT("---");
  stari.dwXCountChars   = 128;
  stari.dwYCountChars   = 300;
  stari.dwFlags         = STARTF_USESHOWWINDOW|STARTF_USECOUNTCHARS;
  stari.wShowWindow     = SW_HIDE;
  stari.hStdInput       = 0;
  stari.hStdOutput      = 0;
  stari.hStdError       = 0;

  hRead  = hWrite = 0;

  sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  sa.lpSecurityDescriptor = 0;
  sa.bInheritHandle = 1;

  do
  {
    hproc = ::GetCurrentProcess();

    if(!::CreatePipe(&hRead, &stari.hStdOutput, &sa, 0)) break;
    if(!::DuplicateHandle(hproc,stari.hStdOutput,hproc,&stari.hStdError,0,1,DUPLICATE_SAME_ACCESS)) break;
    if(!::CreatePipe(&stari.hStdInput, &hWrite, &sa, 0)) break;

    stari.dwFlags |= STARTF_USESTDHANDLES;

    le = _tcslen(exe);
    lp = param?_tcslen(param):0;
    command = (TCHAR*)malloc(sizeof(TCHAR)*(le+lp+32)); if(!command) break;
    _tcscpy_s(command,le+lp+32,exe);
    if(0<lp)
    {
      _tcscpy_s(command+le,lp+32,__TEXT(" "));
      _tcscpy_s(command+le+1,lp+32-1,param);
    }

    ok = CreateProcess(0,command,0,0,1,IDLE_PRIORITY_CLASS,0,0,&stari,&proci);
    free(command);

    while(ok)
    {
      ok = WAIT_TIMEOUT==WaitForSingleObject(proci.hProcess,10);
      for(avail=0;PeekNamedPipe(hRead,0,0,0,&avail,0) && avail;avail=0)
      {
        if(ReadFile(hRead,out,min(sizeof(out),avail),&read,0) && read)
        {
          write.Write(out,read);
        }
      }
    }

  } while(0);

  if(stari.hStdOutput) CloseHandle(stari.hStdOutput);
  if(stari.hStdInput ) CloseHandle(stari.hStdInput);
  if(stari.hStdError ) CloseHandle(stari.hStdError);
  if(hRead ) CloseHandle(hRead);
  if(hWrite) CloseHandle(hWrite);

  return write.Detach();
}


两种方式
1(错误的方式)
将结果从cmd输出到txt,然后您的程序将其读取
2(好方法)
管道(见上文)
two ways
1 (bad way)
output the result from cmd to txt and then your programe read it
2 (good way)
pipe(see above)


这篇关于910514-如何将cmd框输出重定向到文本框?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆