|
Prev: XP SP3: changes in stream "005SummaryInformation"
Next: ReplaceFile fails, but the file exists... ?
From: Andre Hamilton Andre on 27 Jun 2008 12:38 I am currently trying to redirect stdin/stdout from the cmd process so I can execute commands analize the results in a seperate program. I followed the instrcutions found on msdn with anonymous pipes(http://msdn.microsoft.com/en-us/library/ms682499(VS.85).aspx), but this only works temporarily. 1)I am able to read and write to the console, but it is out of order. I use 2 function to read and write to the console: bool readFromPipe(string* pipeString);//reads string from pipe and stores it in string bool writeToPipe(string writeString);//write the string to stdin(hChildStdinWr) of console I first call writeToPipe(), then readFromPipe(), and then print the results to the screen. But the results from readFromPipe doesnt get printed onscreen untill a second call to writeToPipe() and readFromPipe. Below is sample output of my program(what I typed in is in red). //------------------------------------------------------------------------ >> dir Copyright (c) 2006 Microsoft Corporation. All rights reserved. C:\Users\jadmin\Documents\Borland Studio Projects\Debug_Build>any text dir Volume in drive C has no label. Volume Serial Number is 80D7-0AEC Directory of C:\Users\jadmin\Documents\Borland Studio Projects\Debug_Build 06/27/2008 11:43 AM <DIR> . 06/27/2008 11:43 AM <DIR> .. 06/27/2008 11:43 AM 128,871 DevConUtil.obj 06/27/2008 11:39 AM 251,671 PipeTest.obj 06/27/2008 11:43 AM 31,744 Project1.exe 06/27/2008 11:43 AM 1,114,112 Project1.tds 4 File(s) 1,526,398 bytes 2 Dir(s) 79,994,851,328 bytes free C:\Users\jadmin\Documents\Borland Studio Projects\Debug_Build>dir More? //------------------------------------------------------------------------------------- 2)After the second dir is entered, the console outputs the word "More?" and then the cmd process exists. Does anyone know why the console would be ouputting the word more, and if it is at all possible to keep the pipes open for more than one read and write? //Below is a snippet of the code used Below is the main class which creates the process and the pipes 1 <devConUtil.h> 2 //--------------------------------------------------------------------------- 3 4 #ifndef DevConUtilH 5 #define DevConUtilH 6 //--------------------------------------------------------------------------- 7 8 #include "windows.h" 9 #include <vcl.h> 10 11 12 #define BUFSIZE 4098 13 14 15 16 class DevConUtil 17 { 18 public: 19 20 DevConUtil(HANDLE hwd); 21 ~DevConUtil(); 22 std::string sendCommand(std::string cmdString); 23 24 bool wasConstructedProperly() { return constructedProperly; } 25 DWORD getExitStatus(){ GetExitCodeProcess(piProcInfo.hProcess,&exitStat); 26 return exitStat; 27 } 28 29 30 private: 31 HANDLE hChildStdinRd; 32 HANDLE hChildStdinWr; 33 HANDLE hChildStdoutRd; 34 HANDLE hChildStdoutWr; 35 HANDLE hInputFile; 36 HANDLE hSaveStdout; 37 HANDLE hStdout; 38 HANDLE hSaveStdin; 39 40 PROCESS_INFORMATION piProcInfo; 41 DWORD exitStat; 42 43 bool constructedProperly; 44 45 46 47 BOOL createCMDProcess(HANDLE hwnd); 48 bool readFromPipe(std::string* pipeString); 49 bool writeToPipe(std::string writeString); 50 51 52 53 54 }; 55 56 #endif //----------------------------------------- below is the cpp implementation 1 //--------------------------------------------------------------------------- 2 3 4 #pragma hdrstop 5 6 #include "DevConUtil.h" 7 #include <iostream> 8 //--------------------------------------------------------------------------- 9 10 #pragma package(smart_init) 11 12 13 DevConUtil::DevConUtil(HANDLE hwnd) 14 { 15 SECURITY_ATTRIBUTES saAttr; 16 BOOL fSuccess; 17 constructedProperly = true; 18 19 // Set the bInheritHandle flag so pipe handles are inherited. 20 21 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 22 saAttr.bInheritHandle = TRUE; 23 saAttr.lpSecurityDescriptor = NULL; 24 25 // Get the handle to the current STDOUT. 26 27 hStdout = GetStdHandle(STD_OUTPUT_HANDLE); 28 29 // Create a pipe for the child process's STDOUT. 30 31 if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) 32 { 33 MessageBox(hwnd,"Stdout pipe creation failed","ERROR",MB_OK); 34 constructedProperly = false; 35 36 } 37 38 39 // Ensure that the read handle to the child process's pipe for STDOUT is not inherited. 40 41 SetHandleInformation( hChildStdoutRd, HANDLE_FLAG_INHERIT, 0); 42 43 44 // Create a pipe for the child process's STDIN. 45 46 if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0)) 47 { 48 MessageBoxA(NULL,"Stdin pipe creation failed\n","ERROR",MB_OK); 49 constructedProperly = false; 50 51 } 52 53 54 // Ensure that the write handle to the child process's pipe for STDIN is not inherited. 55 56 SetHandleInformation( hChildStdinWr, HANDLE_FLAG_INHERIT, 0); 57 58 // Now create the child process. 59 60 61 BOOL rslt = createCMDProcess(hwnd); 62 if(!(rslt)) 63 { 64 constructedProperly = false; 65 } 66 67 std::string tmp; 68 readFromPipe(&tmp); 69 //std::cout<<tmp.c_str(); 70 } 71 72 DevConUtil::~DevConUtil() 73 { 74 if (! CloseHandle(hChildStdinWr)) 75 MessageBox(NULL,"Close pipe failed","ERROR",MB_OK); 76 // Close the write end of the pipe before reading from the 77 // read end of the pipe. 78 79 if (!CloseHandle(hChildStdoutWr)) 80 MessageBox(NULL,"Closing handle failed","ERROR",MB_OK); 81 82 //std 83 84 } 85 86 std::string DevConUtil::sendCommand(std::string cmdString) 87 { 88 //std 89 bool wrSuccess = false; 90 bool readSucess = false; 91 bool con = true; 92 std::string result(""); 93 std::string tmp("Hellow World"); 94 wrSuccess = writeToPipe(cmdString); 95 96 readSucess = readFromPipe(&result); 97 98 //readSucess = 99 100 return result; 101 102 } 103 104 105 BOOL DevConUtil::createCMDProcess(HANDLE hwnd) 106 { 107 TCHAR szCmdline[]=TEXT("cmd -ka "); 108 109 STARTUPINFO siStartInfo; 110 BOOL bFuncRetn = FALSE; 111 112 // Set up members of the PROCESS_INFORMATION structure. 113 114 ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) ); 115 116 // Set up members of the STARTUPINFO structure. 117 118 ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) ); 119 siStartInfo.cb = sizeof(STARTUPINFO); 120 siStartInfo.hStdError = hChildStdoutWr; 121 siStartInfo.hStdOutput = hChildStdoutWr; 122 siStartInfo.hStdInput = hChildStdinRd; 123 siStartInfo.wShowWindow = SW_SHOW; 124 siStartInfo.dwFlags |= STARTF_USESTDHANDLES |STARTF_USESHOWWINDOW; 125 126 // Create the child process. 127 128 bFuncRetn = CreateProcess(NULL, 129 szCmdline, // command line 130 NULL, // process security attributes 131 NULL, // primary thread security attributes 132 TRUE, // handles are inherited 133 0, // creation flags 134 NULL, // use parent's environment 135 NULL, // use parent's current directory 136 &siStartInfo, // STARTUPINFO pointer 137 &piProcInfo); // receives PROCESS_INFORMATION 138 139 if (bFuncRetn == 0) 140 { 141 MessageBox(hwnd,"CreateProcess failed","ERROR",MB_OK); 142 return FALSE; 143 } 144 else 145 { 146 CloseHandle(piProcInfo.hProcess); 147 CloseHandle(piProcInfo.hThread); 148 return bFuncRetn; 149 } 150 151 //std 152 } 153 154 bool DevConUtil::readFromPipe(std::string * pipeString ) 155 { 156 //std 157 DWORD dwRead, dwWritten; 158 CHAR chBuf[BUFSIZE]; 159 std::string returnString; 160 161 ZeroMemory(chBuf,BUFSIZE); 162 163 164 if( ReadFile( hChildStdoutRd, chBuf, BUFSIZE, &dwRead, 165 NULL) ||dwRead != 0) 166 { 167 (*pipeString) = chBuf; 168 169 return true; 170 171 } 172 else 173 { 174 (*pipeString) = "Could not read from Pipe"; 175 return false; 176 }//else 177 178 179 } 180 181 bool DevConUtil::writeToPipe(std::string writeString) 182 { 183 //std 184 DWORD dwRead, dwWritten; 185 CHAR chBuf[BUFSIZE]; 186 DWORD err; 187 188 writeStringwriteString = writeString + "\n\r" ; 189 if (WriteFile(hChildStdinWr, writeString.c_str(), writeString.Length() +1, 190 &dwWritten, NULL)) 191 { 192 //CloseHandle(hChildStdinWr); 193 return true; 194 } 195 else 196 { 197 err = GetLastError(); 198 } 199 200 return false; 201 202 203 } //---------------------------- and this is the main file 1 //--------------------------------------------------------------------------- 2 3 #pragma hdrstop 4 5 //--------------------------------------------------------------------------- 6 7 #pragma argsused 8 9 #include "DevConUtil.h" 10 #include <iostream> 11 #include <string> 12 13 int main(int argc, char* argv[]) 14 { 15 DevConUtil* pipe = new DevConUtil(NULL); 16 std::string exitString(""); 17 std::cout<<">>\n"; 18 19 bool con = true; 20 do 21 { 22 std::cin>>exitString; 23 if(ll.AnsiCompare("exit") == 0) 24 con = false; 25 exitString = pipe->sendCommand(exitString); 26 27 std::cout<<exitString.c_str(); 28 // std::cout<<"\n-----\n"<<std::endl; 29 std::flushall(); 30 31 }while(con); 32 33 return 0; 34 35 } 36 37 38 //---------------------------------------------------------------------------
|
Pages: 1 Prev: XP SP3: changes in stream "005SummaryInformation" Next: ReplaceFile fails, but the file exists... ? |