이, IIRC을 할 수있는 쉬운 일이 아니다. 문제는 Windows에서 실행 파일 자체가 GUI 응용 프로그램이든 콘솔 응용 프로그램이든 플래그를 가지고 있다는 것입니다. cmd.exe
은 둘 중 하나를 실행할 때 다르게 동작합니다. 응용 프로그램의 핵심 기능을 라이브러리로 분할하고 별도의 CLI 및 GUI 프론트 엔드를 구축하는 것이 좋습니다.
EDIT : 정말로 주장한다면, 이것은 목표를 향해 먼 길을 간다.goto
그것이 지금 if
로 대체 될 수있는 역사적 이유가있다 :
static
bool
usable_handle (HANDLE h)
{
return h && h != INVALID_HANDLE_VALUE;
}
static
bool
try_reopen_std_handle (int dest_handle, DWORD os_handle_num, HANDLE os_handle,
int flags)
{
if (! usable_handle (os_handle))
return false;
int ret = SetStdHandle (os_handle_num, os_handle);
assert (ret);
if (! ret)
return false;
int base_flags = 0;
#if defined (UNICODE)
//base_flags = _O_WTEXT;
#endif
int opened_handle = _open_osfhandle (reinterpret_cast<intptr_t>(os_handle),
flags | base_flags);
assert (opened_handle != -1 && "_open_osfhandle");
if (opened_handle == -1)
return false;
int dupd_handle = _dup2 (opened_handle, dest_handle);
assert (dupd_handle != -1 && "_dup2");
return dupd_handle == 0;
}
static
bool
try_fdopen (FILE * f, int handle, char const * mode)
{
FILE * tmp = _fdopen (handle, mode);
if (tmp && f)
*f = *tmp;
return !! tmp;
}
static
HANDLE
try_dup_os_handle (HANDLE src)
{
if (! usable_handle (src))
return INVALID_HANDLE_VALUE;
HANDLE dest = INVALID_HANDLE_VALUE;
HANDLE const process = GetCurrentProcess();
if (DuplicateHandle (process, src, process, &dest, 0, TRUE,
DUPLICATE_SAME_ACCESS))
return dest;
else
return INVALID_HANDLE_VALUE;
}
static
void
init_std_io()
{
// Retrieve inherited standard handles. AttachConsole() will close
// the existing standard handles, so we duplicate them here first
// to keep them alive.
HANDLE os_stdin = try_dup_os_handle (GetStdHandle (STD_INPUT_HANDLE));
HANDLE os_stdout = try_dup_os_handle (GetStdHandle (STD_OUTPUT_HANDLE));
HANDLE os_stderr = try_dup_os_handle (GetStdHandle (STD_ERROR_HANDLE));
// Attach existing console or allocate a new one.
int ret = AttachConsole (ATTACH_PARENT_PROCESS);
if (ret)
OutputDebugString (_T("Attached existing console.\n"));
else
{
ret = AllocConsole();
if (ret)
OutputDebugString (_T("Allocated new console.\n"));
else
OutputDebugString (_T("Failed to allocate new console.\n"));
assert (ret);
}
// Open a "POSIX" handle for each OS handle and then fdopen() a C stream
// for each such "POSIX" handle.
//
// Only use the standard handle provided by AttachConsole() if the standard
// handle from before AttachConsole() is not usable.
//
// Finally, re-open standard C stream.
if (! usable_handle (os_stdin))
os_stdin = GetStdHandle (STD_INPUT_HANDLE);
ret = try_reopen_std_handle (0, STD_INPUT_HANDLE, os_stdin, _O_RDONLY);
if (! ret)
goto do_stdout;
try_fdopen (stdin, 0, "r");
do_stdout:
if (! usable_handle (os_stdout))
os_stdout = GetStdHandle (STD_OUTPUT_HANDLE);
ret = try_reopen_std_handle (1, STD_OUTPUT_HANDLE, os_stdout, _O_WRONLY);
if (! ret)
goto do_stderr;
try_fdopen (stdout, 1, "w");
do_stderr:
if (! usable_handle (os_stderr))
os_stderr = GetStdHandle (STD_ERROR_HANDLE);
ret = try_reopen_std_handle (2, STD_ERROR_HANDLE, os_stderr, _O_WRONLY);
if (! ret)
goto done_stderr;
try_fdopen (stderr, 2, "w");
done_stderr:;
}
당신의 대답은 재미있는 것, 내가을 포함해야했다 그러나 충분하지 않는 것 같습니다. _O_TEXT는 아직 정의되지 않았습니다. 어떤 파일을 포함시켜야합니까? –
포함 할 올바른 파일을 찾았지만 작동하지 않습니다. cmd 상자에서 시작할 때, 새 상자를 생성하고 (아마 거기에 내용을 인쇄 한 다음) 닫습니다. –
이것은 다소 이상하게 보입니다. 'HANDLE '은 8 바이트 너비 일 수 있지만 4 바이트 길이로 변환합니다. 확실합니까? –