# Windows: Where should \`Command::new\` look for executables?

**URL:** <https://internals.rust-lang.org/t/windows-where-should-command-new-look-for-executables/15015>\
**Category:** libs\
**Created:** [July 13, 2021, 5:00pm UTC](https://internals.rust-lang.org/t/windows-where-should-command-new-look-for-executables/15015 "2021-07-13T17:00:29Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![chrisd](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/chrisd/32/7232_2.png) [@chrisd](https://internals.rust-lang.org/u/chrisd)\
**Post date:** [July 13, 2021, 5:00pm UTC](https://internals.rust-lang.org/t/windows-where-should-command-new-look-for-executables/15015/1 "2021-07-13T17:00:29Z")

</div>

On Windows, what strategy should `Command::new` use to find executables? Possible search locations include:

- The exe's directory. Traditionally the executable's directory is a kind of application bundle. Binaries are in the root and resources are in subfolders (this also affects default dll loading if not using an rpath equivalent). On the other hand, if that's the wanted behaviour of `Command` then it's likely that the developer won't want to be running some random other application if, for some reason, it's not where it's supposed to be. And it's easy enough to use `std::env::current_exe` to get the exe's directory in that case.
- Path environment variable.
- "App Paths". Applications can register their presence in the registry instead of (or in addition to) using `Path`. E.g. `HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths`
- System folders (i.e. `C:\Windows\System32` and `C:\Windows`). These should already be in `Path` but if they're not then should they still be searched? Do people generally assume (as now) that `cmd` et al will always be found?

Should Rust try to search all these locations? Some? Or should it just stick to the `Path` environment variable?

Ideally this would be configurable in some way but even then it's desirable to have sensible defaults. Also assume for the sake of this thread that some implementation details of `Command::new` can be changed (or else it's replaced with a different method). This follows on from [here](https://internals.rust-lang.org/t/std-command-resolve-to-avoid-security-issues-on-windows/14800) in which it was pointed out that there can be security implications with the current behaviour of `Command::new`.

---

<div class="post-metadata">

**Author:** ![CAD97](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cad97/32/3460_2.png) [@CAD97](https://internals.rust-lang.org/u/CAD97)\
**Post date:** [July 13, 2021, 5:41pm UTC](https://internals.rust-lang.org/t/windows-where-should-command-new-look-for-executables/15015/2 "2021-07-13T17:41:43Z")

</div>

Whatever the searched path(s), it should match the lookup behavior of one of

- typing the exe path/name into the Run dialogue
- typing the exe path/name into cmd
- typing the exe path/name into Powershell
- calling [Win32/`CreateProcess`](https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa)
- calling [C#/`Process.Start`](https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.process.start)

Or some other system that's default on Windows.

It doesn't matter which, really, just that it matches something. IIRC, all of these are subtly different ☹

---

<div class="post-metadata">

**Author:** ![chrisd](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/chrisd/32/7232_2.png) [@chrisd](https://internals.rust-lang.org/u/chrisd)\
**Post date:** [July 13, 2021, 6:56pm UTC](https://internals.rust-lang.org/t/windows-where-should-command-new-look-for-executables/15015/3 "2021-07-13T18:56:03Z")

</div>

See, I think the fact these all have subtle differences is potentially an argument for not necessarily being too strict about following any one so long as the rules are simple enough to understand. All except `CreateProcess` and `cmd` can potentially change in the future (and even those may depend on particular settings or configurations). But any way, to the best of my knowledge this is the search behaviour:

- [`CreateProcess`](https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw#parameters):
  - The `exe`'s directory.
  - The current directory\*
  - Windows system directories
  - `Path` environment variable
  - It only runs `.exe` files

- [`ShellExecute`](https://docs.microsoft.com/en-us/windows/win32/shell/app-registration#finding-an-application-executable):
  - The current directory\*
  - Windows system directories
  - `Path` environment variable
  - `App Paths` registry
  - It can "run" non-`.exe` files based on their registered "verbs", if any.

- Run dialogue:
  - I can't find documentation but it's presumably using `ShellExecute`. Except I'd assume the current directory isn't relevant.

- Powershell:
  - `Path` environment variable
  - It can run non-".exe" files in a similar way to `ShellExecute` but limited to the extensions listed in the `PATHEXT` environment variable.

- [cmd](https://docs.microsoft.com/en-us/previous-versions//cc723564(v=technet.10)#command-search-sequence):
  - Internal command
  - The current directory\*
  - `Path` environment variable
  - It can run non-".exe" files in a similar way to `ShellExecute` but limited to the extensions listed in the `PATHEXT` environment variable.

- `Process.Start`:
  - It seems to be a wrapper around `CreateProcess` and `ShellExecute` depending on how exactly it's used. I'm not sure if it does anything on top of that.

\* NOTE: Using the current directory is what the CVE takes issue with.

I've linked my sources above. Those without links I've provided my best guess based on my current understanding. I would need to investigate further though.

---

<div class="post-metadata">

**Author:** ![bjorn3](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bjorn3/32/2736_2.png) [@bjorn3](https://internals.rust-lang.org/u/bjorn3)\
**Post date:** [July 13, 2021, 9:11pm UTC](https://internals.rust-lang.org/t/windows-where-should-command-new-look-for-executables/15015/4 "2021-07-13T21:11:25Z")

</div>

The cmd/powershell way would be best IMHO as it most closely matches the behavior on most other OSes where only `PATH` is considered.

---

<div class="post-metadata">

**Author:** ![chrisd](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/chrisd/32/7232_2.png) [@chrisd](https://internals.rust-lang.org/u/chrisd)\
**Post date:** [July 14, 2021, 4:03am UTC](https://internals.rust-lang.org/t/windows-where-should-command-new-look-for-executables/15015/5 "2021-07-14T04:03:21Z")

</div>

I'm generally nervous of the argument that Windows implementations should match posix/Linux conventions (if only because this can lead to headaches and buggy workarounds for incompatible behaviours).

But in this specific case it would be the easiest to both implement and explain. And it's justifiable based on Powershell.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [October 12, 2021, 4:03am UTC](https://internals.rust-lang.org/t/windows-where-should-command-new-look-for-executables/15015/6 "2021-10-12T04:03:48Z")

</div>

Closed on October 12, 2021, 4:03am UTC

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
