What does std::process::Command spawn() use under the hood on Windows?

Hi,

I was trying to dig through the source of std::process::Command but still couldn't quite understand whether it uses CreateProcess or ShellExecute/ShellExecuteEx.

Could someone point me to the right place, please?

Thanks!

Looks like CreateProcessW https://github.com/rust-lang/rust/blob/dd430bc8c22f57992ec1457a87437d14283fdd65/library/std/src/sys/windows/process.rs#L360-L372

unsafe {
    cvt(c::CreateProcessW(
        program.as_ptr(),
        cmd_str.as_mut_ptr(),
        ptr::null_mut(),
        ptr::null_mut(),
        c::TRUE,
        flags,
        envp,
        dirp,
        si_ptr,
        &mut pi,
    ))
}?;
1 Like

I know you got your answer, but for future reference, you can find that stuff yourself. I recommend the rg command.

Go into the rust source directory and search for CreateProcess or ShellExecuteEx.

source/rust$ rg 'CreateProcess|ShellExecuteEX' ./
./library/std/src/sys/windows/process.rs
360:            cvt(c::CreateProcessW(
442:            // Let `CreateProcessW` figure out if it exists or not.
459:        // From the `CreateProcessW` docs:
819:    // Always quote the program name so CreateProcess to avoid ambiguity when

./library/std/src/sys/windows/c/windows_sys.rs
121:    pub fn CreateProcessW(

./library/std/src/sys/windows/c/windows_sys.lst
2507:Windows.Win32.System.Threading.CreateProcessW

./library/std/src/os/windows/process.rs
173:    /// Sets the [process creation flags][1] to be passed to `CreateProcess`.
2 Likes

Reasonably, it can't be anything shell-related. You don't even have to read the source. The documentation explicitly states that there is no shell involved.

By the way, you can infer this just from the fact that Rust tries very hard to prevent you from shooting yourself in the foot. Defaulting to shell invocation would be a huge security hazard (any untrusted user input you pass in will be executed by the shell), as well as a portability concern (even on Windows, there are at least two shells, cmd and PowerShell, not to mention sh, bash, csh, zsh, fish, etc. on Unices). So it would be out of place in a correctness-oriented language.

1 Like

@H2CO3 Thanks, but I think you misapprehend what ShellExecute is about; perhaps based on its name? The name may be misleading in this case, but it's not really comparable to system() on Unix and it doesn't use cmd.exe, pwsh.exe (or powershell.exe) under the hood. The idea is to have a number of "registered" (literally configurable in the registry) verbs - open being sort of a default - and creating a process based on that. And the "shell" part refers to the shell API and Windows Explorer as the entity chiefly responsible for the graphical desktop experience.

Thanks everyone for the helpful answers and a special thanks for the hint regarding rg.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.