-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Use reparse points to detect Windows installer shims #2284
Conversation
0253ada
to
4bb4b39
Compare
let mut path_encoded = path | ||
.as_os_str() | ||
.encode_wide() | ||
.chain(std::iter::once(0)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previously, this wouldn't work for one of the two shims. But adding the null terminator seems to fix it on my machine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding the null termination seems correct. OsStr is not null terminated https://doc.rust-lang.org/std/ffi/struct.OsString.html
fc4efc5
to
60937ee
Compare
b0dabce
to
c8e9a79
Compare
c8e9a79
to
9581d67
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for fixing this. I should have tested this workflow when improving windows support. And nice find with the null terminator
Have you considered upstreaming this back to Rye.
But what about https://twitter.com/charliermarsh/status/1765750403461689701
std::ptr::null_mut(), | ||
0, | ||
buf.as_mut_ptr().cast(), | ||
buf.len() as u32 * 2, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: not a 100 sure but I think we could use mem::size_of here (or size_of_value) to avoid the * 2
CloseHandle(reparse_handle); | ||
} | ||
|
||
success && String::from_utf16_lossy(&buf).contains("\\AppInstallerPythonRedirector.exe") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this buf be sliced to bytes returned? It might not matter because it only tests startswidth but might still be good practice
if !path.is_absolute() { | ||
return false; | ||
} | ||
|
||
// The path must point to something like: | ||
// `C:\Users\crmar\AppData\Local\Microsoft\WindowsApps\python3.exe` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we reuse the uv-fs function instead of reimplementing the check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They're actually different checks (sigh). The one in uv-fs
needs to accept python3.12.exe
and friends. The one here only accepts python3.exe
and python.exe
, since those are the only ones that get added as app redirects.
return false; | ||
} | ||
// Ex) `WindowsApps` | ||
if !components |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be simplified to using components.ends_with("Microsoft/WindowsApps") after having done the fuzzy python.exe check
@@ -130,7 +130,7 @@ fn find_python( | |||
for name in possible_names.iter().flatten() { | |||
if let Ok(paths) = which::which_in_global(&**name, Some(&path)) { | |||
for path in paths { | |||
if cfg!(windows) && windows::is_windows_store_shim(&path) { | |||
if windows::is_windows_store_shim(&path) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know how to make code suggestions on ipad…
I would add #[cfg(windows)] to the if block instead of having an empty non-windows implementation in the windows module
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sigh, I originally did this but the cross-platform Clippy warnings were so brutal.
This does NOT apply to Windows Store Python. |
Summary
This PR enables use of the Windows Store Pythons even with
py
is not installed. Specifically, we need to ensure that thepython.exe
andpython3.exe
executables installed into theC:\Users\crmar\AppData\Local\Microsoft\WindowsApp
directory are used when they're not "App execution aliases" (which merely open the Windows Store, to help you install Python).When
py
is installed, this isn't strictly necessary, since the "resolved" executables are discovered viapy
. These look likeC:\Users\crmar\AppData\Local\Microsoft\WindowsApps\PythonSoftwareFoundation.Python.3.11_qbs5n2kfra8p0\python.exe
.Closes #2264.
Test Plan
py
.cargo run venv --python python.exe
andcargo run venv --python python3.exe
,uv
exited with a failure that no Python could be found.cargo run venv --python python3.10.exe
also succeeded.