MiniCon

Running on old Windows

MiniCon runs on Windows Server 2016 and Windows 10 version 1607 (build 14393). Most modern terminals do not, and the reasons are specific enough to be worth writing down — both so you can verify the claim and so you can diagnose it if your machine is older still.

Why other terminals stop there

Windows gained a pseudoconsole — CreatePseudoConsole, usually called ConPTY — in Windows 10 build 17763 (version 1809). A terminal built on it cannot run on anything earlier.

Microsoft does publish ConPTY as a redistributable (Microsoft.Windows.Console.ConPTY: conpty.dll plus OpenConsole.exe, which is what WezTerm bundles). It does not lower the floor: the package states it supports 10.0.17763.0 and above, the same version as the in-box API. Shipping it does not buy you Server 2016.

What MiniCon does instead

It resolves ConPTY at run time, and falls back

The three entry points are looked up with GetProcAddress rather than imported. That distinction matters more than it sounds: every static import is resolved by the PE loader before main runs, so one missing symbol does not disable a feature — it refuses to start the program at all, with a dialog naming a symbol you cannot act on.

When the lookup fails, MiniCon starts a console agent: it re-executes itself with an internal argument, that second process takes a hidden console, spawns your shell into it, and polls the screen buffer with ReadConsoleOutputW, turning what changed into a terminal stream. This is the mechanism every Windows terminal used before 1809. The APIs are as old as Win32.

The agent is MiniCon itself. No third-party binary, no winpty-agent.exe, no extra file to deploy.

Selection is by capability, not by version number

MiniCon asks the system whether the exports are there. A build-number comparison would have to be revisited if anything ever lowered the floor; the version number is only used for the message you read.

Everything above the adapter is identical either way — the same pipes, the same command line, the same environment. Nothing in the terminal knows which backend it got.

No Visual C++ redistributable

A clean Server 2016 has no VCRUNTIME140.dll. MiniCon links the VC runtime statically and depends only on modules Windows itself provides:

advapi32.dll   gdi32.dll     gdiplus.dll   imm32.dll
kernel32.dll   ntdll.dll     shell32.dll   user32.dll
api-ms-win-core-synch-l1-2-0.dll
api-ms-win-crt-heap-l1-1-0.dll
api-ms-win-crt-runtime-l1-1-0.dll
api-ms-win-crt-string-l1-1-0.dll

The api-ms-win-crt-* entries are the Universal CRT, an operating-system component since Windows 10 RTM — not a redistributable. A gate in the test suite parses the shipped executable's import table and fails if anything outside that set appears, so this cannot quietly regress.

panic = "unwind" is preserved. Panic containment is not traded away for the dependency: a panic in a background thread is caught rather than taking the process down.

SetThreadDescription, or why documentation is not proof

Worth knowing if you port anything else to build 14393.

Microsoft documents SetThreadDescription as available in Windows 10 version 1607. Windows Server 2016 is 1607. It is still missing there, because 1607 implements it only in KernelBase.dll and the kernel32 forwarder did not appear until 1703. The SDK's own header guards do not catch this either — the guard passes.

A documented minimum version is evidence. Only the target machine is proof.

Checking your own machine

Ask MiniCon first

--status reports what this machine actually gave it. It opens no window and starts no session, so it works on a machine where opening a terminal is the thing that does not work:

minicon.exe --status
minicon 0.1.0

  pty backend    console-agent
                 Windows build 14393 has no ConPTY; a pseudoconsole needs build 17763 (1809)
  font           新宋体 (8x15 cells)
                 half/full width correct
  diagnostics    C:\Users\you\AppData\Roaming\agenterm-diagnostics.log

Every line is a property of the running system rather than of the build, which is why none of it can be answered by reading the source. If you are reporting a problem, this output is the most useful thing to send — it identifies the binary, the Windows, the backend it chose and the font the system really resolved to, and it names the file MiniCon writes to when something fails.

If it will not start at all

Then --status cannot run either, and the cause is almost always a static import the system cannot resolve. The loader names exactly one of them at a time — so fixing the one it named just reveals the next.

scripts/probe-imports.ps1 answers the whole question at once. Run it on the machine that fails:

powershell -ExecutionPolicy Bypass -File probe-imports.ps1 -Path .\minicon.exe

It parses the executable's import table itself — the target needs no Visual Studio — resolves every named import against the running system, and prints the complete missing set. Send that list rather than the first name.

What you give up

The fallback reads a console screen buffer on a timer. It is a faithful terminal for a shell and for the console programs Windows ships, but it is not a pseudoconsole:

On Windows 10 1809 and newer, none of this applies — MiniCon uses ConPTY and the agent never starts.