带有NodeJS的IExpress安装后批处理无法立即找到NPM

时间:2018-08-15 23:34:22

标签: node.js windows batch-file windows-installer iexpress

我正在尝试使用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的运行放到安装脚本中,而不是使用“后安装”吗?

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

What is the reason for '...' is not recognized as an internal or external command, operable program or batch file?的答案说明了Windows注册表中存储系统用户的位置以及如何对它们进行更新。它还说明没有进程可以修改已经运行的进程的环境变量,并且每个新进程都将继承其父进程的当前环境变量列表。

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

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

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

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

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

这可以通过使用以下注释代码扩展npm来完成:

post_install.bat

该批处理文件读取当前存储在Windows注册表中的系统用户环境变量,并更新 local 环境变量,包括 local @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 XP / Windows Server 2003上也可以使用,尽管与Windows Vista / Server 2008和所有更高版本的Windows相比, REG 的输出在Windows XP / Server 2003上有所不同

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

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

答案 1 :(得分:0)

对于评论来说,这个时间太长了,尽管说实话,我的回答不只是回答。不过,尽力而为:

  1. 安全性 iExpress suffers from some major security vulnerabilities。如果这打动了您的客户,那确实是一件可怕的事情。只有我的两分钱和友好的单挑。
  2. SendMessageTimeout :即使成功应用了环境变量更新,该更新对系统上所有正在运行的应用程序也不是立即可用的。
  3. Chris Painter :我不了解 NodeJS 。希望Chris Painter知道如何正确部署此类脚本,我怀疑还有另一种方法比您使用的方法更可靠。不过,他现在可能不会潜伏在这里。
  

更新:使用a link在上述问题中添加了注释,该注释显示了如何使用Advanced Installer部署Node.js。