Skip to content

Eliminate conhost.exe from git.exe and hooks process launches#1981

Open
ShiningMassXAcc wants to merge 1 commit into
microsoft:masterfrom
ShiningMassXAcc:user/nbaird/62385282-eliminate-conhost
Open

Eliminate conhost.exe from git.exe and hooks process launches#1981
ShiningMassXAcc wants to merge 1 commit into
microsoft:masterfrom
ShiningMassXAcc:user/nbaird/62385282-eliminate-conhost

Conversation

@ShiningMassXAcc
Copy link
Copy Markdown
Member

@ShiningMassXAcc ShiningMassXAcc commented May 21, 2026

Summary

GVFS launches git.exe processes with CreateNoWindow=true (or CREATE_NO_WINDOW in native code). Despite the name, this flag tells Windows to create a new hidden console for each child process, which allocates a conhost.exe instance. For frequent, small git operations (e.g., during prefetch), the per-process conhost creation/teardown overhead is disproportionately large.

Changes

File Change Why
GitProcess.cs:827 CreateNoWindow = true to false Central git.exe wrapper (all prefetch calls route here)
ProcessHelper.cs:21 CreateNoWindow = redirectOutput to false Generic process helper
GitHooksLoader.cpp:132 CREATE_NO_WINDOW to DETACHED_PROCESS Native hooks loader — truly detaches from console

How it works

  • CreateNoWindow = false with UseShellExecute = false: child inherits parent console state. Since GVFS runs as a service with no console, child gets no console and no conhost.
  • DETACHED_PROCESS (native): explicitly detaches from any console without allocating a new one.

Verification

Conhost elimination confirmed

Setting conhost.exe per git.exe
CreateNoWindow=true (old) 1 conhost.exe spawned
CreateNoWindow=false (new) 0 — eliminated

Benchmark (3 runs x 50 git.exe invocations)

Metric Old New Improvement
Total (50 processes) 3905ms 2949ms 956ms saved (24.5%)
Per-process 78.1ms 59.0ms 19.1ms saved

For a prefetch spawning 20-50 git.exe processes, this eliminates ~380-960ms of pure conhost overhead per cycle.

Reference

  • Same pattern as ToolLocationTransformer PR 15071136 (merged)
  • ADO 62385282

Comment thread GVFS/GVFS.Common/ProcessHelper.cs
@ShiningMassXAcc ShiningMassXAcc force-pushed the user/nbaird/62385282-eliminate-conhost branch 2 times, most recently from 4c8b9ee to 2714f45 Compare May 21, 2026 23:22
@ShiningMassXAcc ShiningMassXAcc marked this pull request as ready for review May 21, 2026 23:25
GVFS launches git.exe processes with CreateNoWindow=true (or
CREATE_NO_WINDOW in native code). Despite the name, this flag tells
Windows to create a new hidden console for each child process, which
allocates a conhost.exe instance. For frequent, small git operations
(e.g., during prefetch), the per-process conhost creation/teardown
overhead is disproportionately large.

Changes:

- GitProcess.cs: Set CreateNoWindow=false. With UseShellExecute=false
  and stdout/stderr redirected to pipes, the child inherits the
  parent's console state. Since GVFS.Mount runs as a service with no
  console, the child gets no console and no conhost. Also remove the
  unused redirectStandardError parameter (all callers pass true).

- ProcessHelper.cs: Set CreateNoWindow=false unconditionally. When
  redirectOutput is true, I/O goes through pipes so no console is
  needed. When redirectOutput is false, the child inherits the
  parent's console handles, which is correct for terminal contexts
  and harmless in service contexts (output was already going to an
  invisible hidden console).

- GitHooksLoader.cpp: Use DETACHED_PROCESS instead of
  CREATE_NO_WINDOW in the no-console branch. Explicitly detaches
  from any console without allocating a new one. The console branch
  (user terminal) is unchanged.

Verified with edge-case tests across terminal, hidden-console, and
fully-detached (DETACHED_PROCESS) parent contexts. All git status,
git fetch (prefetch hook), and gvfs health scenarios pass.

Assisted-by: Tyrie Vella <tyrielv@gmail.com>
Assisted-by: Claude Opus 4.6
Signed-off-by: Tyrie Vella <tyrielv@gmail.com>
@tyrielv tyrielv force-pushed the user/nbaird/62385282-eliminate-conhost branch from 2714f45 to 6c01575 Compare May 22, 2026 20:22
@tyrielv tyrielv enabled auto-merge May 22, 2026 20:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants