Windows 环境变量那些事
环境变量的查找顺序
在 Windows 上可以在命令提示符或 PowerShell 中输入 python
启动 Python 的 REPL。Windows 是如何找到 python
这个命令的呢,当然是通过 %Path%
的环境变量,因此对每个文件夹进行查找,找到最先出现的 python
可执行文件。
使用 WHERE
命令可以对环境变量中和当前目录中的可执行文件进行查找。
例如:
C:\Users\Foair>WHERE python
C:\Program Files\Python37\python.exe
所以当 Windows 查找一个可执行文件是按照环境变量中目录,和当前路径进行查找的。只要找到一个就不会继续查找了。
还有一点需要说明的就是可执行文件,在 Windows 中可执行文件不只是 .exe
,Windows 默认的至少就有 .bat
.cmd
.js
.msc
.com
等文件,并不局限于 .exe
文件。
可执行文件名的扩展名可以使用 ECHO %PATHEXT%
查看。
C:\Users\Foair\Desktop>ECHO %PATHEXT%
.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.PY;.PYW
当输入一个命令的时候,比如 touch
就会去查找这些扩展名的文件,touch
可能对应 touch.exe
,但也可能对应 touch.py
,取决于优先级和文件存在与否。在上面的 %PATHEXT%
的环境变量中,.exe
的优先级是高于 .py
文件的,因此当两个文件都存在的时候,调用 .exe
文件的优先级是高于 .py
文件的。
同理,%Path%
环境变量也是具有优先级的,越早出现,优先级越高。当然,当搜索一个可执行文件的时候,当前目录的优先级高于%Path%
,因此当前文件夹的可执行文件总是先调用。另外 %Path%
的搜索优先级高于 “%PATHEXT%`。
假设 D:\alias
已经放到 %Path%
环境变量下,并在 D:\alias
创建一个 xxx.cmd
。另一个在 %USERPROFILE%\Desktop
下创建 xxx.bat
和 xxx.cmd
。(xxx
命令需要没有被占用,且 .bat
优先级高于 .cmd
。)
当在 %USERPROFILE%\Desktop
下调用 xxx
的时候,应该是调用 %USERPROFILE%\Desktop\xxx.bat
。
在 C:\
下调用 xxx
命令,应该是调用 D:\alias\xxx.cmd
。
假如 %USERPROFILE%\Desktop
也加在了 %Path%
的最后,在 D:\
调用的也是 D:\alias\xxx.cmd
。
其他环境变量可以使用 SET
命令进行查看。
参考
这事要从 node node.js 说起 - 前端 - 掘金
“Register” an .exe so you can run it from any command line in Windows - Stack Overflow
添加 JavaScript 文件默认为 Node 执行
在 Python 的安装程序中提供了 Python Launcher,用于将 .py
文件关联为可执行文件,简化调用过程。
而 Node.js 不提供这样的功能,.js
也被 Windows 的 WSH 占用,而 WSH 现在基本上也不会用到(得出这个结论是找了很多资料的,因为 jsc
这样的编译器都被藏得很深)。因此可以放心大胆地将 .js
文件关联到 Node。
ASSOC .js=NodeJS
FTYPE NodeJS=node %1 %*
%1
代表当前打开的文件,比如 index.js
,也可以使用 %L
代替(Python Launcher 写的是 %L
),根据零星的资料,这个应该表示的是完整的长路径,而 %1
是短路径。使用上,应该没有太大的差别。
还原到默认的设置,执行以下命令:
ASSOC .js=JSFile
备注
以下命令和 WSH 有关。.vbs
和 .js
都和这两个有关。JScript 可以调用 .Net。
CScript /?
WScript /?
参考
Run .js files using node.exe on Windows 7
如何规划环境变量的设置
对于大型的应用程序,比如 TeX Live,可以将所有 .exe
文件所在的 bin
目录添加到环境变量。而经常使用的单个程序,比如 aria2,可以将 aria2c.exe
生成可执行的 .bat
或 .cmd
文件添加到一个目录,这个目录专门用来存放这些「快捷方式」。
我将这个目录在 D:\alias
,将所有可执行的 .bat
放在这个地方。并将这个目录放到环境变量中,那样就不会有其他的程序来「污染」当前的环境变量。
其实这个做法的来源是 Node.js,当全局安装一个 Node 模块的命令行程序的时候,就会创建一个同名的 .cmd
文件,当在命令行调用这个程序的时候,就会查找到这个可执行的 .cmd
,js
程序得以执行。
当 npm i @vue/cli -g
后,会在一个目录中创建 vue.cmd
,内容可能如下:
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\node_modules\@vue\cli\bin\vue.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\node_modules\@vue\cli\bin\vue.js" %*
)
@
的意思是不显示当前命令的输出,%*
是传入是所有参数。
当 vue.cmd
所在的目录存在 node.exe
时会使用该 node
引擎解析 JavaScript,并将一些参数传递给 node
。如果不存在,那么就会在局部设置一个新的环境变量(只影响当前批处理,不会扩散),并且将 .js
的可执行去除,使用全局的 node
进行 JavaScript 的解析。
因此我要创建一个 aria2c.exe
的快捷方式到到 D:\alias
下,这样就不会造成其他负面影响。
aria2.bat
的内容如下:
@G:\aria2\aria2c.exe %*
这样就很灵活了。
同理,如果我想将 Course Cralwer 映射为 moocal
,可以创建 moocal.bat
到 D:\alias
,写下如下内容:
@G:\course-crawler\mooc.py %*
备注
%cd%
可以用在批处理和当前命令行中,而 %~dp0
只能用在批处理中。且 %cd%
是当前目录,而 %~dp0
是批处理所在目录。%
使用 %%
进行转义。
%~dp0
是对第 0 个参数,一般是可执行文件进行扩展,~
表示扩展,d
表示驱动器,p
代表路径。
一些详细的说明可以在命令提示符下面键入 CALL /?
or FOR /?
来查看。
参考
Windows 脚本中 %~dp0 的含义 - huaius - ChinaUnix 博客
Microsoft Windows XP - Using batch parameters
后记
还可以将程序路径添加到 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths
中,不过这样只能使用 START
命令或「运行」来启动,是不可以直接键入程序名的。
START
命令的用法:https://ss64.com/nt/start.html
一般来说 cmd 的用法很诡异,在未来应该是要被 PowerShell 完全取代的。但现在 PowerShell 的打开很慢,所以批处理还是有其存在的意义。
附一个设置工具,用来生成 xxx.cmd
。
Aliases for Windows command line
Rapid Environment Editor(环境变量设置工具,用处不大)
启动一个程序(也可以打开一个文件)
@ECHO OFF
start "" "C:\Program Files (x86)\Software\software.exe" %*
或者
@ECHO OFF
"C:\Program Files (x86)\Software\software.exe" %*
完整的操作步骤
MKDIR D:\aliases
SETX PATH "D:\aliases;%PATH%"
创建一个新窗口的 CMD
@ECHO OFF
START "myprogram" /D "C:\path to\" /W "myprogram.exe" %*
在当前窗口的 CMD(切换到另一个目录,然后切换回来)
@ECHO OFF
PUSHD "E:\path\"
"shortcut.exe" %*
POPD
保留当前的工作目录(如果可执行文件需要依赖,就会在当前目录查找不到依赖)
CD /D D:\aliases\
MKLINK "shortcut.exe" "E:\origin.exe"