带有NodeJS的IExpress安装后批处理无法立即找到NPM [英] IExpress Post Installation Batch with NodeJS not finding NPM immediately

查看:79
本文介绍了带有NodeJS的IExpress安装后批处理无法立即找到NPM的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用iExpress在我在NodeJS上创建的小脚本上安装依赖项.

iExpress软件包仅安装软件包Node:

msiexec /i node.msi

然后运行安装后批处理以将Javascript放入%UserProfile%文件夹中的文件夹中.

安装后批处理使用以下命令运行: cmd /c post_install.bat

批处理中有一行不起作用:

npm install <dependency>

在安装MSI之后,这似乎无法立即生效,但是在第二次运行.exe并安装NodeJS时,它将奏效.

因此,无论出于何种原因,要么MSI直到批处理完成后才设置PATH变量,要么iExpress Post Installation批处理未设置正确的环境变量.

其他任何人都遇到过此问题,是否有解决方法或建议?

我应该将MSI的安装和NPM的运行放到安装脚本中,而不是使用后安装"吗?

感谢您的帮助.

解决方案

的答案是什么?不能识别为内部或外部命令,可操作程序或批处理文件?解释系统 user 环境变量在Windows注册表中的存储位置以及更新方式在他们身上.它还解释说,没有进程可以修改已经在运行的进程的环境变量,并且每个新进程都将继承其父进程的当前环境变量列表.

因此,在启动 IExpress 安装过程时,此安装过程将从其父进程(通常是Windows资源管理器)继承环境变量,但也可以是www浏览器或任何其他应用程序.

IExpress 安装过程运行msiexec /i node.msi,该过程将安装 Node.js ,最有可能添加或修改系统用户 Windows注册表中的环境变量.但是,对整个计算机和当前用户的持久性存储环境变量所做的那些修改不会自动转移到已经在运行 IExpress 安装过程的 local 环境变量列表中.

下一步是通过 IExpress 安装过程启动的,该过程是带有命令行cmd /c post_install.bat的命令行过程,该命令行过程由Windows获取当前为 IExpress 安装过程设置的环境变量的新副本.与之共事.

因此,无论在Windows注册表中在持久存储的系统 user 环境变量上还是在对于执行批处理文件post_install.bat的Windows命令进程, MSIEXEC 进程的本地环境变量不可见.

但是post_install.bat执行的npm批处理文件取决于 Node.js 安装过程中Windows注册表中存储的环境变量.因此,在执行npm批处理之前,有必要使用 system user 环境变量(按此顺序)更新 local 环境变量.文件.

这可以通过使用以下注释代码扩展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注册表中的系统用户环境变量,并更新 local 环境变量,包括 local PATH即使在Windows XP/Windows Server 2003上也可以使用,尽管与Windows Vista/Server 2008和所有更高版本的Windows相比, REG 的输出在Windows XP/Server 2003上有所不同./p>

要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面.

  • call /?
  • cd /?
  • echo /?
  • endlocal /?
  • for /?
  • if /?
  • reg /?
  • reg query /?
  • rem /?
  • set /?
  • setlocal /?

I'm trying to use iExpress to install dependencies on a small script that I've created on NodeJS.

The iExpress package simply installs the packages Node:

msiexec /i node.msi

Then runs a Post installation Batch to put the Javascript into a folder in the %UserProfile% folder.

The Post installation Batch is run with: cmd /c post_install.bat

In the batch there is a line which isn't working:

npm install <dependency>

This doesn't seem to work immediately after the MSI install, but it will work the second time the .exe is run and NodeJS is installed.

So for whatever reason, either the MSI isn't setting the PATH variables until after the Batch is finished, or the iExpress Post Installation batch isn't getting set with the right environmental variables.

Anyone else experienced this problem, is there a work around or recommendation?

Should I put the installation of the MSI and the running of NPM into an installation script instead of using the Post Install?

Thanks for your help.

解决方案

The answer on What is the reason for '...' is not recognized as an internal or external command, operable program or batch file? explains where system and user environment variables are stored in Windows registry and how updates are made on them. It also explains that no process can modify the environment variables of an already running process and each new process inherits the current list of environment variables of its parent process.

So on starting IExpress installation process this installation process inherits the environment variables from its parent process which is usually Windows Explorer, but can be also a www browser or any other application.

The IExpress installation process runs msiexec /i node.msi which installs Node.js and most likely adds or modifies system or user environment variables in Windows registry. But those modifications on persistent stored environment variables for entire machine and current user are not automatically taken over to local environment variables list of already running IExpress installation process.

Next is started by IExpress installation process a command process with command line cmd /c post_install.bat which gets by Windows a fresh copy of environment variables as currently set for IExpress installation process to work with.

So whatever the Node.js installation process modified in Windows registry on the persistent stored system and user environment variables or on local environment variables of MSIEXEC process is not visible for the Windows command process executing the batch file post_install.bat.

But npm batch file executed by post_install.bat depends on environment variables stored in Windows registry during Node.js installation process. For that reason it is necessary to update local environment variables with the system and user environment variables (in this order) before executing npm batch file.

This can be done by extending post_install.bat with following commented code:

@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

This batch file reading system and user environment variables as currently stored in Windows registry and updating the local environment variables including local PATH works even on Windows XP / Windows Server 2003 although output of REG is different on Windows XP / Server 2003 in comparison to Windows Vista / Server 2008 and all later Windows versions.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • call /?
  • cd /?
  • echo /?
  • endlocal /?
  • for /?
  • if /?
  • reg /?
  • reg query /?
  • rem /?
  • set /?
  • setlocal /?

这篇关于带有NodeJS的IExpress安装后批处理无法立即找到NPM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆