25

Background

Last year I compiled a portable blog/web-server system that I can run from a flash-drive. It’s great and works wonderfully, especially on XP. The problem is that when it’s run in Windows 7, each console program spawns two process, the process itself, plus a copy of conhost.exe.

Problem

In the case of the portable blog system, each one of its server components (MySQL’s mysqld.exe, Apache’s two instances of httpd.exe, VisualSVN’s two instances of visualsvnserver.exe, and PHP’s multiple instances of php-cgi.exe) spawns an instance of conhost.exe. At this moment (with no copies of php-cgi.exe active, I have five instances of conhost.exe running, using up next to no CPU cycles, but consuming 22MB of memory (in addition to the 80MB that the actual processes are currently using).

Research

Since Windows 7 was released (and I think possibly since Vista), I have on several occasions tried to figure out exactly what purpose the various (new) host processes (e.g., conhost.exe, dllhost.exe, and taskhost.exe) do and whether they are actually necessary. I have tried killing them and found that the console programs continue to work, both for programs that use a console window, and those that don’t (like servers).

I am already familiar with the whole csrss.exe ⇨ Windows Vista ⇨ conhost.exe and have seen that same (almost verbatim) explanation numerous times. The problem is that everybody simply copy-pastes that same explanation which is not helpful. All it says is that in XP-, console applications where “hosted by” or “run under” csrss.exe, but in Windows 7, they were moved to conhost.exe for security. The security aspect makes sense, but it says nothing about what it means to host it or why/when it’s necessary (or whether it’s possible to avoid it if not necessary). Even Raymond Chen’s discussion on the matter glosses over why console apps are hosted differently at all.

The closest thing I can find to a detailed, technical explanation is a Microsoft blog post which seems to reinforce the idea that it’s merely about the console app’s GUI and window. This leaves me wondering even harder whether conhost.exe is necessary for windowless programs like these servers. If there is no window at all, then why should I have to waste resources and clutter the process-space with unnecessary processes? Why can’t Windows detect when it’s unnecessary and avoid it? SecurityMatt’s response was also slightly useful in regards to a technical explanation, but again, not enough of the information I’m looking for.

I’m not the only one who has tried to figure out a way to stop unnecessary instances of conhost. This person asked about disabling it and was told simply “it’s not possible” with no further effort or thought about it. Hugh D and “Hardly a feature” pointed out the issue with numerous, redundant instances of conhost (at least with csrss, there was only a single copy running), including the resource usage and lingering instances after their child processes have ended. I Laufer questioned whether/when it’s even necessary.

Observations and Solution Attempts

If they are not actually necessary at all times (again, I have not seen any ill effects from killing them), then I suppose I could (very irritatingly) work-around the issue by replacing the servers with batch-files that run the servers, wait, and then kill the copy of conhost that they cause to run. Of course this requires a quick and easy way of determining which one it is. FallenGameR asked how to get the instance of conhost.exe associated with a console program of a given PID but did not get an answer. I would think that simply retrieving the PID of the parent process should do the trick (no, ProcessExplorer is not an option, an automated/scriptable solution is required), but not only would that require creating some sort of framework to get the PID of the child (instead of simply running it and being done with the task), but it would also mean figuring out a way to make it compatible with XP as well (e.g., checking the image-name of the parent process). This blog post gives one way, but it requires PowerShell and is hardly ideal, not to mention it says nothing about the ramifications of running the script.

Question(s)

Perhaps Microsoft figure that nobody uses command-prompts anymore (*cough*Windows 8*cough*) and so assumed that it’s not a big deal to burden them, but there are definitely scenarios where multiple console apps are running and having each and every one spawn an extra, memory-consuming, PID-using process is awful, and trying to work around it is, at best, horribly inconvenient.

Does anybody have definitive, authoritative information on the matter? Again, I have already read the generic explanation; I am wondering:

  1. Why console applications must (still) be handled differently at all
  2. Under what specific circumstances they need to have conhost
  3. What the consequences are of killing conhost
  4. If there’s any way to stop/prevent/disable/block it or at least an easy way to quickly deal with it aftwards?
4
  • 1
    Before anybody bothers to link to it (or vote to close as a duplicate of it, I have already seen other questions here like [this one]). Like I said, dragging-and-dropping a file to a windowless console app is irrelevant, so why is conshost.exe still spawning?
    – Synetech
    Jul 25, 2013 at 19:48
  • 1
    From what I've read, part of the problem is that Windows does not handle consoles like *nix does. They are not simply character devices, and not interoperable as such at all (There's a very good discussion about this under the PuTTY feature request to support using PuTTY as a local command terminal). I had always figured that conhost.exe was the Windows' equivalent of a PTY, and cmd.exe was the shell. Jul 25, 2013 at 21:00
  • @techie007, that’s the page that I (tried to) link to in my comment above.
    – Synetech
    Jul 26, 2013 at 1:17

3 Answers 3

19
  1. Console applications must be differently handled because under the NT kernel (which underlies all of 2000, XP, Vista, Windows 7, and Windows 8) they are second-class citizens. In the Unix system architecture, every process at creation time has the standard input, output, and error streams attached to it; terminal IO is implemented in terms of these streams (stdin coming from the keyboard, and stdout/stderr going to the terminal), and extra effort is required on the part of a process which doesn't wish to make use of those streams or have their file descriptors open.

    In the Windows NT architecture, which while not a lineal descendant of VMS was developed by more or less the same team, the opposite is true; a newly spawned process by default has no I/O streams connected to it at all, and there is no such concept as a "terminal". Programs which wish to behave in a slightly more Unixy fashion may request (by compile-time declaration) that the system create for them a console window, and input/output streams connected to it; the system will do so, but since Windows, unlike Unix, doesn't give you terminals for free, a considerable amount of additional effort is required to create one, thus formerly csrss.exe, and now conhost.exe.

    As for the difference between the two, your "Hardly a feature" link explains it quite adequately; in short, it exists to work around a security flaw in the previous iteration of Windows's highly recondite console API, which allowed for privilege escalation in versions of NT older than Windows 7. (Vista, FYI, does not have conhost.exe, which is befitting of its status as the Windows Millennium of the NT family.)

  2. Any program which wants the equivalent of Unix stdin/stdout/stderr needs a console, hence an instance of conhost.exe. Immigrants from Unix-land, such as Apache, PHP, et al., are going to want these streams, hence the system's automatic instantiation of conhost.exe for them, whether they actually display a window or not. In theory, it would be possible to modify the source for e.g. Apache such that it required no terminal, and compile it as a Windows GUI application instead of a console application, so that the system wouldn't feel the need to spawn it a conhost.exe. Assuming it's also possible in practice, no one seems to have cared enough to do so. Perhaps you will be the first.

  3. Killing a given conhost.exe will almost certainly disable console IO for whatever process is running under that instance. You probably don't care about that because you're dealing with server processes that aren't doing anything interesting on the console IO streams anyway, so there's probably no reason not to kill their conhost.exes. If in doubt, kill them off and see if it breaks anything.

  4. There is no way to prevent Windows from instantiating conhost.exe when a program is launched which requests console IO; the only way to do so would be to recompile it so that Windows doesn't regard it as a console application. However, assuming that killing a given server process's parent conhost.exe doesn't impair its functionality in any way you care about, you should be able to kill them all at once by issuing taskkill /f /im conhost.exe in a Run prompt or a console window -- preferably the former, since the latter will probably die, and almost certainly cease to work, as soon as its parent conhost.exe instance is killed. Again, if in doubt, kill them off and see if it breaks anything.

20
  • 5
    All that said, a portable server stack on a Flash drive sounds like it never spends much time running on any given machine, and 22M is roughly 1% of the RAM complement of the lowest-end machine you can even easily buy these days. Is it really enough of a problem to be worth this much time and effort? Jul 25, 2013 at 21:53
  • All that said, a portable server stack on a Flash drive sounds like it never spends much time running on any given machine I don’t know what this means. Are you talking about CPU cycles? If so, then a web-server can get quite hammered if the site is popular enough (and hammered even if it’s not; PHP on Windows isn’t exactly CPU cheap). If you mean how often it is run in general, I leave it running on my laptop all week long.
    – Synetech
    Jul 26, 2013 at 1:22
  • 22M is roughly 1% of the RAM complement of the lowest-end machine you can even easily buy these days. Is it really enough of a problem to be worth this much time and effort? You don’t run a personal web-server on a new machine, you run it on an old system that isn’t useful for much else. (In 1997 a friend told me he was running a Linux web-server on an old and minimal—by that time’s standard—system.) Since it’s portable, it has to be able to be as compatible as possible. And it’s not just the memory; for one thing, it also pollutes the process-space and clutters Task Manager.
    – Synetech
    Jul 26, 2013 at 1:27
  • Vista, FYI, does not have conhost.exe, which is befitting of its status as the Windows Millennium of the NT family. That’s why I put Vista between csrss to conhost; it was a middle step. As for poor Windows ME, don’t bad-mouth it. I recently re-played Jewels of the Oracle by running it in XP in VMPlayer, but when I tried to play Jewels II, I couldn’t. It wouldn’t run in XP or 2000. It runs in 98, but 98 has poor audio-video support in VMPlayer and VirtualBox. After a dozen attempts, I found that the only combination of OS & VM that lets the game work correctly was ME in VMPlayer.
    – Synetech
    Jul 26, 2013 at 1:37
  • 4
    In order: When I hear "portable server stack on a Flash drive", I think "user can't dedicate a box to it and needs it easily movable between machines", because there is no other good reason to do it that way. If you're already dealing with VM overhead, why not just run your web server stack on a Linux VM? No conhost.exe that way. And as for Windows ME, I had to try to support it back when it was new, and you can cite all the obscure, belated corner cases you like without budging my opinion of that dog's breakfast of an OS, which I could badmouth all day without doing it justice. Jul 26, 2013 at 4:06
7

A console application started with the DETACHED_PROCESS flag does get a console nor a conhost child process. The problem is that the flag does not apply to grand-children so it will only work with the processes you start directly (if you even can find a utility that allows you to specify this flag).

The other option that might work is if the console process calls the FreeConsole() function. Some server applications support a -d or -detach parameter but this is probably more common on *nix systems...

1
  • 1
    That sounds brilliant. None of those pages mention conhost, but the connection seems fairly clear. I will do some tests to see what kind of effects it has.
    – Synetech
    Apr 5, 2014 at 16:48
2

Quick solution that may work for you. When linking your application add /SUBSYSTEM:WINDOWS to the options. You could also used editbin.exe to modify an existing executable.

This prevents windows from spawning a conhost.exe for you application.

2
  • That sounded promising, but I just tried it and it did not work. I used it to change the subsystem for mysqld, but when I ran that, it still spawned a conhost instance.
    – Synetech
    Sep 18, 2013 at 14:58
  • Could it be that stderr is still required for mysqld and, thus, it needs conhost? Jan 19, 2016 at 17:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .