Hello @Kohei Tagami ,
Thank you for the detailed report and the clear repro data. I looked into this and was able to reproduce the same behavior locally, so let me share what I found along with the relevant documentation.
To give you the short answer first, there is no documentation that guarantees the command line returned by information class 60 (ProcessCommandLineInformation) is immutable for a given process, and the 0xffffffff -ForceV1 to 0x4 change you observed appears to be normal, expected initialization behavior for conhost.exe rather than a defect.
I want to explain why there is no immutability guarantee. Information class 60 (ProcessCommandLineInformation) is not listed in the official NtQueryInformationProcess reference at all. The documented classes stop at values like ProcessSubsystemInformation (75), but class 60 is not among them, so it is effectively undocumented. You can see this in NtQueryInformationProcess function (winternl.h). That same page also states in its Remarks that "The NtQueryInformationProcess function and the structures that it returns are internal to the operating system and subject to change from one release of Windows to another", and the banner notes the function "may be altered or unavailable in future versions of Windows." So even for the documented classes no stability contract is offered, and class 60 has no contract at all.
Let me also describe what the transition actually reflects. The command line reported by class 60 is read from the target process's user mode RTL_USER_PROCESS_PARAMETERS.CommandLine, which lives in the PEB. Both of these structures are documented as internal and writable, and are explicitly marked "may be altered in future versions of Windows", as you can see in PEB (winternl.h) and RTL_USER_PROCESS_PARAMETERS (winternl.h). The conhost.exe process is launched with a placeholder command line (0xffffffff -ForceV1) and, during its own early initialization, the real console handle value (0x4) is written into that PEB field and the -ForceV1 token is dropped. So to answer your sub question, it is closest to option (a): the command line data in the process is genuinely being updated in place during init, and class 60 reflects that live value. It is not a case of the query returning stale or inconsistent data, and both reads returning NTSTATUS 0 is consistent with that.
I was able to reproduce this on my side as well. On Windows 11 (build 26200.9168), by opening a newly created conhost.exe once (a single handle that I never reopened) and burst polling class 60, I captured the exact transition you described:
[t+ 11 us] NTSTATUS=0 [\??\C:\Windows\system32\conhost.exe 0xffffffff -ForceV1]
[t+23648 us] NTSTATUS=0 [\??\C:\Windows\system32\conhost.exe 0x4]
The transition window is very narrow (a few milliseconds during conhost startup), which matches why it is only occasionally observed.
Based on this, my recommendation is that for a read only monitor you do not treat the class 60 command line as stable during a process's early lifetime, especially for conhost.exe. If you need a value you can rely on, it is safer to sample it after the target has finished initializing, and to treat any value read during the very first milliseconds as potentially transient. Since class 60 is undocumented, its exact behavior can also change between Windows releases.
Please let me know if a documented, supported alternative for your specific scenario would help, and I can look into options. If you found my response helpful or informative, I would greatly appreciate it if you could follow this guide for your confirmation.
Thank you.