-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Environment.ProcessPath hangs with exe path > MAX_PATH #110800
Comments
Tagging subscribers to this area: @dotnet/area-system-runtime |
Quoting documentation:
Thus, it is correct to test for |
I agree, a fix would be to call |
Yes, it is what we do in other places runtime/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessManager.Win32.cs Lines 182 to 184 in cdfafde
I do not think it is necessary. |
Description
Running an exe that is located in a path that exceeds the MAX_PATH (260 chars) will hang if it calls
Environment.ProcessPath
. CurrentlyEnvironment.ProcessPath
on Windows callsGetProcessPath
runtime/src/libraries/System.Private.CoreLib/src/System/Environment.Windows.cs
Lines 127 to 142 in e654570
The current logic is
ValueStringBuilder
to a capacity of 260The issue is that
GetModuleFileNameW
does not return the required capacity if the provided buffer size is too small but rather the return value is the length of the string that is copied to the buffer. If the exe is located in a path that exceeds 260 the first call will be with a buffer of 260 and the return value of 260. As260 >= 260
thebuilder.EnsureCapacity(260)
call is a no-op because the capacity is already that size. As the capacity is never increased the loop will continue to run indefinitely.A quick example in a PowerShell script showing this behaviour when the provided capacity is less than what is required. This example runs in an exe that does not exceed MAX_PATH but it illustrates how
GetModuleFileNameW
acts when the provided size is not enough to copy the full file name.The logic will have to change to see if the return value is equal to the provided size and increase the value string builder by x amount until the return value is less than the provided size.
Reproduction Steps
Use the following C# project that will copy itself to a path that exceeds MAX_PATH and start the process. It uses
CreateProcess
here internally because .NET cannot start an exe for something that exceeds MAX_PATH.This uses the following csproj
Expected behavior
Exe path is returned. I'm unsure whether it should have the
\\?\
prefix or not.Actual behavior
Process hangs indefinitely. With the reproducer above, it will be killed after 5 seconds.
Regression?
No
Known Workarounds
You can use
Process.GetCurrentProcess().MainModule.FileName
or PInvoke the call toGetModuleFileNameW
with the correct logic.Configuration
.NET 9
Windows 2025 but same behaviour occurs on older WIndows versions
Tested on ARM64 but same behaviour occurs on x64 and probably x86
The only thing specific to this configuration is that it runs on Windows. I think Windows XP had a slightly different return value behaviour of
GetModuleFileNameW
but that has long been unsupported.Other information
No response
The text was updated successfully, but these errors were encountered: