// Get a handle to the STDOUT screen buffer to copy from and // create a new screen buffer to copy to.
hStdout = GetStdHandle(STD_OUTPUT_HANDLE); hNewScreenBuffer = CreateConsoleScreenBuffer( GENERIC_READ | // read/write access GENERIC_WRITE, 0, // not shared NULL, // default security attributes CONSOLE_TEXTMODE_BUFFER, // must be TEXTMODE NULL); // reserved; must be NULL if (hStdout == INVALID_HANDLE_VALUE || hNewScreenBuffer == INVALID_HANDLE_VALUE) { printf("CreateConsoleScreenBuffer (%d)\n", GetLastError()); return; }
// Make the new screen buffer the active screen buffer.
if (! SetConsoleActiveScreenBuffer(hNewScreenBuffer) ) { printf("SetConsoleActiveScreenBuffer (%d)\n", GetLastError()); return; }
// Set the source rectangle.
srctReadRect.Top = 0; // top left: row 0, col 0 srctReadRect.Left = 0; srctReadRect.Bottom = 1; // bot. right: row 1, col 79 srctReadRect.Right = 79;
// The temporary buffer size is 2 rows x 80 columns.
coordBufSize.Y = 2; coordBufSize.X = 80;
// The top left destination cell of the temporary buffer is // row 0, col 0.
coordBufCoord.X = 0; coordBufCoord.Y = 0;
// Copy the block from the screen buffer to the temp. buffer.
fSuccess = ReadConsoleOutput( hStdout, // screen buffer to read from chiBuffer, // buffer to copy into coordBufSize, // col-row size of chiBuffer coordBufCoord, // top left dest. cell in chiBuffer &srctReadRect); // screen buffer source rectangle if (! fSuccess) { printf("ReadConsoleOutput (%d)\n", GetLastError()); return; }
// Set the destination rectangle.
srctWriteRect.Top = 10; // top lt: row 10, col 0 srctWriteRect.Left = 0; srctWriteRect.Bottom = 11; // bot. rt: row 11, col 79 srctWriteRect.Right = 79;
// Copy from the temporary buffer to the new screen buffer.
fSuccess = WriteConsoleOutput( hNewScreenBuffer, // screen buffer to write to chiBuffer, // buffer to copy from coordBufSize, // col-row size of chiBuffer coordBufCoord, // top left src cell in chiBuffer &srctWriteRect); // dest. screen buffer rectangle if (! fSuccess) { printf("WriteConsoleOutput (%d)\n", GetLastError()); return; } Sleep(10000);
// Restore the original active screen buffer.
if (! SetConsoleActiveScreenBuffer(hStdout)) { printf("SetConsoleActiveScreenBuffer (%d)\n", GetLastError()); return; } }
编译环境,VS2008
运行环境,Win7
STARTUPINFO si = {sizeof(si)};
PROCESS_INFORMATION pi = {0};
TCHAR szApp[MAX_PATH] = _T("cmd");
if(::CreateProcess(NULL, szApp, NULL,NULL,FALSE,NULL,NULL,NULL,&si,&pi))
{
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
尔后,逐行试了下,发现问题发生在这里
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
不解。。不知道这里应该是如何?
不应该是STARTF_USESHOWWINDOW 吗?
哪位大大能解释一下。偶对进程是小白。
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE; HANDLE hInRead;
HANDLE hOutWrite;
HANDLE hInWrite;
HANDLE hOutRead;
if (!::CreatePipe(&hInRead, &hInWrite, &sa, 0))
{
return;
} if (!::CreatePipe(&hOutRead, &hOutWrite, &sa, 0))
{
return;
}// ::CloseHandle(hInRead);
// ::CloseHandle(hOutWrite); PROCESS_INFORMATION pi;
STARTUPINFO si; si.cb = sizeof(STARTUPINFO);
::GetStartupInfo(&si);
si.hStdInput = hOutRead;
si.hStdError = hInWrite;
si.hStdOutput = hInWrite;
si.wShowWindow = SW_SHOW;
si.dwFlags = STARTF_USESHOWWINDOW| STARTF_USESTDHANDLES; TCHAR sz[] = _T("cmd");
if (!::CreateProcess(NULL, sz
,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi))
{
return;
} if (!pi.hProcess)
{
return;
}
试试这段代码
,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi))
{
return;
}
else
{
WaitForSingleObject(pi.hProcess, INFINITE);
}
void test()
{
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE; HANDLE hInRead;
HANDLE hOutWrite;
HANDLE hInWrite;
HANDLE hOutRead;
if (!::CreatePipe(&hInRead, &hInWrite, &sa, 0))
{
return;
} if (!::CreatePipe(&hOutRead, &hOutWrite, &sa, 0))
{
return;
}// ::CloseHandle(hInRead);
// ::CloseHandle(hOutWrite); PROCESS_INFORMATION pi;
STARTUPINFO si; si.cb = sizeof(STARTUPINFO);
::GetStartupInfo(&si);
si.hStdInput = hOutRead;
si.hStdError = hInWrite;
si.hStdOutput = hInWrite;
si.wShowWindow = SW_SHOW;
si.dwFlags = STARTF_USESHOWWINDOW| STARTF_USESTDHANDLES; TCHAR sz[] = _T("cmd");
if (!::CreateProcess(NULL, sz
,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi))
{
return;
}
else
{
WaitForSingleObject(pi.hProcess, INFINITE);
} if (!pi.hProcess)
{
return;
}}
这个是我的测试函数
输入不是应该是写的么?输出不是应该是读的么?
为啥要反过来?si.hStdInput = hOutRead;
si.hStdError = hInWrite;
si.hStdOutput = hInWrite;
这样么?读的话是
::ReadFile(hInWrite, ...)这样对么?
si.hStdError = hInWrite;
si.hStdOutput = hInWrite;读写很简单,既然控制台从houtread读内容,你就往houtwrite里写
控制台把内容写到了hInWrite,当然就要从hinread里读这才是管道,从一端进就从另一端出,从另一端出就要往一端放
#include <stdio.h>
VOID main(void)
{
HANDLE hStdout, hNewScreenBuffer;
SMALL_RECT srctReadRect;
SMALL_RECT srctWriteRect;
CHAR_INFO chiBuffer[160]; // [2][80];
COORD coordBufSize;
COORD coordBufCoord;
BOOL fSuccess;
// Get a handle to the STDOUT screen buffer to copy from and
// create a new screen buffer to copy to.
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
hNewScreenBuffer = CreateConsoleScreenBuffer(
GENERIC_READ | // read/write access
GENERIC_WRITE,
0, // not shared
NULL, // default security attributes
CONSOLE_TEXTMODE_BUFFER, // must be TEXTMODE
NULL); // reserved; must be NULL
if (hStdout == INVALID_HANDLE_VALUE ||
hNewScreenBuffer == INVALID_HANDLE_VALUE)
{
printf("CreateConsoleScreenBuffer (%d)\n", GetLastError());
return;
}
// Make the new screen buffer the active screen buffer.
if (! SetConsoleActiveScreenBuffer(hNewScreenBuffer) )
{
printf("SetConsoleActiveScreenBuffer (%d)\n", GetLastError());
return;
}
// Set the source rectangle.
srctReadRect.Top = 0; // top left: row 0, col 0
srctReadRect.Left = 0;
srctReadRect.Bottom = 1; // bot. right: row 1, col 79
srctReadRect.Right = 79;
// The temporary buffer size is 2 rows x 80 columns.
coordBufSize.Y = 2;
coordBufSize.X = 80;
// The top left destination cell of the temporary buffer is
// row 0, col 0.
coordBufCoord.X = 0;
coordBufCoord.Y = 0;
// Copy the block from the screen buffer to the temp. buffer.
fSuccess = ReadConsoleOutput(
hStdout, // screen buffer to read from
chiBuffer, // buffer to copy into
coordBufSize, // col-row size of chiBuffer
coordBufCoord, // top left dest. cell in chiBuffer
&srctReadRect); // screen buffer source rectangle
if (! fSuccess)
{
printf("ReadConsoleOutput (%d)\n", GetLastError());
return;
}
// Set the destination rectangle.
srctWriteRect.Top = 10; // top lt: row 10, col 0
srctWriteRect.Left = 0;
srctWriteRect.Bottom = 11; // bot. rt: row 11, col 79
srctWriteRect.Right = 79;
// Copy from the temporary buffer to the new screen buffer.
fSuccess = WriteConsoleOutput(
hNewScreenBuffer, // screen buffer to write to
chiBuffer, // buffer to copy from
coordBufSize, // col-row size of chiBuffer
coordBufCoord, // top left src cell in chiBuffer
&srctWriteRect); // dest. screen buffer rectangle
if (! fSuccess)
{
printf("WriteConsoleOutput (%d)\n", GetLastError());
return;
}
Sleep(10000);
// Restore the original active screen buffer.
if (! SetConsoleActiveScreenBuffer(hStdout))
{
printf("SetConsoleActiveScreenBuffer (%d)\n", GetLastError());
return;
}
}
我的程序是MFC应用程序
CCmdProessDlg::CCmdProessDlg(CWnd* pParent /*=NULL*/)
: CDialog(CCmdProessDlg::IDD, pParent)
, m_strIn(_T(""))
, m_strOut(_T(""))
{
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE; HANDLE hInWrite;
HANDLE hOutRead;
if (!::CreatePipe(&m_hIn, &hInWrite, &sa, 0))
{
return;
} if (!::CreatePipe(&hOutRead, &m_hOut, &sa, 0))
{
return;
}
// ::CloseHandle(hInRead);
// ::CloseHandle(hOutWrite); PROCESS_INFORMATION pi = {0};
STARTUPINFO si = {sizeof(STARTUPINFO)};
::GetStartupInfo(&si);
si.hStdInput = hOutRead;
si.hStdError = hInWrite;
si.hStdOutput = hInWrite;
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; TCHAR sz[MAX_PATH] = _T("cmd");
if (!::CreateProcess(NULL, sz
,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi))
{
return;
} m_hProcess = pi.hProcess; ::CloseHandle(hOutRead);
::CloseHandle(hInWrite); ::CloseHandle(pi.hProcess);
::CloseHandle(pi.hThread);}
CCmdProessDlg::~CCmdProessDlg()
{
WriteCmd(_T("exit"));
CloseHandle(m_hIn);
CloseHandle(m_hOut);}
BOOL CCmdProessDlg::OnInitDialog()
{
CDialog::OnInitDialog(); // 将“关于...”菜单项添加到系统菜单中。 // IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
} // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标 // TODO: 在此添加额外的初始化代码 UpdateIn(); return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void CCmdProessDlg::OnOK()
{ WriteCmd(m_strIn); UpdateIn();
}
void CCmdProessDlg::UpdateIn()
{
UpdateData();
Sleep(200); USES_CONVERSION;
DWORD dwData;
char sz[1024] = {0};
while (PeekNamedPipe(m_hIn, sz, 1024, &dwData, NULL, 0) && dwData > 0)
{
ReadFile(m_hIn, sz, dwData, &dwData, NULL); m_strOut += A2T(sz);
} dwData = GetLastError(); UpdateData(FALSE);
}void CCmdProessDlg::WriteCmd( LPCTSTR sCmd )
{
USES_CONVERSION; char sz[1024] = "";
strcpy(sz, T2A(sCmd));
strcat(sz, "\n"); DWORD dwBytes;
::WriteFile(m_hOut, sz, strlen(sz), &dwBytes, NULL); Sleep(200);
}
万岁。。感谢各位支持。