Closed
Description
Description
On Windows, std::process::Command
accepts arbitrary file extensions in place of the correct file extension (typically .exe
) for a command when at least one environment variable is specified (e.g. command.env("FOO", "BAR")
). The issue does not reproduce when no environment variables are specified.
Rust Version
> rustc --version
rustc 1.26.0 (a77568041 2018-05-07)
Minimum repro
use std::process::Command;
fn main() {
Command::new("cmd.bannana")
.env("FOO", "BAR")
.args(&["/c", "echo", "hello"])
.status()
.unwrap();
}
Expected Result
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "The system cannot find the file specified." }', libcore\result.rs:945:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.
error: process didn't exit successfully: `target\debug\command-ext-err.exe` (exit code: 101)
Actual Result
hello
Negative Reprodution
The following code snippet does NOT reproduce the issue.
use std::process::Command;
fn main() {
Command::new("cmd.bannana")
.args(&["/c", "echo", "hello"])
.status()
.unwrap();
}
Metadata
Metadata
Assignees
Labels
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
cuviper commentedon May 18, 2018
I believe it's this chunk that does it:
rust/src/libstd/sys/windows/process.rs
Lines 144 to 160 in ba64edb
Specifically that
.with_extension(env::consts::EXE_EXTENSION)
changes the extension. I expect the intent is to add.exe
only when there's no extension, so a barecmd
still findscmd.exe
.(This should really be using
PATHEXT
though, rather than just "exe".)cuviper commentedon May 18, 2018
Nevermind about
PATHEXT
-- that's used bycmd.exe
, butCreateProcess
only adds "exe".ollie27 commentedon May 18, 2018
Duplicate of #37519. That chunk of code is very broken.
AndrewGaspar commentedon May 19, 2018
It does sound perhaps that this can't be fixed because it's a long standing issue and would break backwards compatibility. Please close this if so.
jokeyrhyme commentedon May 20, 2018
@AndrewGaspar it seems a shame to have something in the core standard library that is known broken for all perpetuity
Are there any crates that implement a cross-platform std::process with the desired behaviour on Windows?
I've been using which for some of this functionality, but I still have to pair it with a call to
cmd.exe /c example.com
in order to execute, becausestd;:process::Command
is insufficient on Windows for anything but ".exe" filesretep998 commentedon May 20, 2018
The problem with being unable to run other things isn't the extension but rather that
CreateProcess
just won't work correctly with them. The only thing you can reliablyCreateProcess
are normal PE binaries, regardless of extension (although you do have to explicitly specify the extension if it isn't.exe
).The code in libstd definitely needs to be fixed though. I'll have to run some tests to determine how
CreateProcess
handles appending.exe
though, to ensure behavior is consistent.BasixKOR commentedon Mar 6, 2020
I just found a documentation about how file extensions work in Windows, and it might help since CMD finds the application to open a file with
%PATHEXT%
using this information (I found this on Stack Overflow answer, but it may be wrong.).ChrisDenton commentedon Dec 2, 2021
The issue in the OP has been fixed as a side-effect of #87704. So I think this issue can be closed.
Supporting
%PATHEXT%
could be a new feature request if there's demand for it. As noted above, it's not supported by theCreateProcess
function that Rust currently uses.ChrisDenton commentedon Jul 4, 2022
Closing as resolved.
.bat
and.cmd
files inCommand::new
#123728