(Когда) действительно необходим CONHOST.EXE?

Фон

В прошлом году я собрал портативную систему для блогов и веб-серверов, которую можно запускать с флешки. Это здорово и прекрасно работает, особенно на XP. Проблема в том, что при запуске в Windows 7 каждая консольная программа порождает два процесса, сам процесс плюс копию conhost.exe,

проблема

В случае портативной системы блогов, каждый из ее серверных компонентов (MySQL's mysqld.exe, Два случая Apache httpd.exe VisualSVN два экземпляра visualsvnserver.exe и несколько экземпляров PHP php-cgi.exe) порождает случай conhost.exe, На данный момент (без копий php-cgi.exe активный, у меня есть пять экземпляров conhost.exe работает, используя почти без циклов ЦП, но потребляя 22 МБ памяти (в дополнение к 80 МБ, которые в настоящее время используют реальные процессы).

Исследование

Поскольку Windows 7 была выпущена (и я думаю, что возможно начиная с Vista), я несколько раз пытался выяснить, для какой цели используются различные (новые) процессы хоста (например, conhost.exe, dllhost.exe, а также taskhost.exe) делать и нужны ли они на самом деле. Я попытался убить их и обнаружил, что консольные программы продолжают работать, как для программ, которые используют окно консоли, так и для тех, которые не (например, серверы).

Я уже знаком со всем csrss.exe ⇨ Windows Vista ⇨ conhost.exe и видел это же (почти дословно) объяснение много раз. Проблема в том, что все просто копируют и вставляют то же самое объяснение, которое не помогает. Все это говорит о том, что в XP- консольных приложениях, где "размещаются" или "работают под" csrss.exe, но в Windows 7 они были перенесены в conhost.exe для обеспечения безопасности. Аспект безопасности имеет смысл, но он ничего не говорит о том, что означает его размещение или почему / когда это необходимо (или возможно ли избежать этого, если в этом нет необходимости). Даже в дискуссии Раймонда Чена по этому вопросу скрывается, почему консольные приложения вообще размещаются по-разному.

Наиболее подробное техническое объяснение, которое я могу найти, - это сообщение в блоге Microsoft, которое, кажется, подтверждает идею о том, что речь идет только о графическом интерфейсе и окне консольного приложения. Это заставляет меня задуматься еще сильнее, conhost.exe необходимо для таких программ без окон, как эти серверы. Если окна вообще нет, то зачем мне тратить ресурсы и загромождать пространство процессов ненужными процессами? Почему Windows не может определить, когда это не нужно, и избежать этого? Ответ SecurityMatt был также немного полезен в отношении технического объяснения, но, опять же, недостаточно информации, которую я ищу.

Я не единственный, кто пытался найти способ остановить ненужные случаи conhost, Этот человек спросил о его отключении, и ему просто сказали "это невозможно" без каких-либо дополнительных усилий или мыслей об этом. Хью Д. и "Вряд ли особенность" указали на проблему с многочисленными, избыточными случаями conhost (по крайней мере, с csrss была запущена только одна копия), включая использование ресурсов и длительные экземпляры после завершения их дочерних процессов. Я Лауфер усомнился, / когда это даже необходимо.

Наблюдения и попытки решения

Если они на самом деле не нужны во все времена (опять же, я не видел никаких побочных эффектов от их убийства), то я полагаю, что мог бы (очень раздражающе) обойти проблему, заменив серверы пакетными файлами, которые запускают серверы подожди, а потом убей копию conhost что они заставляют бежать. Конечно, это требует быстрого и простого способа определить, какой это. FallenGameR спросил, как получить экземпляр conhost.exe связан с консольной программой с заданным PID, но не получил ответа. Я бы подумал, что простое получение PID родительского процесса должно помочь (нет, ProcessExplorer не является опцией, требуется автоматическое / скриптовое решение), но не только для того, чтобы создать некую платформу для получения PID дочерний процесс (вместо того, чтобы просто запустить его и выполнить задачу), но это также означало бы найти способ сделать его совместимым с XP (например, проверить имя-изображения родительского процесса). Это сообщение в блоге дает один способ, но требует PowerShell и вряд ли идеально, не говоря уже о том, что ничего не говорит о последствиях запуска сценария.

Вопросы)

Возможно, Microsoft считает, что никто больше не использует командные строки (* кашель *Windows 8* кашель *), и поэтому предположил, что не стоит их обременять, но есть определенно сценарии, когда несколько консольных приложений работают и имеют каждое из них. порождать дополнительный, требующий памяти процесс, использующий PID, ужасно, и пытаться обойти его, в лучшем случае, ужасно неудобно.

У кого-нибудь есть точная, авторитетная информация по этому вопросу? Опять же, я уже прочитал общее объяснение; Мне интересно:

  1. Почему консольные приложения должны (все еще) обрабатываться по-другому вообще
  2. При каких конкретных обстоятельствах они должны иметь conhost
  3. Каковы последствия убийства conhost
  4. Есть ли какой-нибудь способ остановить / предотвратить / отключить / заблокировать его или хотя бы простой способ быстро справиться с ним назад?

3 ответа

  1. Консольные приложения должны обрабатываться по-разному, поскольку под ядром NT (которое лежит в основе всех 2000, XP, Vista, Windows 7 и Windows 8) они являются гражданами второго сорта. В архитектуре системы Unix каждый процесс во время создания имеет стандартные потоки ввода, вывода и ошибок, связанные с ним; Терминальный ввод-вывод реализован в терминах этих потоков (stdin, поступающий с клавиатуры, и stdout/stderr, идущий к терминалу), и требуются дополнительные усилия со стороны процесса, который не желает использовать эти потоки или имеет их файловые дескрипторы открыты.

    В архитектуре Windows NT, которая, хотя и не является прямым потомком VMS, была разработана более или менее одной и той же командой, верно и обратное; вновь порожденный процесс по умолчанию не имеет подключенных к нему потоков ввода-вывода, и такого понятия, как "терминал", не существует. Программы, которые хотят вести себя немного более Unixy-способом, могут запросить (путем объявления времени компиляции), что система создаст для них окно консоли и подключенные к нему потоки ввода / вывода; система сделает это, но поскольку Windows, в отличие от Unix, не предоставляет вам терминалы бесплатно, для их создания требуется значительное количество дополнительных усилий, поэтому раньше csrss.exe, и сейчас conhost.exe,

    Что касается разницы между ними, ваша ссылка "Вряд ли особенность" объясняет это вполне адекватно; короче говоря, он существует для обхода уязвимости безопасности в предыдущей итерации весьма секретного консольного API-интерфейса Windows, который допускал повышение привилегий в версиях NT, более старых, чем Windows 7. (Vista, к сведению, не имеет conhost.exe, что соответствует статусу Windows Millennium семейства NT.)

  2. Любая программа, которая хочет эквивалент Unix stdin/stdout/stderr, нуждается в консоли, следовательно, экземпляр conhost.exe, Иммигранты из Unix-land, такие как Apache, PHP и др., Захотят получить эти потоки, следовательно, автоматическое создание экземпляров системы conhost.exe для них, действительно ли они отображают окно или нет. Теоретически, было бы возможно изменить исходный код, например, для Apache, так, чтобы он не требовал терминала, и скомпилировать его как приложение с графическим интерфейсом Windows вместо консольного приложения, чтобы система не чувствовала необходимости порождать его. conhost.exe, Предполагая, что это также возможно на практике, похоже, никто не заботился об этом. Возможно, вы будете первым.

  3. Убить данное conhost.exe почти наверняка отключит консольный ввод-вывод для любого процесса, запущенного под этим экземпляром. Вы, вероятно, не заботитесь об этом, потому что имеете дело с серверными процессами, которые в любом случае не делают ничего интересного в потоках ввода-вывода консоли, поэтому, вероятно, нет причин не убивать их conhost.exes. Если есть сомнения, убейте их и посмотрите, не сломается ли что-нибудь.

  4. Нет способа предотвратить создание экземпляров Windows conhost.exe когда запускается программа, которая запрашивает консольный ввод-вывод; единственный способ сделать это - перекомпилировать его, чтобы Windows не считала его консольным приложением. Тем не менее, предполагая, что уничтожение родительского процесса данного сервера conhost.exe не влияет на его функциональность любым способом, который вас волнует, вы должны иметь возможность убить их всех сразу, выполнив taskkill /f /im conhost.exe в командной строке или в окне консоли - желательно первое, поскольку последнее, вероятно, умрет и почти наверняка перестанет работать, как только его родитель conhost.exe Экземпляр убит. Опять же, если сомневаетесь, убейте их и посмотрите, не сломается ли что-нибудь.

Консольное приложение запущено с DETACHED_PROCESS Флаг не получает ни консоль, ни дочерний процесс conhost. Проблема в том, что флаг не применяется к внукам, поэтому он будет работать только с процессами, которые вы запускаете напрямую (если вы даже можете найти утилиту, которая позволяет вам указать этот флаг).

Другой вариант, который может работать, если консольный процесс вызывает FreeConsole() функция. Некоторые серверные приложения поддерживают параметр -d или -detach, но это, вероятно, более распространено в системах *nix...

Быстрое решение, которое может работать на вас. При связывании вашего приложения добавьте /SUBSYSTEM:WINDOWS к параметрам. Вы также можете использовать editbin.exe для изменения существующего исполняемого файла.

Это предотвращает появление Windows conhost.exe для вашего приложения.

Другие вопросы по тегам