IJpress Post Installation Batch与NodeJS没有立即找到NPM

问题描述 投票:2回答:2

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

iExpress包只是安装包Node:

msiexec /i node.msi

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

Post安装批处理使用:cmd /c post_install.bat运行

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

npm install <dependency>

这在MSI安装后似乎不会立即生效,但它将在第二次运行.exe并安装NodeJS时工作。

因此,无论出于何种原因,MSI都没有设置PATH变量,直到Batch完成之后,或者没有使用正确的环境变量设置iExpress Post Installation批次。

其他人遇到过这个问题,是否有工作或推荐?

我应该将MSI的安装和NPM的运行放入安装脚本而不是使用Post Install吗?

谢谢你的帮助。

node.js windows batch-file windows-installer iexpress
2个回答
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安装过程的本地环境变量列表中。

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

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

但是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注册表中并更新本地环境变量(包括本地PATH)甚至可以在Windows XP / Windows Server 2003上运行,尽管与Windows Vista相比,Windows XP / Server 2003上的REG输出不同/ Server 2008和所有更高版本的Windows版本。

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

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

0
投票

这对评论来说太长了,不过我老实说评论不仅仅是回答。尽管如此,还有一些事情:

  1. 安全:iExpress suffers from some major security vulnerabilities。如果这打击了你的客户,处理它真的是一件可怕的事情。只是我的两分钱和友好的单挑。 这同样适用于此处讨论的许多自解压安装工具:Error Creating a 7-zip installer package(链接仅供参考,您不应该需要它)。 建议您使用已建立且维护得当的部署工具:Tools Discussion and links all over the placeTools List(仅限简化的主要工具)。访问推荐的最后一个链接。
  2. SendMessageTimeout:即使成功应用,环境变量更新也不会立即用于系统上所有正在运行的应用程序。 据说你可以使用SendMessageTimeout API用新设置和变量更新所有正在运行的窗口。我不确定这是多么可靠 - 我记得Win9X当天有些问题,但我不是这方面的专家。 也许看看这里:https://www.advancedinstaller.com/forums/viewtopic.php?t=27578。这是一个非常好的留言板属于Advanced InstallerWiX features the WixBroadcastSettingChange and WixBroadcastEnvironmentChange Custom Actions(我从未尝试过)。我相信它的核心实现在这里:BroadcastSettingsChange.cpp。 本质上:调用SendMessageTimeout API应该使PATH改变“坚持”。
  3. Chris Painter:我不能在NodeJS上加速。希望Chris Painter能够知道如何正确部署这些脚本,我怀疑还有另一种方法比你使用的更可靠。此刻他可能不会潜伏在这里。

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

© www.soinside.com 2019 - 2024. All rights reserved.