操作系统 实验七
控制台重定向
使用管道实现重定向功能。
#include<windows.h>
#define BUF_SIZE 1000
TCHAR PipeData[BUF_SIZE]="\0";
LRESULT CALLBACK myWndProc(HWND hWnd,UINT uMsgId,WPARAM wParam,LPARAM lParam);
void AppendText(HWND hwnd);
void OnPing(HWND hwnd);
void PeekAndPump();
int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPreInst,LPSTR pszCmdLine,int nCmdShow)
{
static char szAppName[]="输出重定向!";
WNDCLASS wndClass;
HWND hWnd;
MSG msg;
wndClass.style=CS_VREDRAW|CS_HREDRAW;//V veritical H horizontal
wndClass.lpfnWndProc=myWndProc;
wndClass.cbClsExtra=0;
wndClass.cbWndExtra=0;
wndClass.hInstance=hInst;
wndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
wndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
wndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
wndClass.lpszMenuName=NULL;
wndClass.lpszClassName=szAppName;
if(0==RegisterClass(&wndClass))
return 0;
hWnd=CreateWindow(
szAppName,
szAppName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInst,
NULL
);
if(hWnd==0) return 0;
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Sleep(10000);
return msg.wParam;
}
LRESULT CALLBACK myWndProc(HWND hWnd,UINT uMsgId,WPARAM wParam,LPARAM lParam)
{
switch(uMsgId)
{
case WM_CREATE:
return 0;
case WM_PAINT:
AppendText(hWnd);
return 0;
case WM_CHAR:
if(wParam=='s'||wParam=='S')
OnPing(hWnd);
case WM_CLOSE:
DestroyWindow(hWnd);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hWnd,uMsgId,wParam,lParam);
}
}
void AppendText(HWND hwnd)
{
static TCHAR Data[10*BUF_SIZE]="\0";
HDC hDC;
PAINTSTRUCT paintStruct;
RECT clientRect;
strcat(Data,PipeData);
PipeData[0]='\0';
hDC=BeginPaint(hwnd,&paintStruct);
if(hDC!=NULL)
{
TextOut(hDC,0,0,"Press s or S to start ping",25);
GetClientRect(hwnd,&clientRect);
DrawText(hDC,Data,-1,&clientRect,DT_LEFT|DT_VCENTER);
EndPaint(hwnd,&paintStruct);
}
}
void OnPing(HWND hwnd)
{
LPCTSTR szCommand="ping.exe 127.0.0.1";
LPCTSTR szCurrentDirectory="c:\\windows\\system32\\";
DWORD BytesLeftThisMessage=0;
DWORD TotalBytesAvailable=0;
HANDLE PipeReadHandle;
HANDLE PipeWriteHandle;
PROCESS_INFORMATION ProcessInfo;
SECURITY_ATTRIBUTES SecurityAttributes;
STARTUPINFO StartupInfo;
BOOL Success;
//Initialization of structure
ZeroMemory(&StartupInfo,sizeof(StartupInfo));
ZeroMemory(&ProcessInfo,sizeof(ProcessInfo));
ZeroMemory(&SecurityAttributes,sizeof(SecurityAttributes));
//Sets the security property structure
SecurityAttributes.nLength=sizeof(SECURITY_ATTRIBUTES);
SecurityAttributes.bInheritHandle=TRUE;
SecurityAttributes.lpSecurityDescriptor=NULL;
//create the pipe
Success=CreatePipe(&PipeReadHandle,&PipeWriteHandle,&SecurityAttributes,0);
if(!Success) return;
StartupInfo.cb=sizeof(STARTUPINFO);
StartupInfo.dwFlags=STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
StartupInfo.hStdOutput=PipeWriteHandle;
StartupInfo.hStdError=PipeWriteHandle;
//create a proceed
Success=CreateProcess(NULL,(LPTSTR)szCommand,NULL,NULL,TRUE,0,NULL,szCurrentDirectory,&StartupInfo,&ProcessInfo);
if(!Success) return;
for(;;)
{
DWORD NumBytesRead=0;
Success=PeekNamedPipe(PipeReadHandle,PipeData,1,&NumBytesRead,&TotalBytesAvailable,&BytesLeftThisMessage);
if(!Success) break;
if(NumBytesRead)
{
Success=ReadFile(PipeReadHandle,PipeData,BUF_SIZE-1,&NumBytesRead,NULL);
if(!Success) break;
//0 are used to terminate data
PipeData[NumBytesRead]='\0';
InvalidateRect(hwnd,NULL,TRUE);
PeekAndPump();
}
CloseHandle(ProcessInfo.hThread);
CloseHandle(ProcessInfo.hProcess);
CloseHandle(PipeReadHandle);
CloseHandle(PipeWriteHandle);
}
}
void PeekAndPump()
{
MSG Msg;
while(PeekMessage(&Msg,NULL,0,0,PM_NOREMOVE))
if(GetMessage(&Msg,NULL,0,0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}