(何时)确实需要CONHOST.EXE?


23

背景

去年,我编译了一个可移植的博客/网络服务器系统,该系统可以从闪存驱动器上运行。它很棒,而且效果很好,尤其是在XP上。问题在于,当它在Windows 7中运行时,每个控制台程序都会生成两个进程,该进程本身,以及的副本conhost.exe

问题

对于便携式博客系统,其服务器组件的每个组件(MySQL的mysqld.exe,Apache的两个实例httpd.exe,VisualSVN的两个实例visualsvnserver.exe以及PHP的多个实例php-cgi.exe)都产生一个实例conhost.exe。目前(没有php-cgi.exe活动副本),我有五个conhost.exe正在运行的实例,几乎没有CPU周期用完,但是却消耗了22MB的内存(除了实际进程当前正在使用的80MB外)。

研究

由于Windows 7发布(我想可能是因为Vista的),我有几次试图弄清楚究竟什么样的目的不同(新)主机进程(例如conhost.exedllhost.exetaskhost.exe),以及它们是否真的必要。我尝试杀死它们,发现控制台程序对于使用控制台窗口的程序和不使用控制台窗口的程序(例如服务器)都可以继续工作。

我已经对整个csrss.exe⇨Windows Vista⇨conhost.exe很熟悉,并且已经多次看到相同的解释(几乎逐字记录)。问题在于,每个人都只是复制粘贴相同的解释而没有帮助。它所说的只是在XP-控制台应用程序中“由...托管”或“在...下运行” csrss.exe,但在Windows 7中,它们被移至conhost.exe安全性考虑。安全方面是有道理的,但它没有说明托管它的含义或必要的理由/时间(或在没有必要的情况下是否有可能避免托管)。就连Raymond Chen 对此的讨论也掩盖了为什么控制台应用程序托管完全不同的原因。

我可以找到最接近详细的技术说明的内容是Microsoft博客文章,它似乎在强化这种想法,即仅涉及控制台应用程序的GUI和窗口。这使我更加想知道,conhost.exe对于像这些服务器这样的无窗口程序是否必要。如果根本没有窗口,那为什么我要浪费资源并用不必要的过程来使过程空间混乱?Windows为什么无法检测到何时不必要并避免它?关于技术说明,SecurityMatt的回复也很有用,但同样,我所寻找的信息不足。

我并不是唯一尝试找出一种方法来停止不必要的实例的人conhost此人询问要禁用它,并被告知“不可能”,没有进一步的努力或思考。Hugh D“难得的功能”指出了许多冗余实例的问题conhost(至少使用csrss,只有一个副本在运行),包括资源使用情况和子进程结束后的剩余实例。我劳弗(Laufer)质疑是否/何时需要。

观察和解决方案尝试

如果实际上并非始终都需要它们(再次,我没有看到杀死它们的任何不良影响),那么我想我可以(非常令人讨厌)通过用运行服务器的批处理文件替换服务器来解决该问题。 ,等待,然后杀死conhost它们导致运行的副本。当然,这需要一种快速简便的方法来确定它是哪一个。FallenGameR询问如何获取conhost.exe与给定PID的控制台程序相关联的实例,但没有得到答案。我认为,简单地获取父进程的PID应该可以解决问题(不,ProcessExplorer不是一种选择,它是自动/可编写的解决方案是必需的),但不仅需要创建某种框架来获取子代的PID(而不是简单地运行它并完成任务),而且还意味着需要找到一种使其兼容的方法以及XP(例如,检查父进程的映像名称)。这篇博客文章提供了一种方法,但是它需要PowerShell,并且并不是理想的选择,更不用说它对运行脚本的后果一无所知。

问题

也许微软认为没有人再使用命令提示符了(*咳嗽* Windows 8 *咳嗽*),因此假设负担不大,但是肯定有多个控制台应用程序正在运行并且每个都有一个的情况。产生一个额外的,消耗内存的,使用PID的过程是很糟糕的,而尝试解决这个问题,充其量是非常不便的。

有人对此事有权威的权威信息吗?同样,我已经阅读了通用说明;我想知道:

  1. 为什么控制台应用程序必须(仍然)以完全不同的方式处理
  2. 在什么样的具体情况,他们需要conhost
  3. 杀戮的后果是什么conhost
  4. 是否有任何方法可以阻止/阻止/禁用/阻止它,或者至少有一种简单的方法可以迅速地对其进行处理?

1
在任何人麻烦链接之前(或投票关闭它的副本,我已经在这里看到了其他问题,例如[this])。就像我说的那样,将文件拖放到无窗口的控制台应用程序是无关紧要的,那么为什么conshost.exe仍然生成?
Synetech

1
根据我的阅读,部分问题是Windows无法像* nix一样处理控制台。它们不仅是字符设备,而且根本就不能互操作(在PuTTY功能请求下对此进行了很好的讨论,以支持使用PuTTY作为本地命令终端。)我一直认为那conhost.exe是Windows相当于PTY cmd.exe的外壳。
达斯Android


@ techie007,这是我(尝试)在上面的评论中链接到的页面。
Synetech

Answers:


19
  1. 控制台应用程序必须以不同的方式处理,因为在NT内核(属于2000,XP,Vista,Windows 7和Windows 8的所有内核)下,它们是二等公民。在Unix系统体系结构中,每个进程在创建时都附加了标准的输入,输出和错误流。终端IO是根据这些流(来自键盘的stdin和去往终端的stdout / stderr)实现的,在过程中,不希望使用这些流或具有它们的文件描述符打开。

    在Windows NT体系结构中,虽然不是由几乎相同的团队开发的VMS的直系后代,但事实恰恰相反。默认情况下,新产生的进程根本没有连接到任何I / O流,也没有“终端”这样的概念。希望以Unixy方式运行的程序可能会(通过编译时声明)请求系统为它们创建一个控制台窗口,以及与其连接的输入/输出流。系统会这样做,但由于Windows与Unix不同,它不能免费为您提供终端,因此创建以前csrss.exe(现在)的终端需要大量的额外工作conhost.exe

    至于两者之间的区别,您的“很难使用的功能”链接可以充分说明这一点;简而言之,它可以解决Windows高度隐秘控制台API的先前迭代中的一个安全漏洞,该漏洞允许在Windows 7之前的NT版本中提升特权conhost.exe。身份为NT家族的Windows Millennium。)

  2. 任何想要与Unix stdin / stdout / stderr等效的程序都需要一个控制台,因此需要一个实例conhost.exe。来自Unix领域的移民(例如Apache,PHP等)将需要这些流,因此系统会自动conhost.exe为其自动实例化(无论它们是否实际显示窗口)。从理论上讲,可以修改Apache之类的源代码,使其不需要终端,并将其编译为Windows GUI应用程序而不是控制台应用程序,从而使系统无需产生它conhost.exe。假设在实践中这也是可能的,那么似乎没有人足够关心。也许您将是第一个。

  3. 杀死给定对象conhost.exe几乎可以肯定会禁用该实例下正在运行的任何进程的控制台IO。您可能并不在乎,因为您要处理的服务器进程无论如何都不会在控制台IO流上执行任何有趣的操作,因此可能没有理由不杀死它们conhost.exe。如果有疑问,请杀死他们,看看它是否能破坏任何东西。

  4. 无法阻止Windows conhost.exe在启动要求控制台IO的程序时实例化。这样做的唯一方法是重新编译它,以使Windows不会将其视为控制台应用程序。但是,假设杀死给定服务器进程的父进程conhost.exe不会以您关心的任何方式损害其功能,则应该能够通过taskkill /f /im conhost.exe在运行提示符或控制台窗口中发出命令来杀死它们,最好是前者,因为一旦其父conhost.exe实例被杀死,后者可能会死,并且几乎肯定会停止工作。同样,如果有疑问,请杀死他们,看看它是否能破坏任何东西。


5
话虽这么说,闪存驱动器上的便携式服务器堆栈听起来好像从来没有花费任何时间在任何给定机器上运行,而22M大约是您如今可以轻松购买的最低端机器的RAM补充的1%。花费这么多的时间和精力真的足够一个问题吗?
亚伦·米勒

All that said, a portable server stack on a Flash drive sounds like it never spends much time running on any given machine 我不知道这是什么意思。您是否在谈论CPU周期?如果是这样,那么如果该站点足够受欢迎,那么Web服务器可能会受到重创(即使不是那样,也会受到重创; Windows上的PHP并不完全便宜CPU)。如果您是说它通常运行一次,那么我会整周在笔记本电脑上运行它。
Synetech

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? 您不会在新计算机上运行个人Web服务器,而是在旧系统上运行它对其他方面没有多大用处。(1997年,一个朋友告诉我,他当时是在旧的和最小的系统上运行Linux Web服务器(按照当时的标准)。)由于它是可移植的,因此必须尽可能兼容。这不仅是记忆;一方面,它还会污染进程空间并使任务管理器混乱。
Synetech

Vista, FYI, does not have conhost.exe, which is befitting of its status as the Windows Millennium of the NT family. 这就是为什么我把Vista的之间csrssconhost; 这是中间步骤。至于糟糕的Windows ME,请不要误以为是。我最近通过在VMPlayer中的XP中运行它来重新播放Oracle珠宝,但是当我尝试播放Jewels II时,我无法。它不能在XP或2000中运行。它可以在98中运行,但是98在VMPlayer和VirtualBox中对音频视频的支持较差。经过十几次尝试,我发现使游戏正确运行的OS和VM的唯一组合是VMPlayer中的ME。
Synetech

4
顺序:当我听到“闪存驱动器上的便携式服务器堆栈”时,我认为“用户无法在其上专用盒子,而需要在机器之间轻松移动它”,因为没有其他充分的理由这样做。如果您已经在处理VM开销,为什么不只在Linux VM上运行Web服务器堆栈呢?不是conhost.exe那样的 至于Windows ME,我必须尝试在它刚推出时就予以支持,并且您可以引用所有喜欢的晦涩,过时的案例,而不会犹豫我对那只OS早餐的看法,我可能整天都在苦恼没有做到公正。
亚伦·米勒

7

以该DETACHED_PROCESS标志开头的控制台应用程序不会获得控制台或conhost子进程。问题在于该标志不适用于子孙,因此仅适用于直接启动的进程(如果您甚至可以找到允许您指定此标志的实用程序)。

另一个可行的选择是控制台进程调用该FreeConsole()函数。某些服务器应用程序支持-d或-detach参数,但这在* nix系统上可能更常见。


1
听起来很棒。这些页面均未提及conhost,但连接似乎相当清楚。我将做一些测试,看看它有什么样的效果。
Synetech 2014年

2

适用于您的快速解决方案。链接应用程序时,将/ SUBSYSTEM:WINDOWS添加到选项。您还可以使用editbin.exe修改现有的可执行文件。

这样可以防止Windows为您的应用程序生成conhost.exe。


这听起来很有希望,但我只是尝试了一下,但没有成功。我用它来更改的子系统mysqld,但是当我运行它时,它仍然产生了一个conhost实例。
Synetech

可能stderr仍然需要mysqld,因此需要conhost吗?
David T. Macknet '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.