Здравствуйте, вce!
Сегодня я проанилизировал некоторые примеры и пришёл к выоду что рершение задачи возможно разным путём. Не думаю, что кто-нибудь сможет оъяснить верность того или иного решения. Практика показала, что подобные задачи зачастую приходится решать путём подбора вариантов, ибо скудость информации от MS на эту тему безмерна. Привожу код работающий в 98 и 2000 Windows'ах.
/////////////////////////////////////////////////////////////////////////////////
static void EnsureChildProcDied(void);
static PROCESS_INFORMATION pi;
static bool RunProcess(PVOID pv)
{
if(!pRcvBuf)pRcvBuf= new char[100];
if(!pTsmBuf)pTsmBuf= new char[100];
HANDLE hChildsInpPipe=0,hMyOutPipe=0;
HANDLE hChildsOutPipe=0,hMyInpPipe=0;
bool fSuccess;
int iFailures=0;
if(ptl)
{
sprintf(str,"Running %s '%s' { %s} for {%s}\r\n",
ptl->szTlType[0]?ptl->szTlType:"CommandLine tool",
ptl->szTlAlias[0]?ptl->szTlAlias:"",
pszThisToolFPath,pszTargetFile);
}
else sprintf(str,"Running... {tool: %s} for {%s}\r\n",pszThisToolFPath,pszTargetFile);
Lm(str);
dwNbytesRead=0; dwReadSoFar=0; dwWritn=0;
DWORD dwRes;
DWORD dwRead=1;
bool bRead=1,bRes=0;
PVOID psd = NULL;
LPSECURITY_ATTRIBUTES psa=0;
if(sg.uOsVersion==W2000 || sg.uOsVersion==WXP || sg.uOsVersion==WNT4)
{
assert(psd = GlobalAlloc(GPTR, SECURITY_DESCRIPTOR_MIN_LENGTH));
assert(InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION));
assert(SetSecurityDescriptorDacl(psd, -1, 0, 0));
psa = (LPSECURITY_ATTRIBUTES)::GlobalAlloc(GPTR, sizeof(SECURITY_ATTRIBUTES));
psa->nLength = sizeof(SECURITY_ATTRIBUTES);
psa->lpSecurityDescriptor = psd;
psa->bInheritHandle = TRUE;
}
memset(&pi,0,sizeof pi);
STARTUPINFO si={0};
BOOL bProc;
HANDLE hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);
HANDLE hCurProc=GetCurrentProcess();
memset(&si, 0, sizeof(STARTUPINFO));
if(!CreatePipe(&hMyInpPipe, &hChildsOutPipe, psa,10000)){ goto end;}
if(!CreatePipe(&hChildsInpPipe, &hMyOutPipe, psa,10000)){ goto end;}
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdError = hChildsOutPipe;
si.hStdInput = hChildsInpPipe;
si.hStdOutput = hChildsOutPipe;
si.wShowWindow=SW_HIDE;
si.dwFillAttribute=0;//BACKGROUND_BLUE|FOREGROUND_GREEN;
si.dwFlags=STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;//|STARTF_USEFILLATTRIBUTE;// |
SetCurrentDirectory(pszCurrDir);// Чтобы компилятор знал откуда плясать
#ifdef DBUG
SaveShortFile("_CmdLineReal.txt",pszFullCmdLine,strlen(pszFullCmdLine));
#endif
SetStdHandle(STD_OUTPUT_HANDLE,hChildsOutPipe);
SetStdHandle(STD_ERROR_HANDLE,hChildsOutPipe);
SetStdHandle(STD_INPUT_HANDLE,hChildsInpPipe);
bProc=CreateProcess(NULL,pszFullCmdLine,0,psa,TRUE,CREATE_SUSPENDED,0,0, &si, &pi);//|CREATE_NEW_CONSOLE
if(!bProc || (!pi.hProcess || !pi.hThread || !pi.dwProcessId || !pi.dwThreadId))
{ Mbox("No Process created"); Gle(); goto end;}
if(hChildsOutPipe)CloseHandle(hChildsOutPipe); hChildsOutPipe=0;
if(hChildsInpPipe)CloseHandle(hChildsInpPipe); hChildsInpPipe=0;
dwTicksStarted=GetTickCount();
dwRes=ResumeThread(pi.hThread);
//sprintf(str,"ResumeThread return %d\r\n",dwRes); Lm(str);
SetLastError(0);
while((bRead && dwRead) || iFailures < 10)
{
dwRead=0;
bRead=ReadFile(hMyInpPipe,pRcvBuf+dwNbytesRead,1,&dwRead,0);
if(bRead && dwRead)
{ dwNbytesRead+=dwRead;
if( dwNbytesRead+1>=50)
{ *(pRcvBuf+dwNbytesRead)=0; Lm(pRcvBuf);
dwReadSoFar+=dwNbytesRead; dwNbytesRead=0;
}
}
else iFailures++;
}
//sprintf(str,"dwReadSoFar %d\r\n",dwReadSoFar); Lm(str);
bRes=CompleteReading();
#ifdef DBUG
SaveShortFile("_pszLe.txt",pszLe,iCurErrStrlen);
#endif
if(ptl)FindAndAddWarnsErrorMessage(ptl,pv);
end:
if(hChildsInpPipe)CloseHandle(hChildsInpPipe);
if(hMyOutPipe)CloseHandle(hMyOutPipe);
if(hChildsOutPipe)CloseHandle(hChildsOutPipe);
if(hMyInpPipe)CloseHandle(hMyInpPipe);
SetStdHandle(STD_INPUT_HANDLE, hSaveStdin);
SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout);
//CloseHandle(pi.hThread);
// Cleanup memory allocation
if(psa)GlobalFree(psa);
if(psd)GlobalFree(psd);
EnsureChildProcDied();
dwTicksFinished=GetTickCount();
return bRes;
}
////////////////////////////////////////////////////////////////////////////////
static void EnsureChildProcDied(void)
{
if(pi.hProcess && pi.dwProcessId && GetProcessVersion(pi.dwProcessId))
{
DWORD dwRes=WaitForInputIdle(pi.hProcess,500);
BOOL bTermRes=TerminateProcess(pi.hProcess,0);
if(!bTermRes)Gle();
else *zd.pbCompiling=0;
}
}
////////////////////////////////////////////////////////////////////////////////