关于“...”的原因是什么的答案不被识别为内部或外部命令、可运行程序或批处理文件?解释系统和用户环境变量在 Windows 注册表中的存储位置以及如何对其进行更新。它还解释了没有进程可以修改已经运行的进程的环境变量,并且每个新进程都会继承其父进程的当前环境变量列表。
因此,在启动IExpress安装过程时,此安装过程会从其父进程继承环境变量,该父进程通常是 Windows 资源管理器,但也可以是 www 浏览器或任何其他应用程序。
IExpress安装过程运行msiexec /i node.msi
安装Node.js并很可能在 Windows 注册表中添加或修改系统或用户环境变量。但是对整个机器和当前用户的持久存储环境变量的那些修改不会自动接管到已经运行的IExpress安装过程的本地环境变量列表中。
接下来由IExpress安装过程启动,这是一个带有命令行的命令过程,cmd /c post_install.bat
它通过 Windows 获取当前为IExpress安装过程设置的环境变量的新副本。
因此,无论在 Windows 注册表中对持久存储系统和用户环境变量或MSIEXEC进程的本地环境变量进行的任何修改,对于执行批处理文件的 Windows 命令进程来说都是不可见的。post_install.bat
但是npm
执行的批处理文件post_install.bat
依赖于Node.js安装过程中存储在 Windows 注册表中的环境变量。因此,有必要在执行批处理文件之前使用系统和用户环境变量(按此顺序)更新本地环境变量。npm
这可以通过post_install.bat
使用以下注释代码进行扩展来完成:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Set current directory to user's profile directory.
cd /D "%UserProfile%"
rem Make sure the environment variables used to build local PATH from
rem the PATH environment variables currently stored in Windows registry
rem do not already exist with unwanted values.
set "LocalPath="
set "SystemPath="
set "UserPath="
rem Get all system environment variables as currently stored in Windows
rem registry and set them in local environment with exception of system PATH.
for /F "skip=2 tokens=1,2*" %%A in ('%SystemRoot%\System32\reg.exe query "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" 2^>nul') do (
if /I "%%A" == "Path" (
set "SystemPath=%%C"
) else if /I "%%B" == "REG_SZ" (
set "%%A=%%C"
) else if /I "%%B" == "REG_EXPAND_SZ" (
call set "%%A=%%C"
)
)
rem Get all user environment variables as currently stored in Windows
rem registry and set them in local environment with exception of user PATH.
for /F "skip=2 tokens=1,2*" %%A in ('%SystemRoot%\System32\reg.exe query "HKEY_CURRENT_USER\Environment" 2^>nul') do (
if /I "%%A" == "Path" (
set "UserPath=%%C"
) else if /I "%%B" == "REG_SZ" (
set "%%A=%%C"
) else if /I "%%B" == "REG_EXPAND_SZ" (
call set "%%A=%%C"
)
)
rem PATH can contain references to environment variables which can be
rem expanded only after having all environment variables except system
rem and user PATH already set in local environment. Now it is possible
rem to expand the environment variable references in system and user
rem PATH and concatenate them two one PATH set in local environment
rem replacing PATH as inherited from process starting this batch file.
if not defined SystemPath goto ProcessUserPath
call set "LocalPath=%SystemPath%"
if not "%LocalPath:~-1%" == ";" set "LocalPath=%LocalPath%;"
:ProcessUserPath
if not defined UserPath goto SetLocalPath
call set "LocalPath=%LocalPath%%UserPath%"
:SetLocalPath
if not defined LocalPath goto DoInstall
if "%LocalPath:~-1%" == ";" set "LocalPath=%LocalPath:~0,-1%"
if defined LocalPath set "PATH=%LocalPath%"
:DoInstall
rem Call NPM in its own environment inherited from current local environment.
rem Then discard all modifications made by NPM batch file on its own local
rem environment and restore the environment this batch file has set before.
setlocal
call npm.cmd install ...
endlocal
rem Insert here other post installation commands.
rem Restore previous environment on starting this batch file which means
rem discarding all modifications made on local list of environment variables
rem and restoring initial current directory before modification by CD at top
rem and restoring initial status of command extensions and delayed expansion.
endlocal
此批处理文件读取当前存储在 Windows 注册表中的系统和用户环境变量,并更新包括本地在内的本地环境变量,即使在 Windows XP / Windows Server 2003 上也可以工作,尽管与 Windows Vista / Windows Vista / 相比,Windows XP / Server 2003 上的REG输出不同Server 2008 和所有更高版本的 Windows。 PATH
要了解使用的命令及其工作原理,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读每个命令显示的所有帮助页面。
call /?
cd /?
echo /?
endlocal /?
for /?
if /?
reg /?
reg query /?
rem /?
set /?
setlocal /?