I use VSCode Anytime I install a python library, I get this notification:
WARNING: The scripts auto-py-to-exe.exe and autopytoexe.exe are installed in 'C:\Users\PC\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\Scripts' which is not on PATH
But I've added that to path. If I run:
echo $env:PATH
I get
C:\Users\PC\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\Scripts:C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Users\PC\AppData\Local\Microsoft\WindowsApps;C:\Users\PC\AppData\Local\Programs\Microsoft VS Code\bin;C:\texlive\2023\bin\windows
suggesting that I've added said path.
I'm confused because I can't run packages from the CLI directly, even though importing them works.
I added the path manually and I've tried removing it but that doesn't work. Any ideas on what to do?
Your own solution is effective in principle -
;is the required separator on Windows - except that your statement isn't valid PowerShell code, and that\chars. don't need escaping as\\in PowerShell; also, you can express the new directory path more generically using theLOCALAPPDATAenvironment variable; therefore:The above modifies
$env:PATHonly for the current session (process).To also persist this change on Windows - so that future sessions see it too:
Interactively, run
sysmd.cpl, select theAdvancedtab, and click onEnvironment Variables..., then add the value of$newDirto the desired scope; since your directory path is user-specific, add it to theUser variables for <username>list.Programmatically, this is surprisingly difficult to do robustly:
If you don't mind converting the original
REG_EXPAND_SZdefinition to a staticREG_SZone, you can use[Environment]::SetEnvironmentVariable()(to target the machine-level definition of the variable, change'User'to'Machine', but not that doing so requires elevation (running as administrator):While this typically has no ill effects, it can; see this answer for background information and a robust alternative; this answer wraps the robust alternative in a helper function,
Add-Path, and explains whysetx.exeshould be avoided forPATHupdates.A simpler programmatic alternative, which also works on Unix-like platforms, is to add the above statements to your
$PROFILEfile, but note that only PowerShell sessions and programs launched from them will then see the updatedPATH, and that profile-loading can be suppressed by launching a PowerShell session via the-NoProfileCLI parameter (the PowerShell CLI (powershell.exe -NoProfilefor Windows PowerShell,pwsh -NoProfilefor PowerShell (Core) 7+)Note that .NET cannot offer APIs for persistent environment-variable definitions on Unix-like platforms, because there's no unified mechanism across all of them.
Cross-platform background information on the
PATHenvironment variable:The platform-specific separator used in the list of directory paths stored in the special
PATHenvironment variable is:;on Windows:on Unix-like platformsIn cross-platform scripting, make changes to
PATHas follows in PowerShell:Use
$env:PATH- all uppercase - because environment-variable access is case-sensitive on Unix-like platforms, and the special variable's name is indeedPATHthere.Path, but because environment-variable access is case-insensitive, any case variation and therefore alsoPATHworks.Use the - confusingly named -
[System.IO.Path]::PathSeparatorproperty to get the platform-native separator.In forming directory paths to add, use the platform-native file-system path separator, which .NET reflects in the - equally unfortunately named -
[System.IO.Path]::DirectorySeparatorCharproperty.PowerShell's
Join-Pathcmdlet and .NET's[System.IO.Path]::Combine()method, when given components of a path, implicitly use the platform-native separator, which is\on Windows, and/on Unix-like platforms.\has no special meaning in PowerShell (and neither incmd.exe) so there is no need to represent literal\characters as\\(however, in the context of file-system paths, such accidentally duplicated separators are generally still accepted).On Windows, you could alternatively use
/as well, which is safe to use in the context ofPATHas well as PowerShell-native commands..NET reflects this fact via the
[System.IO.Path]::AltDirectorySeparatorCharpropertyHowever, programs / scripts examining
$env:PATHfor existing entries are likely to assume\, so it's best to use the platform-native separator.Also, generally speaking, there are still Windows contexts where
/doesn't work, such as incmd.exeand COM APIs.Generally, aim to express your directory paths in terms of environment / well-known directories, to be resolved to literals paths at the time of adding entries:
E.g., the
C:\Users\PC\AppData\Localpart of your path could be replaced with environment variable$env:LOCALAPPDATAHowever, for cross-platform use it's best to use platform-agnostic abstractions, as provided - within limits - by
[System.Environment]::GetFolderPath()E.g., the platform-agnostic equivalent of the above is:
Since use of
[System.Environment]::GetFolderPath()isn't very PowerShell-friendly, GitHub issue #6966 asks for surfacing known folders platform-agnostically via a separate namespace / provider, e.g.$sf:LocalApplicationData(sfstanding for special folder).