文件ProgramExec.h
//---------------------------------------------------------------------------
#ifndef ProgramExecH#define ProgramExecH
#include "MyUnicodeString.h"//---------------------------------------------------------------------------DWORD WINAPI ReadFromPipe(LPVOID args);
/* globals */
#define CHUNK 25#define STATICBUFFERSIZE 1000typedef struct { HANDLE pipe; char buffer[STATICBUFFERSIZE];} pipeinfo;
pipeinfo Out = { INVALID_HANDLE_VALUE, '/0' };pipeinfo Err = { INVALID_HANDLE_VALUE, '/0' };MyUnicodeString* myUnicodeString;
void execProgram(UnicodeString& cmd,MyUnicodeString& _myUnicodeString,int& returnCode){ STARTUPINFOW si; PROCESS_INFORMATION pi; SECURITY_ATTRIBUTES sa; DWORD threadID; char msg[300]; BOOL ok; HANDLE hProcess, h, pipeThreads[2]; char cmdline[100]; myUnicodeString = &_myUnicodeString;
hProcess = GetCurrentProcess();
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); ZeroMemory(&si, sizeof(STARTUPINFOW)); si.cb = sizeof(STARTUPINFOW); si.dwFlags = STARTF_USESTDHANDLES; si.hStdInput = INVALID_HANDLE_VALUE;
ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES)); sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE;
/* * Create a non-inheritible pipe. */ CreatePipe(&Out.pipe, &h, &sa, 0);
/* * Dupe the write side, make it inheritible, and close the original. */ DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
/* * Same as above, but for the error side. */ CreatePipe(&Err.pipe, &h, &sa, 0); DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
ok = CreateProcessW(NULL, /* Module name. */ cmd.w_str(), /* Command line. */ NULL, /* Process handle not inheritable. */ NULL, /* Thread handle not inher 调用一个控制台程序并取得其输出(PIPE) www.firnow.com 时间 : 2007-10-19 作者:佚名 编辑:本站 点击: [ 评论 ] itable. */ TRUE, /* yes, inherit handles. */ DETACHED_PROCESS, /* No console for you. */ NULL, /* Use parent's environment block. */ NULL, /* Use parent's starting directory. */ &si, /* Pointer to STARTUPINFOW structure. */ &pi); /* Pointer to PROCESS_INFORMATION structure. */
if (!ok) { DWORD err = GetLastError(); int chars = _snprintf(msg, sizeof(msg) - 1, "Tried to launch: /"%s/", but got error [%u]: ", cmdline, err);
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, &msg[chars], (300 - chars), 0); WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err, NULL); returnCode = 2; return; }
/* * Close our references to the write handles that have now been inherited. */ CloseHandle(si.hStdOutput); CloseHandle(si.hStdError);
WaitForInputIdle(pi.hProcess, 5000); CloseHandle(pi.hThread);
/* * Start the pipe reader threads. */ pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID); pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID);
/* * Block waiting for the process to end. */ WaitForSingleObject(pi.hProcess, INFINITE); CloseHandle(pi.hProcess);
/* * Wait for our pipe to get done reading, should it be a little slow. */ WaitForMultipleObjects(2, pipeThreads, TRUE, INFINITE); CloseHandle(pipeThreads[0]); CloseHandle(pipeThreads[1]); returnCode = 0; return;}DWORD WINAPI ReadFromPipe(LPVOID args){ pipeinfo *pi = (pipeinfo *) args; DWORD dwRead; BOOL ok; char buf[2000];
while(true) { ok = ReadFile(pi->pipe, buf, 2000, &dwRead, 0L); if (!ok || dwRead == 0) { CloseHandle(pi->pipe); return 0; } else { buf[dwRead] = 0;// printf("%s", buf); myUnicodeString->append(buf); } }}
#endif
文件MyUnicodeString.h
//---------------------------------------------------------------------------
#ifndef MyUnicodeStringH#define MyUnicodeStringH//---------------------------------------------------------------------------#include <vcl.h>#include <windows.h>#include <list>using namespace std;
class MyUnicodeString{public: MyUnicodeString(); ~MyUnicodeString(); MyUnicodeString(wchar_t * wchar_ts); MyUnicodeString(UnicodeString str); MyUnicodeString(const wchar_t * wchar_ts); MyUnicodeString(int number); int indexOf(wchar_t ch); int indexOf(wchar_t * wchar_ts); int lastIndexOf(wchar_t ch); int lastIndexOf(wchar_t * wchar_ts); int getOccurCount(wchar_t* wchar_ts); int getOccurCount(wchar_t ch); int getLength(); int getLength(wchar_t * str); int getLength(const wchar_t * str); wchar_t* getReversed(); void reverse(); wchar_t* getReversed(wchar_t * str); int copy(const wchar_t* src,wchar_t* dest); int copy(wchar_t* src,wchar_t* dest); void copy(wchar_t* src,wchar_t* dest,int count); void copy(const wchar_t* src,wchar_t* dest,int count); list<UnicodeString>* split(wchar_t* splitter); list<UnicodeString>* split(UnicodeString splitter); wchar_t * getSubString(int startIndex,int count); wchar_t * getSubString(int startIndex); void rtrim(); void ltrim(); void trim(); bool startsWith(wchar_t *wchar_ts); bool endsWith(wchar_t *wchar_ts); void replace(wchar_t* oldwchar_ts,wchar_t* newwchar_ts); void replace(UnicodeString oldStr,UnicodeString newStr); void toUpperCase(); void toLowerCase(); MyUnicodeString* operator + (wchar_t* wchar_ts); wchar_t* towchar_ts(); UnicodeString getString(); wchar_t* getCopy(); bool isInt();//Contains only numbers int toInt(); bool isLargerThan(wchar_t* wchar_ts); bool equals(wchar_t* dest); void append(const wchar_t * str); void append(UnicodeString str); void append(wchar_t * str); void append(wchar_t ch); void appendNum(int number); void append(wchar_t appendwchar_t,int toLength); void insertBefore(wchar_t insertwchar_t,int toLength); void release(); wchar_t* getSpace(int count);private: int indexOf(wchar_t ch,bool isReverse); int indexOf(wchar_t * wchar_ts,bool isReverse); int indexOf(wchar_t* src,wchar_t ch,bool isReverse); int indexOf(wchar_t* src,wchar_t * wchar_ts,bool isReverse); wchar_t * getLtrim(wchar_t* wchar_ts); wchar_t * getSubString(wchar_t* src,int startIndex,int count); wchar_t * getSubString(wchar_t* src,int startIndex); bool startsWith(wchar_t* src,wchar_t *wchar_ts); void copy(wchar_t* src); void copy(const wchar_t* src); bool isBufferNull; wchar_t * intTowchar_ts(int number); void setEndChar(wchar_t* chars,int index);protected: void replaceBuffer(wchar_t* src); wchar_t* charBuffer;};
#endif
文件MyUnicodeString.cpp
//---------------------------------------------------------------------------
#pragma hdrstop
#include "MyUnicodeString.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)const wchar_t END_CHAR('/0');
MyUnicodeString::MyUnicodeString(){ isBufferNull = true; charBuffer = NULL;}MyUnicodeString::MyUnicodeString(UnicodeString str){ isBufferNull = true; charBuffer = NULL; if(str.Length()!=0) { copy(str.w_str()); }}MyUnicodeString::MyUnicodeString(wchar_t * wchar_ts){ isBufferNull = true; charBuffer = NULL; copy(wchar_ts);}MyUnicodeString::MyUnicodeString(const wchar_t * wchar_ts){ isBufferNull = true; copy(wchar_ts);}MyUnicodeString::MyUnicodeString(int number){ isBufferNull = true; wchar_t* wchar_ts = intTowchar_ts(number); copy(wchar_ts); free(wchar_ts);}wchar_t * MyUnicodeString::intTowchar_ts(int number){ const int maxLenForNumber = 10; wchar_t * str = getSpace(maxLenForNumber); wchar_t temp; int i = 0; if(number==0) { str[i]='0'; i++; } else { while(number!=0) { int remains = number%10; number /= 10; str[i] = remains+'0'; i++; } } setEndChar(str,i); i--; for(int j=0;j<(i+1)/2;j++) { temp = str[j]; str[j] = str[i-j]; str[i-j] = temp; } return str;}wchar_t* MyUnicodeString::getSpace(int count){ return (wchar_t*)malloc(sizeof(wchar_t)*(count+1));}int MyUnicodeString::indexOf(wchar_t ch){ return indexOf(ch,true);}int MyUnicodeString::indexOf(wchar_t * wchar_ts){ return indexOf(wchar_ts,false);}int MyUnicodeString::lastIndexOf(wchar_t ch){ return indexOf(ch,true);}int MyUnicodeString::lastIndexOf(wchar_t * wchar_ts){ return indexOf(wchar_ts,true);}int MyUnicodeString::indexOf(wchar_t ch,bool isReverse){ return indexOf(charBuffer,ch,isReverse);}int MyUnicodeString::indexOf(wchar_t * wchar_ts,bool isReverse){ return indexOf(charBuffer,wchar_ts,isReverse);}
int MyUnicodeString::indexOf(wchar_t* src,wchar_t ch,bool isReverse){ wchar_t * wchar_ts = getSpace(1); wchar_ts[0] = ch; setEndChar(wchar_ts,1); int index = indexOf(src,wchar_ts,isReverse); free(wchar_ts); return index;}int MyUnicodeString::indexOf(wchar_t* src,wchar_t * toSearchwchar_ts,bool isReverse){ const int NOT_FOUND = -1; if(src==NULL) { return NOT_FOUND; } if(toSearchwchar_ts[0]==END_CHAR) return NOT_FOUND; int i = 0; int j = 0; wchar_t * str,*searchStr; int strLen,searchStrLen; if(!isReverse) { str = src; searchStr = toSearchwchar_ts; } else { str = getReversed(); searchStr = getReversed(toSearchwchar_ts); } strLen = getLength(str); searchStrLen = getLength(searchStr); while(str[i]!=END_CHAR) { j = 0; while(searchStr[j]!=END_CHAR) { if(str[i+j]==END_CHAR) return NOT_FOUND; if(str[i+j]!=searchStr[j]) break; j++; } if(searchStr[j]==END_CHAR)//reach the end { if(!isReverse) return i; else return strLen-i-searchStrLen; } i++; } return NOT_FOUND;}int MyUnicodeString::getOccurCount(wchar_t* wchar_ts){ int occurCount = 0; int index; wchar_t * src = charBuffer; while((index=indexOf(src,wchar_ts,false))!=-1) { src += index+getLength(wchar_ts); occurCount++; } return occurCount;}int MyUnicodeString::getOccurCount(wchar_t ch){ wchar_t * wchar_ts = getSpace(1); wchar_ts[0] = ch; wchar_ts[1] = END_CHAR; int occurCount = getOccurCount(wchar_ts); free(wchar_ts); return occurCount;}int MyUnicodeString::getLength(){ return getLength(charBuffer);}int MyUnicodeString::getLength(wchar_t * str){ const wchar_t* str1 = str; return getLength(str1);}int MyUnicodeString::getLength(const wchar_t * str){ int i = 0; int length = 0; if(str!=NULL) { while(str[i]!=END_CHAR) { i++; length++; } }
return length;}wchar_t* MyUnicodeString::getReversed(wchar_t * str){ int len = getLength(str); wchar_t * wchar_ts = getSpace(len); for(int i=0;i<len;i++) { wchar_ts[len-i-1] = str[i]; } wchar_ts[len] = END_CHAR; return wchar_ts;}wchar_t* MyUnicodeString::getReversed(){ return getReversed(charBuffer);}void MyUnicodeString::reverse(){ wchar_t* reversed = getReversed(); replaceBuffer(reversed);}void MyUnicodeString::append(const wchar_t * str){ int bufferLen = getLength(); int strLen = getLength(str); if(strLen!=0) { isBufferNull = false; wchar_t * wchar_ts = getSpace(bufferLen+strLen); copy(charBuffer,wchar_ts); copy(str,wchar_ts+bufferLen); replaceBuffer(wchar_ts); }}void MyUnicodeString::append(wchar_t * str){ const wchar_t* str1 = str; append(str1);}void MyUnicodeString::append(wchar_t ch){ wchar_t * wchar_ts = getSpace(1); wchar_ts[0] = ch; wchar_ts[1] = END_CHAR; append(wchar_ts); free(wchar_ts);}void MyUnicodeString::append(UnicodeString str){ append(str.w_str());}void MyUnicodeString::appendNum(int number){ wchar_t* wchar_ts = intTowchar_ts(number); append(wchar_ts); free(wchar_ts);}int MyUnicodeString::copy(wchar_t* src,wchar_t* dest){ int i = 0; if(src==NULL||dest==NULL) return 0; while(src[i]!=END_CHAR) { dest[i] = src[i]; i++; } dest[i] = END_CHAR;
return i;}int MyUnicodeString::copy(const wchar_t* src,wchar_t* dest){ int i = 0; while(src[i]!=END_CHAR) { dest[i] = src[i]; i++; } dest[i] = END_CHAR; return i;}void MyUnicodeString::copy(wchar_t* src,wchar_t* dest,int count){ int i = 0; if(src==NULL||dest==NULL) { return; } while(src[i]!=END_CHAR&&i<=count-1) { dest[i] = src[i]; i++; } dest[i] = END_CHAR;}void MyUnicodeString::copy(const wchar_t* src,wchar_t* dest,int count){ int i = 0; while(src[i]!=END_CHAR&&i<=count-1) { dest[i] = src[i]; i++; } dest[i] = END_CHAR;}void MyUnicodeString::copy(wchar_t* src){ int strLen = getLength(src); if(strLen!=0) { release(); charBuffer = getSpace(strLen); isBufferNull = false; copy(src,charBuffer); }}void MyUnicodeString::copy(const wchar_t* src){ int i = 0; int strLen = 0; while(src[i]!=END_CHAR) { i++; strLen++; } if(strLen!=0) { release(); charBuffer = getSpace(strLen); isBufferNull = false; copy(src,charBuffer); }}list<UnicodeString>* MyUnicodeString::split(wchar_t* splitter){ if(charBuffer==NULL) return NULL; list<UnicodeString>* resultList = new list<UnicodeString>();
int occurCount = getOccurCount(splitter); int splitterLen = getLength(splitter); wchar_t** arr = (wchar_t**)malloc(sizeof(wchar_t*)*(occurCount+2)); wchar_t *src = charBuffer; int index; int start = 0; int arrIndex = 0; int length = 0; while((index=indexOf(src,splitter,false))!=-1) { length = index; arr[arrIndex] = getSubString(start,length); start += length + splitterLen; src += length + splitterLen; arrIndex++; }
arr[arrIndex] = getSubString(start);
for(int i=0;i<=arrIndex;i++) { resultList->push_back(UnicodeString(arr[i])); free(arr[i]); } free(arr); return resultList;}list<UnicodeString>* MyUnicodeString::split(UnicodeString splitter){ if(splitter!=NULL) { return split(splitter.w_str()); } else { return NULL; }}wchar_t * MyUnicodeString::getSubString(wchar_t* src,int startIndex,int count){ wchar_t* dest = getSpace(count); copy(src+startIndex,dest,count); return dest;}wchar_t * MyUnicodeString::getSubString(int startIndex,int count){ return getSubString(charBuffer,startIndex,count);}wchar_t * MyUnicodeString::getSubString(wchar_t* src,int startIndex){ int length = getLength(src+startIndex); wchar_t* dest = getSpace(length); copy(src+startIndex,dest,length); return dest;}wchar_t * MyUnicodeString::getSubString(int startIndex){ return getSubString(charBuffer,startIndex);}void MyUnicodeString::rtrim(){ if(getLength()!=0) { wchar_t* reversed = getReversed(); release(); wchar_t* ltrimed = getLtrim(reversed); free(reversed); if(getLength(ltrimed)!=0) { replaceBuffer(getReversed(ltrimed)); } free(ltrimed); }}wchar_t * MyUnicodeString::getLtrim(wchar_t* wchar_ts){ int i = 0; while(wchar_ts[i]!=END_CHAR) { if(wchar_ts[i]!=' ') break; i++; } return getSubString(wchar_ts,i);}void MyUnicodeString::ltrim(){ if(getLength()!=0) { wchar_t * ltrimed = getLtrim(charBuffer); release(); copy(ltrimed); free(ltrimed); }}void MyUnicodeString::trim(){ rtrim(); ltrim();}bool MyUnicodeString::startsWith(wchar_t* src,wchar_t *wchar_ts){ int i = 0; bool result = true; while(src[i]!=END_CHAR&&wchar_ts[i]!=END_CHAR) { if(src[i]!=wchar_ts[i]) { result = false; break; } i++; } if(src[i]==END_CHAR&&wchar_ts[i]!=END_CHAR) result = false; return result;}bool MyUnicodeString::startsWith(wchar_t *wchar_ts){ return startsWith(charBuffer,wchar_ts);}bool MyUnicodeString::endsWith(wchar_t *wchar_ts){ wchar_t* reversedSrc = getReversed(); wchar_t* reversedwchar_ts = getReversed(wchar_ts); bool result = startsWith(reversedSrc,reversedwchar_ts); free(reversedSrc); free(reversedwchar_ts); return result;}void MyUnicodeString::replace(wchar_t* oldwchar_ts,wchar_t* newwchar_ts){ int occurCount = getOccurCount(oldwchar_ts); int oldwchar_tsLen = getLength(oldwchar_ts); int newwchar_tsLen = getLength(newwchar_ts); int newLength = getLength(charBuffer)+(newwchar_tsLen-oldwchar_tsLen)*occurCount; wchar_t * wchar_ts = getSpace(newLength);
wchar_t *src = charBuffer; int index; int start = 0; int i = 0; int length = 0; wchar_t * temp; wchar_t * dest = wchar_ts; while((index=indexOf(src,oldwchar_ts,false))!=-1) { length = index; copy(src,dest,length); dest += length; start = length + oldwchar_tsLen; src += start; copy(newwchar_ts,dest,newwchar_tsLen); dest += newwchar_tsLen; i++; }
copy(src,dest); wchar_ts[newLength] = END_CHAR;
copy(wchar_ts); free(wchar_ts);}void MyUnicodeString::replace(UnicodeString oldStr,UnicodeString newStr){ replace(oldStr.w_str(),newStr.w_str());}wchar_t* MyUnicodeString::getCopy(){ int length = getLength(); wchar_t * wchar_ts = getSpace(length); copy(charBuffer,wchar_ts); return wchar_ts;}void MyUnicodeString::toUpperCase(){ int i = 0; wchar_t* dest = getCopy(); while(dest[i]!=END_CHAR) { if(dest[i]>='a'&&dest[i]<='z') dest[i] -= 'a'-'A'; i++; } copy(dest); free(dest);}void MyUnicodeString::toLowerCase(){ int i = 0; wchar_t* dest = getCopy(); while(dest[i]!=END_CHAR) { if(dest[i]>='A'&&dest[i]<='Z') dest[i] += 'a'-'A'; i++; } copy(dest); free(dest);}MyUnicodeString* MyUnicodeString::operator + (wchar_t* wchar_ts){ append(wchar_ts); return this;}wchar_t* MyUnicodeString::towchar_ts(){ return charBuffer;}UnicodeString MyUnicodeString::getString(){ return UnicodeString(charBuffer);}bool MyUnicodeString::equals(wchar_t* dest){ if(getLength()==getLength(dest)&&startsWith(dest)) return true; else return false;}bool MyUnicodeString::isInt(){ if(charBuffer==NULL) return false; int i = 0; while(charBuffer[i]!=END_CHAR) { if(i==0) { if((charBuffer[i]<'0'||charBuffer[i]>'9') &&charBuffer[i]!='-') return false; } else { if(charBuffer[i]<'0'||charBuffer[i]>'9') return false; } i++; } return true;}int MyUnicodeString::toInt(){ int i = 0; int result = 0; int sub = 1; //To identify positive or negative number if(isInt()) { while(charBuffer[i]!=END_CHAR) { if(i==0&&charBuffer[i]=='-') sub = -1; else result = result*10+charBuffer[i]-48;
i++; } result *= sub; } else { throw "Not Integer"; }
return result;}bool MyUnicodeString::isLargerThan(wchar_t* wchar_ts){ int i = 0; while(charBuffer[i]!=END_CHAR&&wchar_ts[i]!=END_CHAR) { if(charBuffer[i]>wchar_ts[i]) return true; else if (charBuffer[i]<wchar_ts[i]) return false;
i++; } if(charBuffer[i]==END_CHAR&&wchar_ts[i]!=END_CHAR) return false; if(charBuffer[i]!=END_CHAR&&wchar_ts[i]==END_CHAR) return true; return false;}void MyUnicodeString::replaceBuffer(wchar_t* src){ release(); isBufferNull = false; charBuffer = src;}void MyUnicodeString::append(wchar_t appendwchar_t,int toLength){ int len = getLength(); wchar_t* wchar_ts = getSpace(toLength); copy(charBuffer,wchar_ts); for(int i=0;i<toLength-len;i++) { wchar_ts[len+i]=appendwchar_t; } wchar_ts[toLength] = END_CHAR; replaceBuffer(wchar_ts);}void MyUnicodeString::insertBefore(wchar_t insertwchar_t,int toLength){ int len = getLength(); if(toLength>len) { wchar_t* wchar_ts = getSpace(toLength); int i; for(i=0;i<toLength-len;i++) { wchar_ts[i]=insertwchar_t; } copy(charBuffer,wchar_ts+i); replaceBuffer(wchar_ts); }}void MyUnicodeString::release(){ if(!isBufferNull) { free(charBuffer); charBuffer = NULL; isBufferNull = true; }}void MyUnicodeString::setEndChar(wchar_t* chars,int index){ wcscpy(chars+index,L"/0");}MyUnicodeString::~MyUnicodeString(){ release();}
测试代码:
UnicodeString cmd("help"); MyUnicodeString myUnicodeString; int returnCode; execProgram(cmd,myUnicodeString,returnCode);
控制台程序输入信息:myUnicodeString.getString();