Skip to content

Commit

Permalink
bugfix: not print anything at cli mode
Browse files Browse the repository at this point in the history
  • Loading branch information
tomwillow committed Nov 29, 2023
1 parent 7203e45 commit b0ed6d1
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 1 deletion.
14 changes: 13 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/source-charset:utf-8>")

project(SmartCharsetConverter)

# === guicon ============================
add_library(guicon STATIC
${PROJECT_SOURCE_DIR}/third_party/guicon/guicon.h
${PROJECT_SOURCE_DIR}/third_party/guicon/guicon.cpp
)

# === SmartCharsetConverter =============

# 添加代码
file(GLOB COMMON_CODE
src/Common/*.h
Expand All @@ -28,6 +36,7 @@ add_definitions(-DUNICODE -D_UNICODE)
# 添加include目录
include_directories(
${PROJECT_SOURCE_DIR}
${PROJECT_SOURCE_DIR}/third_party
${PROJECT_SOURCE_DIR}/third_party/WTL/include
${PROJECT_SOURCE_DIR}/src/Common
${PROJECT_SOURCE_DIR}/src/Control
Expand Down Expand Up @@ -67,7 +76,9 @@ add_executable(${PROJECT_NAME}
target_sources(${PROJECT_NAME} PRIVATE src/SmartCharsetConverter.rc)

# 链接uchardet
target_link_libraries(${PROJECT_NAME} libuchardet_static)
target_link_libraries(${PROJECT_NAME}
libuchardet_static
guicon)

# 完成后拷贝icu dll
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
Expand All @@ -81,4 +92,5 @@ add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD

# VS 设置 Subsystem 选项
set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS")
set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS_RELWITHDEBINFO "/SUBSYSTEM:WINDOWS")
set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS_MINSIZEREL "/SUBSYSTEM:WINDOWS")
28 changes: 28 additions & 0 deletions src/CLIHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@
#include "FileFunction.h"
#include "ConsoleSettings.h"

#include <guicon/guicon.h>

#include <sstream>
#include <iostream>
#include <filesystem>
#include <memory>

using std::wcerr;
using std::wcout;
Expand Down Expand Up @@ -47,6 +50,31 @@ SmartCharsetConverter --input <path>... --target_charset <charset> [--target_lin
)";

int CLIMain(const std::vector<std::wstring> &args) noexcept {

try {
bool ok = AttachParentConsole(1024);
if (!ok) {
throw std::runtime_error("failed to AttachParentConsole");
}

} catch (const std::runtime_error &err) {
MessageBoxA(NULL, err.what(), "Error", MB_OK | MB_ICONERROR);
return -1;
}

std::shared_ptr<void> defer(nullptr, [](auto) {
try {
bool ok = ReleaseConsole();
if (!ok) {
throw std::runtime_error("failed to ReleaseConsole");
}

} catch (const std::runtime_error &err) {
MessageBoxA(NULL, err.what(), "Error", MB_OK | MB_ICONERROR);
return -1;
}
});

enum class TaskType { PURE_PRINT, CONVERT };
TaskType taskType = TaskType::CONVERT;
bool setInput = false;
Expand Down
131 changes: 131 additions & 0 deletions third_party/guicon/guicon.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#include "guicon.h"

#include <tlhelp32.h>

#include <memory>
#include <stdexcept>
#include <cassert>
#include <iostream>

DWORD GetParentPID() {
int pid = GetCurrentProcessId();
HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
std::shared_ptr<void> defer(nullptr, [h](auto) {
CloseHandle(h);
});

PROCESSENTRY32 pe = {0};
pe.dwSize = sizeof(PROCESSENTRY32);

if (!Process32First(h, &pe)) {
throw std::runtime_error("failed at Process32First");
}

DWORD parentPid = 0;

do {
if (pe.th32ProcessID != pid) {
continue;
}

assert(parentPid == 0);

parentPid = pe.th32ParentProcessID;
} while (Process32Next(h, &pe));

return parentPid;
}

bool ReleaseConsole() {
bool result = true;
FILE *fp;

// Just to be safe, redirect standard IO to NUL before releasing.

// Redirect STDIN to NUL
if (freopen_s(&fp, "NUL:", "r", stdin) != 0)
result = false;
else
setvbuf(stdin, NULL, _IONBF, 0);

// Redirect STDOUT to NUL
if (freopen_s(&fp, "NUL:", "w", stdout) != 0)
result = false;
else
setvbuf(stdout, NULL, _IONBF, 0);

// Redirect STDERR to NUL
if (freopen_s(&fp, "NUL:", "w", stderr) != 0)
result = false;
else
setvbuf(stderr, NULL, _IONBF, 0);

// Detach from console
if (!FreeConsole())
result = false;

return result;
}

bool RedirectConsoleIO() {
bool result = true;
FILE *fp;

// Redirect STDIN if the console has an input handle
if (GetStdHandle(STD_INPUT_HANDLE) != INVALID_HANDLE_VALUE)
if (freopen_s(&fp, "CONIN$", "r", stdin) != 0)
result = false;
else
setvbuf(stdin, NULL, _IONBF, 0);

// Redirect STDOUT if the console has an output handle
if (GetStdHandle(STD_OUTPUT_HANDLE) != INVALID_HANDLE_VALUE)
if (freopen_s(&fp, "CONOUT$", "w", stdout) != 0)
result = false;
else
setvbuf(stdout, NULL, _IONBF, 0);

// Redirect STDERR if the console has an error handle
if (GetStdHandle(STD_ERROR_HANDLE) != INVALID_HANDLE_VALUE)
if (freopen_s(&fp, "CONOUT$", "w", stderr) != 0)
result = false;
else
setvbuf(stderr, NULL, _IONBF, 0);

// Make C++ standard streams point to console as well.
std::ios::sync_with_stdio(true);

// Clear the error state for each of the C++ standard streams.
std::wcout.clear();
std::cout.clear();
std::wcerr.clear();
std::cerr.clear();
std::wcin.clear();
std::cin.clear();

return result;
}

void AdjustConsoleBuffer(short minLength) {
// Set the screen buffer to be big enough to scroll some text
CONSOLE_SCREEN_BUFFER_INFO conInfo;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &conInfo);
if (conInfo.dwSize.Y < minLength)
conInfo.dwSize.Y = minLength;
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), conInfo.dwSize);
}

bool AttachParentConsole(short minLength) {
bool result = false;

// Release any current console and redirect IO to NUL
ReleaseConsole();

// Attempt to attach to parent process's console
if (AttachConsole(ATTACH_PARENT_PROCESS)) {
AdjustConsoleBuffer(minLength);
result = RedirectConsoleIO();
}

return result;
}
11 changes: 11 additions & 0 deletions third_party/guicon/guicon.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#pragma once

#include <Windows.h>

DWORD GetParentPID();

bool ReleaseConsole();

bool RedirectConsoleIO();

bool AttachParentConsole(short minLength);

0 comments on commit b0ed6d1

Please sign in to comment.