|
결국.. DevC++ 소스프로그램의 델파이 소스를 빌더로 변경해서 해결했습니다.
머 배치파일이나 윈도 플, 도스 플.. 다되는군요..
참고 하시라고.. ^^
간략하게 사용법은..
Memo1->Text = RunAndGetOutput("c:\\test.bat", "c:\\", false);
이러면.. 모든과정이 끝난다음에 결과가 메모로 입력됩니다.
실행중간에 라인단위로 전달받을려면..
소스를 조금만 수정하세요.. 주석부..
== 소스 ==
String __fastcall TForm1::RunAndGetOutput(String Cmd, String WorkDir,
// ErrFunc: TErrFunc; // 에러 표시용 함수 지정
// LineOutputFunc: TLineOutputFunc; // 라인단위 출력용 함수 지정
// CheckAbortFunc: TCheckAbortFunc; // 중지용 함수 실행
bool ShowReturnValue)
{
STARTUPINFO tsi;
PROCESS_INFORMATION tpi;
DWORD nRead;
char aBuf[101];
SECURITY_ATTRIBUTES sa;
HANDLE hOutputReadTmp, hOutputRead, hOutputWrite, hInputWriteTmp, hInputRead,
hInputWrite, hErrorWrite;
String FOutput;
String CurrentLine;
bool bAbort;
String Result;
FOutput = "";
CurrentLine = "";
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = true;
CreatePipe(&hOutputReadTmp, &hOutputWrite, &sa, 0);
DuplicateHandle(GetCurrentProcess(), hOutputWrite, GetCurrentProcess(),
&hErrorWrite, 0, true, DUPLICATE_SAME_ACCESS);
CreatePipe(&hInputRead, &hInputWriteTmp, &sa, 0);
// Create new output read handle and the input write handle. Set
// the inheritance properties to FALSE. Otherwise, the child inherits
// the these handles; resulting in non-closeable handles to the pipes
// being created.
DuplicateHandle(GetCurrentProcess(), hOutputReadTmp, GetCurrentProcess(),
&hOutputRead, 0, false, DUPLICATE_SAME_ACCESS);
DuplicateHandle(GetCurrentProcess(), hInputWriteTmp, GetCurrentProcess(),
&hInputWrite, 0, false, DUPLICATE_SAME_ACCESS);
CloseHandle(hOutputReadTmp);
CloseHandle(hInputWriteTmp);
memset(&tsi, 0, sizeof(STARTUPINFO));
tsi.cb = sizeof(STARTUPINFO);
tsi.dwFlags = (STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW);
tsi.hStdInput = hInputRead;
tsi.hStdOutput = hOutputWrite;
tsi.hStdError = hErrorWrite;
bool dFlag = CreateProcess(NULL, Cmd.c_str(), &sa, &sa, true, 0, NULL, WorkDir.c_str(), &tsi, &tpi);
if (!dFlag) {
Result = "Unable to run '" + Cmd + "': " + SysErrorMessage(GetLastError());
return "";
}
CloseHandle(hOutputWrite);
CloseHandle(hInputRead );
CloseHandle(hErrorWrite);
bAbort = false;
while (1) {
// 여기서 외부 중지를 할 수 있도록 한다.
// if (CheckAbortFunc != NULL)
// CheckAbortFunc(bAbort);
// if (bAbort) {
// TerminateProcess(tpi.hProcess, 1);
// break;
// }
if ((!ReadFile(hOutputRead, &aBuf, 16, &nRead, NULL)) || (nRead == 0)) {
if (GetLastError() == ERROR_BROKEN_PIPE)
break;
else
MessageDlg("Pipe read error, could not execute file", mtError, TMsgDlgButtons() << mbOK, 0);
}
aBuf[nRead] = 0;
FOutput = FOutput + String(aBuf);
// 라인 단위 출력을 한다.
// if (LineOutputFunc != NULL) {
// CurrentLine = CurrentLine + String(aBuf);
// if (CurrentLine.c_str()[CurrentLine.Length()] == 10) {
// CurrentLine.Delete(CurrentLine.Length(), 1);
// LineOutputFunc(CurrentLine);
// CurrentLine = "";
// }
// }
}
GetExitCodeProcess(tpi.hProcess, &nRead);
if (ShowReturnValue)
Result = FOutput + " " + IntToStr(nRead);
else
Result = FOutput;
CloseHandle(hOutputRead);
CloseHandle(hInputWrite);
CloseHandle(tpi.hProcess);
CloseHandle(tpi.hThread);
return Result;
}
//---------------------------------------------------------------------------
고황일 님이 쓰신 글 :
: 다들 비도 많이 오고 무더운데 고생이 많습니다.
: 이번에 신형 장비를 받고 장비용 프로그램을 짜다 개발 환경이 너무 않좋아서 개발 툴을 작성하고 있습니다.
: 머.. 대단한 실력은 아니지만 그럭저럭 구현을 다 했는데요, 콘솔 리다이렉션이 문제입니다.
: 컴파일/링크 과정에 콘솔 출력들을 ListBox에 표시하고 싶은데요 계속 콘솔 창이 떠버려서 문제입니다.
:
: 이 프로그램이 cygwin에 있는 g++를 이용하여 컴파일을 해야하는데
: 간단하게 g++.exe 파일을 실행만 하면 좋은데.. 몇가지 스크립트를 배치 파일로 작성을
: 해 놨지 뭡니다까... 그래서 스크립트 자동화를 해벌릴려고 했더니 배치 파일내에서
: 소스 파일을 파싱하는 java 프로그램을 실행해서 스크립트가 새로 갱신이 되는 구조로 되어있어서
: 개발 툴내에서 어쩔수 없이 배치 파일을 실행을 해야하는 상황이 생겼습니다.
:
: 포럼내에서 검색해서 찾은 방법은 하나의 실행 파일을 (16bit DOS/32bit 콘솔) 실행했을때는
: 리다이렉션이 가능한데.. 배치파일을 실행하면 콘솔 창이 계속 떠버리는 상황이 발생됩니다.
: 제가 원하는 것은 개발 툴내에서 배치파일을 호출을 해도 모든 콘솔 출력을 ListBox 컴포넌트에
: 기록을 하는건데.. 계속 실패하고 있습니다.
:
: 선배님의 자문을 구합니다.
|