diff --git a/core/cli.py b/core/cli.py index f0fbdca..7e8d77b 100644 --- a/core/cli.py +++ b/core/cli.py @@ -66,7 +66,55 @@ def _print(line: str) -> None: - print(line, flush=True) + try: + print(line, flush=True) + except OSError: + pass + + +def _ensure_cli_stdio() -> None: + """Give the packaged (windowed) build real stdio for CLI mode. + + PyInstaller builds flint with ``console=False``, so the GUI never + flashes a console. CLI invocations launched from PowerShell or + Explorer then have no stdout handle at all and ``print`` raises + OSError under Python 3.14's stricter stdio handling. When the std + handles are not real files or pipes (cmd-style redirection), attach + to the parent console instead so CLI output is visible. In dev there + is a real console and nothing happens. + """ + if not getattr(sys, "frozen", False): + return + try: + import msvcrt + + for stream in (sys.stdout, sys.stderr): + fd = stream.fileno() + handle = msvcrt.get_osfhandle(fd) + if handle != -1 and ctypes.windll.kernel32.GetFileType(handle) in ( + 1, + 3, + ): + return + except Exception: + pass + try: + # ATTACH_PARENT_PROCESS: reuse the console of the process that + # launched us, then reopen the standard streams onto it. + if ctypes.windll.kernel32.AttachConsole(0xFFFFFFFF): + # These streams must outlive the function; they become + # sys.stdout/stderr/stdin for the rest of the process. + sys.stdout = open( # noqa: SIM115 + "CONOUT$", "w", encoding="utf-8", errors="replace" + ) + sys.stderr = open( # noqa: SIM115 + "CONOUT$", "w", encoding="utf-8", errors="replace" + ) + sys.stdin = open( # noqa: SIM115 + "CONIN$", "r", encoding="utf-8", errors="replace" + ) + except Exception: + pass def _opts(argv: list[str]) -> tuple[dict[str, str | bool], str | None]: @@ -568,6 +616,7 @@ def _cmd_queue(opts: dict[str, str | bool]) -> int: def main(argv: list[str] | None = None) -> int: + _ensure_cli_stdio() argv = list(sys.argv[1:] if argv is None else argv) if "--cli" in argv: argv.remove("--cli") diff --git a/core/version.py b/core/version.py index 430a0e8..998e45d 100644 --- a/core/version.py +++ b/core/version.py @@ -4,4 +4,4 @@ ``setup.py`` when bumping. """ -APP_VERSION = "1.0.2" \ No newline at end of file +APP_VERSION = "1.0.3" \ No newline at end of file diff --git a/setup.py b/setup.py index 8a962bf..40faf5f 100644 --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ setup( name="flint-native", - version="1.0.2", + version="1.0.3", description="Optional native writer extension for Flint", ext_modules=[ Extension( diff --git a/version_info.txt b/version_info.txt index e4536fa..1edd127 100644 --- a/version_info.txt +++ b/version_info.txt @@ -1,7 +1,7 @@ VSVersionInfo( ffi=FixedFileInfo( - filevers=(1, 0, 2, 0), - prodvers=(1, 0, 2, 0), + filevers=(1, 0, 3, 0), + prodvers=(1, 0, 3, 0), mask=0x3F, flags=0x0, OS=0x40004, @@ -17,11 +17,11 @@ VSVersionInfo( [ StringStruct("CompanyName", "Flint"), StringStruct("FileDescription", "Flint — bootable USB writer"), - StringStruct("FileVersion", "1.0.2"), + StringStruct("FileVersion", "1.0.3"), StringStruct("InternalName", "flint"), StringStruct("OriginalFilename", "flint.exe"), StringStruct("ProductName", "Flint"), - StringStruct("ProductVersion", "1.0.2"), + StringStruct("ProductVersion", "1.0.3"), ], ) ]