A) Windows 命令处理器如何搜索命令?
Windows 命令处理器搜索COMMAND执行哪个
- 不是内部命令
cmd.exe
and
- 仅指定文件名,不带文件扩展名,也不带路径
对于与模式匹配的文件command.*
and本地环境变量中列出了文件扩展名PATHEXT
- 当前目录中的第一个and
- next 在本地环境变量的所有目录中
PATH
.
SORT and FIND and FINDSTR and ROBOCOPY and XCOPY还有更多命令不是内部命令cmd.exe
。它们是随 Windows 安装的控制台应用程序,位于目录中%SystemRoot%\System32
有文件名sort.exe
, find.exe
, findstr.exe
, robocopy.exe
, xcopy.exe
, ...
Windows 上默认提供的此类控制台应用程序称为外部命令以更好地将它们与未随 Windows 操作系统安装的控制台应用程序区分开来。
B) 环境变量PATH是如何定义的?
有以下三种类型PATH
变量:
-
System PATH
它用于所有帐户并存储在 Windows 注册表中的键下:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
-
User PATH
仅用于当前帐户并存储在 Windows 注册表中的键下:
HKEY_CURRENT_USER\Environment
-
Local PATH
这始终是一个copy当地的PATH
启动当前进程的父进程。
Windows 连接system and user PATH
to local PATH
对于用作 Windows 桌面的 Windows 资源管理器实例,桌面屏幕上有快捷方式,Windows 开始菜单和 Windows 任务栏作为用户可见的界面Windows外壳 https://en.wikipedia.org/wiki/Windows_shell用户通常从中启动程序。
在启动新进程时,Windows 会将正在运行的进程的整个当前活动环境变量列表复制到新进程。 Windows内核库函数创建进程 https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw该环境变量列表是否在函数参数上从当前进程的内存复制到新进程的内存lpEnvironment
(指向环境的长指针)是空指针。中的一个CreateProcess
Windows 上始终使用函数来从另一个可执行文件启动一个可执行文件。
父进程不能修改任何子进程的环境变量,子进程也不能修改其父进程的环境变量。
这意味着一旦像这样的过程cmd.exe
启动是为了执行批处理文件,该进程有自己的一组环境变量,只有进程本身可以修改。任何其他进程都不能修改已运行进程的环境变量。
C) 错误消息是什么意思?
错误信息
'...' 不被识别为内部或外部命令,
可运行的程序或批处理文件。
总是意味着
-
a 的文件名
- 控制台应用程序
- 图形用户界面应用程序
- 脚本(批处理文件、PowerShell 脚本、Perl 脚本、VBScript、JScript...)
指定执行很可能没有文件扩展名,也没有可执行文件/脚本文件的(完整)路径and
-
Windows 找不到与该模式匹配的文件FileName.*
具有当前活动环境变量中列出的文件扩展名PATHEXT
在当前目录或当前活动环境变量中的任何其他目录中PATH
.
D) 出现此错误消息的可能原因是什么?
典型原因有:
1. 由于输入错误,指定了要执行的文件的文件名错误。
逐个字符检查命令/可执行文件的名称。
2. 当前目录与包含要执行的文件的目录不同。
Run echo Current directory is: %CD%
在命令行上或将此行添加到命令行上方的批处理文件中,但无法查看当前目录是什么。
3. 根本没有安装要运行的可执行文件或脚本。
验证要运行的可执行文件是否存在。有些安装包只有在之前安装了其他软件包(如 Java、NPM、PHP 等)才能工作。
4. 执行文件的目录不在PATH
at all.
在 Windows 中打开控制面板 the System设置窗口,点击高级系统设置在左侧,单击按钮环境变量并在两个列表中查找Path
以及他们的价值观。默认情况下Path
仅存在于列表中系统变量.
5. 修改系统或用户后,正在运行的进程/应用程序没有重新启动PATH
.
的修改system PATH
or user PATH
用命令setx
or via 控制面板-系统和安全-系统-高级系统设置-环境变量由用户或安装程序创建,但已运行的进程/应用程序(例如打开的命令提示符或 PowerShell 窗口)在之后未关闭/退出并打开/重新启动PATH
修改。这是必要的,如章节中详细描述的F) below.
6. 可执行文件%SystemRoot%\System32
在 64 位 Windows 上找不到。
有目录%SystemRoot%\System32
带有 64 位可执行文件和%SystemRoot%\SysWOW64
在 64 位 Windows 上具有 32 位可执行文件,处理器也支持 x86 指令集。大多数可执行文件都存在于这两个目录中。但有一些可执行文件仅存在于System32
和一些只在SysWOW64
.
The system PATH
默认包含作为第一个文件夹路径%SystemRoot%\System32
。但会在两个 Windows 系统文件夹之一中搜索不带路径或带路径指定的可执行文件%SystemRoot%\System32
取决于执行环境。在 64 位环境中执行的应用程序或脚本实际上是在访问%SystemRoot%\System32
而在 32 位环境中执行的应用程序或脚本会被 Windows 重定向文件系统重定向器 https://learn.microsoft.com/en-us/windows/win32/winprog64/file-system-redirector到目录%SystemRoot%\SysWOW64
.
在 32 位环境中运行的应用程序或脚本想要运行 64 位可执行文件%SystemRoot%\System32
必须使用带有文件路径的可执行文件的完全限定文件名%SystemRoot%\Sysnative
.
Note: %SystemRoot%\Sysnative
既不是目录也不是任何类型的链接。它是仅针对 x86 应用程序而存在的非常特殊的东西。 amd64 应用程序不存在它。条件if exist %SystemRoot%\Sysnative
批处理文件中的内容在两种环境中始终为 false,但是if exist %SystemRoot%\Sysnative\cmd.exe
在 32 位执行环境中为 true,在 64 位环境以及 32 位 Windows 上为 false。该条件可用于批处理脚本中,以查明批处理文件是否由 32 位处理cmd.exe
in %SystemRoot%\SysWOW64
在 64 位 Windows 上,了解这一点可能很重要,具体取决于任务。
另请参阅 Microsoft 文档WOW64 实施细节 https://learn.microsoft.com/en-us/windows/win32/winprog64/wow64-implementation-details and 受 WOW64 影响的注册表项 https://learn.microsoft.com/en-us/windows/win32/winprog64/shared-registry-keys.
7. PATH
包含对尚未定义的环境变量的引用。
可以指定在PATH
使用对另一个环境变量值的引用的文件夹路径,例如SystemRoot
。重要的是,此环境变量也在同一组环境变量中定义,或者在 Windows 首先处理的一组环境变量中定义。
例如如果%JAVA_HOME%\bin
被添加到system PATH
环境变量,还必须定义一个system环境变量JAVA_HOME
以及 Java 程序文件的基本文件夹路径。仅仅定义一个是不够的user环境变量JAVA_HOME
或者定义环境变量JAVA_HOME
后来在local批处理文件的环境。
%JAVA_HOME%\bin
添加到user PATH
如果环境变量被 Windows 扩展为完全限定的文件夹路径JAVA_HOME
定义为system or as user环境变量,但未开启JAVA_HOME
稍后定义localWindows 命令进程的环境。
这样的错误只要打开一个新的就很容易看出命令提示符 https://www.howtogeek.com/235101/10-ways-to-open-the-command-prompt-in-windows-10/修改后的窗口system or user PATH
从 Windows 开始菜单并运行set path
。输出PATH
不应再包含任何%Variable%
环境变量值参考。
8.LOCAL变量PATH
之前在命令行或批处理文件中进行了修改。
Run set path
在命令行上或将此命令添加到命令行上方的批处理文件中,但无法查看环境变量的当前值PATH
and PATHEXT
.
那个原因是负责外部命令的SORT执行包含上述某处的批处理文件时未找到set path=...
.
9. 局部变量PATH
太长。
The local多变的PATH
of cmd.exe
太长。 Windows 命令处理器无法在以下文件夹路径中找到任何可执行文件/脚本local Path
如果字符串值长于8191
人物。
请参见我的第二个答案 https://stackoverflow.com/a/75050498/3074564此处有关长度限制的更多详细信息PATH
.
感谢去阿尔伯特·莫西亚维克 https://stackoverflow.com/users/4926013/告知我程序或脚本无法识别的原因。
E) 如何避免出现此错误消息?
最好是编写一个独立的批处理文件PATH
and PATHEXT
以及目录的顺序PATH
这意味着这里使用命令行:
FOR /f "delims=" %%d in ('dir /s /b /ad ^| %SystemRoot%\System32\sort.exe /r') do rd "%%d"
Any 外部命令其中可执行文件存储在%SystemRoot%\System32
应在批处理文件中指定此路径和文件扩展名.exe
。那么 Windows 命令解释器不需要使用以下命令来搜索文件local PATH
and PATHEXT
并且批处理文件始终有效(只要环境变量SystemRoot
也没有在我从未见过的批处理文件中进行修改)。
F) 系统或用户路径更改何时应用于进程?
当用户通过 Windows 开始菜单或 Windows 资源管理器窗口打开命令提示符窗口时,用户将启动cmd.exe
带有隐式使用选项/K
完成命令后保持控制台窗口打开,这有利于调试批处理文件。
当在 Windows 资源管理器中双击批处理文件时,用户将启动cmd.exe
用于使用隐式使用选项处理批处理文件/C
完成批处理后关闭控制台窗口,这不利于调试批处理文件,因为在这种情况下看不到错误消息。
在这两种情况下,Windows 都会创建应用程序启动时的环境变量的副本cmd.exe
通常是 Windows 资源管理器。因此启动的命令进程有一个local PATH
其值与父进程启动时的值相同cmd.exe
.
Example:
-
打开命令提示符窗口,运行title Process1
并运行set path
.
输出是PATH
and PATHEXT
正如当前在控制台窗口中为当前用户帐户定义的那样,现在具有窗口标题Process1.
-
Run set PATH=%SystemRoot%\System32
下一次set path
.
输出又是PATH
and PATHEXT
,但与PATH
现在只包含一个目录。
-
Run start "Process2"
并在带有窗口标题的新控制台窗口中运行Process2命令set path
.
输出是PATH
and PATHEXT
具有与之前相同的值Process1.
这表明在开始新流程时current运行进程的环境变量被复制,而不是 Windows 本身当前存储在 Windows 注册表中的环境变量。
-
Run in Process2命令set PATH=
接下来set path
.
输出仅PATHEXT
因为local PATH
不再存在Process2.
这表明每个进程都可以修改其环境变量,包括完全删除。
-
切换到Process1窗口,运行命令set PATH=%PATH%;%SystemRoot%
接下来set path
.
输出是PATH
有两个目录和PATHEXT
.
-
运行命令start "Process3"
并在打开的带有标题的窗口中Process3命令set path
.
输出是PATH
有两个目录也定义为Process1 and PATHEXT
.
-
Run in Process3命令set PATH=%SystemRoot%\System32
.
有 3 个命令进程正在运行,其值如下local PATH
when %SystemRoot%
扩展到C:\Windows
:
Process1: PATH=C:\Windows\System32;C:\Windows
Process2: PATH
根本不存在。
Process3: PATH=C:\Windows\System32
那么现在打开时会发生什么控制面板-系统-高级系统设置-环境变量并添加到列表中用户变量 the new环境变量PATH
有价值C:\Temp
,或者如果已经有一个user PATH
环境变量,edit PATH
并附加;C:\Temp
到值?
好吧,只要对话框窗口有标题环境变量显示两个列表已打开,修改变量没有任何反应,直到按钮OK单击可将所有更改接管到 Windows 注册表中并关闭窗口。
我们回到三个运行命令进程,运行在Process1, Process2 and Process3命令set path
。可以被看见:
Process1: PATH=C:\Windows\System32;C:\Windows
Process2: PATH
根本不存在。
Process3: PATH=C:\Windows\System32
已经运行的进程没有任何变化。
任何进程都不能修改不同运行进程的环境变量!
从 Windows 开始菜单中再打开一个命令提示符窗口并在第四个命令进程中运行该命令set path
。可见local PATH
第四个命令进程的已附加目录C:\Temp
now.
然后关闭所有四个命令进程并删除添加的user PATH
分别删除;C:\Temp
from user PATH
如果之前已附加此目录路径。
如果没有进程可以修改已运行进程的环境变量,这怎么可能?
作为 Windows 桌面运行的 Windows 资源管理器实例的环境变量列表在关闭时如何修改环境变量带按钮的窗口OK?
这两个问题的答案由eryksun https://stackoverflow.com/users/205580/eryksun在他的评论中。
将修改写入后system and user单击按钮将变量存入注册表OK of 环境变量窗口,Windows 发送WM_SETTINGCHANGE https://learn.microsoft.com/en-us/windows/win32/winmsg/wm-settingchange向所有顶级窗口发送消息,以通知正在运行的应用程序有关更改的系统参数。
是否处理该事件消息以及如何处理由应用程序决定。作为 Windows 桌面运行的 Windows 资源管理器从注册表中读取环境变量并相应地更新其环境变量列表。其他应用程序(例如 Total Commander)也处理此消息并更新其环境变量列表。但cmd.exe
幸运的是,不这样做,因为这确实会带来问题。
有没有可能修改system or user通过通知变量WM_SETTINGCHANGE
从命令提示符窗口或批处理文件中?
可以使用以下命令修改环境变量的注册表值reg add
命令。但这不会导致发送WM_SETTINGCHANGE
向所有顶级窗口发送消息。此类更改完成reg add
或与regedit
需要重新启动 Windows(或至少注销并登录当前用户)。
但也有这样的命令setx
这是专为修改system or user变量并且还发送WM_SETTINGCHANGE
根据指定参数更新注册表后向所有顶级窗口发送消息。跑步setx /?
在命令提示符窗口中了解详细信息。但请考虑到setx
不修改local运行命令进程的环境变量。这必须使用命令来完成set
除了使用setx
.
G) Windows 如何处理环境变量 PATHEXT?
环境变量PATHEXT
与环境变量相比,Windows 处理文件扩展名列表的方式有所不同PATH
.
System PATHEXT
and user PATHEXT
are NOT连接到local PATHEXT
.
A user PATHEXT
replaces the system PATHEXT
对于在已定义的帐户环境下运行的所有进程user PATHEXT
.
只定义了一个system PATHEXT
默认环境变量。
H) 是否可以禁用当前目录中的文件搜索?
如果在命令行或批处理文件中指定了脚本文件或可执行文件的文件名,而没有任何路径(即没有反斜杠),则 Windows 命令处理器默认在当前目录中搜索\
(或正斜杠/
感谢参数字符串中的自动更正)。
但在 Windows Vista 和更高版本的 Windows 客户端版本以及 Windows Server 2003 和更高版本的 Windows 服务器版本上,确实可以禁用在至少没有相对路径的情况下指定的当前目录中搜索脚本/可执行文件.\
通过定义环境变量NoDefaultCurrentDirectoryInExePath
具有写入的任何值eryksun https://stackoverflow.com/users/205580/eryksun在他下面的评论中,并由微软有关功能的文档进行了解释NeedCurrentDirectoryForExePathA https://learn.microsoft.com/en-us/windows/win32/api/processenv/nf-processenv-needcurrentdirectoryforexepatha.
See 从路径中删除当前工作目录 https://stackoverflow.com/questions/50064901/有关此环境变量的使用的更多详细信息。
I) 如何修改系统或用户PATH?
The system and user PATH
用户最好使用 Windows GUI 对话框窗口修改环境变量环境变量。该对话框窗口可以按如下方式打开:
- 单击 WindowsStart菜单按钮。
- 在键盘上输入环境变量.
- Windows 提供了两项:
编辑系统环境变量
编辑您帐户的环境变量
- 单击两个项目之一以打开环境变量 window.
也可以打开Windows控制面板。必须有下一步点击系统和安全 with Category选择显示选项View by。必须点击下一步System。必须点击左侧高级系统设置然后点击按钮环境变量...
The System window can be opened also by pressing the key combination Windows logo key + Pause if the keyboard has the key Pause at all or at least in combination with the key Fn. See also the Microsoft documentation page Keyboard shortcuts in Windows https://support.microsoft.com/en-us/windows/keyboard-shortcuts-in-windows-dcc61a57-8ff0-cffe-9796-cb9706c75eec.
进一步的用户操作是不言自明的,可以编辑user Path
在现有的上列表中或system Path
在下面的列表中。