Esempio n. 1
0
//static function, Share with SyncDialog
UINT CProgressDlg::RunCmdList(CWnd* pWnd, STRING_VECTOR& cmdlist, STRING_VECTOR& dirlist, bool bShowCommand, CString* pfilename, volatile bool* bAbort, CGitGuardedByteArray* pdata, CGit* git)
{
	UINT ret=0;

	std::vector<std::unique_ptr<CBlockCacheForPath>> cacheBlockList;
	std::vector<std::unique_ptr<CGit>> gitList;
	if (dirlist.empty())
		cacheBlockList.push_back(std::make_unique<CBlockCacheForPath>(git->m_CurrentDir));
	else
	{
		for (const auto& dir : dirlist)
		{
			auto pGit = std::make_unique<CGit>();
			pGit->m_CurrentDir = dir;
			gitList.push_back(std::move(pGit));
			cacheBlockList.push_back(std::make_unique<CBlockCacheForPath>(dir));
		}
	}

	EnsurePostMessage(pWnd, MSG_PROGRESSDLG_UPDATE_UI, MSG_PROGRESSDLG_START, 0);

	if(pdata)
		pdata->clear();

	for (size_t i = 0; i < cmdlist.size(); ++i)
	{
		if(cmdlist[i].IsEmpty())
			continue;

		if (bShowCommand)
		{
			CStringA str;
			if (gitList.empty() || gitList.size() == 1 && gitList[0]->m_CurrentDir == git->m_CurrentDir)
				str = CUnicodeUtils::GetMulti(cmdlist[i].Trim() + _T("\r\n\r\n"), CP_UTF8);
			else
				str = CUnicodeUtils::GetMulti((i > 0 ? _T("\r\n") : _T("")) + gitList[i]->m_CurrentDir + _T("\r\n") + cmdlist[i].Trim() + _T("\r\n\r\n"), CP_UTF8);
			for (int j = 0; j < str.GetLength(); ++j)
			{
				if(pdata)
				{
					pdata->m_critSec.Lock();
					pdata->push_back(str[j]);
					pdata->m_critSec.Unlock();
				}
				else
					pWnd->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_RUN,str[j]);
			}
			if(pdata)
				pWnd->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_RUN,0);
		}

		PROCESS_INFORMATION pi;
		CAutoGeneralHandle hRead;
		int runAsyncRet = -1;
		if (gitList.empty())
			runAsyncRet = git->RunAsync(cmdlist[i].Trim(), &pi, hRead.GetPointer(), nullptr, pfilename);
		else
			runAsyncRet = gitList[i]->RunAsync(cmdlist[i].Trim(), &pi, hRead.GetPointer(), nullptr, pfilename);
		if (runAsyncRet)
		{
			EnsurePostMessage(pWnd, MSG_PROGRESSDLG_UPDATE_UI, MSG_PROGRESSDLG_FAILED, -1 * runAsyncRet);
			return runAsyncRet;
		}

		CAutoGeneralHandle piProcess(pi.hProcess);
		CAutoGeneralHandle piThread(pi.hThread);
		DWORD readnumber;
		char lastByte = '\0';
		char byte;
		CString output;
		while (ReadFile(hRead, &byte, 1, &readnumber, nullptr))
		{
			if(pdata)
			{
				if(byte == 0)
					byte = '\n';

				pdata->m_critSec.Lock();
				if (byte == '\n' && lastByte != '\r')
					pdata->push_back('\r');
				pdata->push_back( byte);
				lastByte = byte;
				pdata->m_critSec.Unlock();

				if(byte == '\r' || byte == '\n')
					pWnd->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_RUN,0);
			}
			else
				pWnd->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_RUN,byte);
		}
		if (pdata)
		{
			pdata->m_critSec.Lock();
			bool post = !pdata->empty();
			pdata->m_critSec.Unlock();
			if (post)
				EnsurePostMessage(pWnd, MSG_PROGRESSDLG_UPDATE_UI, MSG_PROGRESSDLG_RUN, 0);
		}

		CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": waiting for process to finish (%s), aborted: %d\n"), (LPCTSTR)cmdlist[i], *bAbort);

		WaitForSingleObject(pi.hProcess, INFINITE);

		DWORD status=0;
		if(!GetExitCodeProcess(pi.hProcess,&status) || *bAbort)
		{
			CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": process %s finished, status code could not be fetched, (error %d; %s), aborted: %d\n"), (LPCTSTR)cmdlist[i], GetLastError(), (LPCTSTR)CFormatMessageWrapper(), *bAbort);

			EnsurePostMessage(pWnd, MSG_PROGRESSDLG_UPDATE_UI, MSG_PROGRESSDLG_FAILED, status);
			return TGIT_GIT_ERROR_GET_EXIT_CODE;
		}
		CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": process %s finished with code %d\n"), (LPCTSTR)cmdlist[i], status);
		ret |= status;
	}

	EnsurePostMessage(pWnd, MSG_PROGRESSDLG_UPDATE_UI, MSG_PROGRESSDLG_END, ret);

	return ret;
}
Esempio n. 2
0
//static function, Share with SyncDialog
UINT CProgressDlg::RunCmdList(CWnd *pWnd,std::vector<CString> &cmdlist,bool bShowCommand,CString *pfilename,bool *bAbort,CGitByteArray *pdata, CGit *git)
{
	UINT ret=0;

	PROCESS_INFORMATION pi;
	HANDLE hRead = 0;

	memset(&pi,0,sizeof(PROCESS_INFORMATION));

	CBlockCacheForPath cacheBlock(git->m_CurrentDir);

	EnsurePostMessage(pWnd, MSG_PROGRESSDLG_UPDATE_UI, MSG_PROGRESSDLG_START, 0);

	if(pdata)
		pdata->clear();

	for (size_t i = 0; i < cmdlist.size(); ++i)
	{
		if(cmdlist[i].IsEmpty())
			continue;

		if (bShowCommand)
		{
			CStringA str = CUnicodeUtils::GetMulti(cmdlist[i].Trim() + _T("\r\n\r\n"), CP_UTF8);
			for (int j = 0; j < str.GetLength(); ++j)
			{
				if(pdata)
				{
					pdata->m_critSec.Lock();
					pdata->push_back(str[j]);
					pdata->m_critSec.Unlock();
				}
				else
					pWnd->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_RUN,str[j]);
			}
			if(pdata)
				pWnd->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_RUN,0);
		}

		git->RunAsync(cmdlist[i].Trim(),&pi, &hRead, NULL, pfilename);

		DWORD readnumber;
		char lastByte = '\0';
		char byte;
		CString output;
		while(ReadFile(hRead,&byte,1,&readnumber,NULL))
		{
			if(pdata)
			{
				if(byte == 0)
					byte = '\n';

				pdata->m_critSec.Lock();
				if (byte == '\n' && lastByte != '\r')
					pdata->push_back('\r');
				pdata->push_back( byte);
				lastByte = byte;
				pdata->m_critSec.Unlock();

				if(byte == '\r' || byte == '\n')
					pWnd->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_RUN,0);
			}
			else
				pWnd->PostMessage(MSG_PROGRESSDLG_UPDATE_UI,MSG_PROGRESSDLG_RUN,byte);
		}
		if (pdata)
		{
			pdata->m_critSec.Lock();
			bool post = !pdata->empty();
			pdata->m_critSec.Unlock();
			if (post)
				EnsurePostMessage(pWnd, MSG_PROGRESSDLG_UPDATE_UI, MSG_PROGRESSDLG_RUN, 0);
		}

		CloseHandle(pi.hThread);

		CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": waiting for process to finish (%s), aborted: %d\n"), cmdlist[i], *bAbort);

		WaitForSingleObject(pi.hProcess, INFINITE);

		DWORD status=0;
		if(!GetExitCodeProcess(pi.hProcess,&status) || *bAbort)
		{
			CloseHandle(pi.hProcess);

			CloseHandle(hRead);

			CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": process %s finished, status code could not be fetched, (error %d; %s), aborted: %d\n"), cmdlist[i], GetLastError(), (CString)CFormatMessageWrapper(), *bAbort);

			EnsurePostMessage(pWnd, MSG_PROGRESSDLG_UPDATE_UI, MSG_PROGRESSDLG_FAILED, status);
			return TGIT_GIT_ERROR_GET_EXIT_CODE;
		}
		CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": process %s finished with code %d\n"), cmdlist[i], status);
		ret |= status;
	}

	CloseHandle(pi.hProcess);

	CloseHandle(hRead);

	EnsurePostMessage(pWnd, MSG_PROGRESSDLG_UPDATE_UI, MSG_PROGRESSDLG_END, ret);

	return ret;
}