Skip to content

Instantly share code, notes, and snippets.

@scagood
Last active January 17, 2018 10:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save scagood/be8624aa262ab3966771404acf00e45e to your computer and use it in GitHub Desktop.
Save scagood/be8624aa262ab3966771404acf00e45e to your computer and use it in GitHub Desktop.
A basic node version manager for windows

NVM windows ish

This will download and symlink to a specified nodejs version.

Installing

The batch file is dependent on both 7zip and curl, these are automatically downloaded (regardless of if they're already installed).

To install simply download the batch file, and add the NodeJS and nvm 'directories' to the %path% enviromnment variable. In my case my path became: %path%;%appdata%\nodejs;%appdata%\nvm

Then copy nvm.bat into %appdata%\nvm.

Finally open a Command Prompt or Power Shell window, and start using nvm

Using

Version checking

to check what version of node and npm is currently installed use:

# Command:
> nvm

# Output e.g.:
Current Configuration:
Node: v8.9.1
Arch: x64
 npm: 5.5.1

Installing NodeJS

Command structure:

nvm %node_version% %node_architecture%
%node_architecture% is assumed to be what your OS is.

Important things to note

Cannot find released versions.

Some version of NodeJS will not be found as the program is looking for a node-v%version%-win-%arch%.zip file. This was not released with all versions of node, I may try to fix this later.

A simple check to see if this is the problem is going to the /dist/ directory. e.g. Version 8.9.3 has a node-v8.9.3-win-x64.zip and a node-v8.9.3-win-x86.zip file. Where as Version 5.0.0 does not.

The Node.exe is complied (https://nodejs.org/dist/v5.0.0/win-x64/) however NPM was not packaged, therefore I cannot find a zip bundle.

Making sym links

Making symlinks on windows requires specific priveledges This program will warn you about admin permissions, and does not check whether making sym links is possible. To skip the sym link creation check set %skipCheck% to true:

set skipCheck=true

Node version is not changing

If nodejs is installed else where the this program might be over written, please ensure either your old node version is not in path or it's uninstalled.

NPM

For every version of NodeJS a new instance of npm is installed, meaning you'll have to reinstall the global modules in each NodeJS version.

Example

To install a specific version of node use:

# Command for getting version 9.1.0
> nvm 9.1.0
# Output e.g. not privileged:
Looking for nodejs-9.1.0-x64
Searching for the node repository.
Unzipping the downloaded repository
Removing the archive file
Moving the extracted files
The node version has been found and extracted, but admin permissions are required to make a 'symlink'.
Please either re-run this in an elevated command prompt or run the following commands as an admin:

rmdir "%appdata%\nodejs\"
mklink /D "%appdata%\nodejs\" "%appdata%\node-bin\nodejs-9.1.0-x64\"
# Output e.g. privileged:
Looking for nodejs-9.1.0-x64
Searching for the node repository.
Unzipping the downloaded repository
Removing the archive file
Moving the extracted files
Remove the old symlink
Make the new symlink
=======================
Current Configuration:
Node: v9.1.0
Arch: x64
 npm: 5.5.1
@echo off
:------------------------------
:SetGlobals
set nodeDir=%appdata%\NodeJS
set nodeBin=%appdata%\Node-Bin
set ExeSBin=http://zone.scagood.uk/scagood/utils
set nodeNvm=%~dp0
set skipCheck=false
:------------------------------
:TidyTime
if "%nodeDir:~-1%"=="\" set nodeDir=%nodeDir:~0,-1%
if "%nodeBin:~-1%"=="\" set nodeBin=%nodeBin:~0,-1%
if "%nodeNvm:~-1%"=="\" set nodeNvm=%nodeNvm:~0,-1%
for /f "tokens=4-5 delims=. " %%i in ('ver') do set VERSION=%%i.%%j
if "%version:~0,2%"=="10" (set /a OS10=1) else (set /a OS10=0)
:------------------------------
:PreparePowerShell
set dlPre=$client = New-Object System.Net.WebClient;
:------------------------------
:Retreve7zip
IF EXIST "%nodeNvm%\7za.exe" GOTO RetreveCurl
echo Downloading 7zip
set dlPst=$client.DownloadFile('%ExeSBin%/7za.exe', '%nodeNvm%\7za.exe');
powershell -nologo -noprofile -command "& {%dlPre%%dlPst%}"
:------------------------------
:RetreveCurl
IF EXIST "%nodeNvm%\curl.exe" GOTO RetreveCrts
echo Downloading Curl
set dlPst=$client.DownloadFile('%ExeSBin%/curl.exe', '%nodeNvm%\curl.exe');
powershell -nologo -noprofile -command "& {%dlPre%%dlPst%}"
:------------------------------
:RetreveCrts
IF EXIST "%nodeNvm%\ca-bundle.crt" GOTO StartNVM
echo Downloading Crts
set dlPst=$client.DownloadFile('%ExeSBin%/ca-bundle.crt', '%nodeNvm%\ca-bundle.crt');
powershell -nologo -noprofile -command "& {%dlPre%%dlPst%}"
set dlPre=
set dlPst=
goto StartNVM
:------------------------------
:CheckAdminPerms
net session 1>nul 2>&1
if %errorLevel% == 0 (
goto successAdmin
) else (
goto failedAdmin
)
:------------------------------
:StartNVM
REM Detect Arch
reg Query "HKLM\Hardware\Description\System\CentralProcessor\0" | find /i "x86" > NUL && set OS=32BIT || set OS=64BIT
IF "%1"=="" goto what
goto findVer
:verFound
goto findArch
:archFound
set nodeFile=nodejs-%nodeVer%-%nodeArch%
if "%OS10%"=="1" (
echo Looking for %nodeFile%
) else (
echo Looking for %nodeFile%
)
IF EXIST "%nodeBin%\%nodeFile%\" (
GOTO link
) else (
GOTO download
)
:successAdmin
IF NOT EXIST "%nodeDir%\" GOTO removed
echo Remove the old symlink
rmdir "%nodeDir%\"
:link
if "%skipCheck%"=="true" (
REM bypass admin check
goto successAdmin
) else (
goto CheckAdminPerms
)
:removed
echo Make the new symlink
mklink /D "%nodeDir%" "%nodeBin%\%nodeFile%\" >nul
echo =======================
goto what
:unzip
echo Unzipping the downloaded repository
7za x "%nodeNvm%\%nodeFile%.zip" -y -o"%nodeNvm%" > nul
echo Removing the archive file
del "%nodeNvm%\%nodeFile%.zip" >nul
echo Moving the extracted files
move "%nodeNvm%\node-v%nodeVer%-win-%nodeArch%" "%nodebin%\%nodeFile%" >nul
goto link
:download
echo Searching for the node repository.
(curl -s -o "%nodeNvm%\%nodeFile%.zip" -w "%%{http_code}" "https://nodejs.org/dist/v%nodeVer%/node-v%nodeVer%-win-%nodeArch%.zip")|findstr /r "^200$" >nul
if errorlevel 1 (
del "%nodeNvm%\%nodeFile%.zip"
goto failedDownload
)
goto unzip
:findVer
set nodeVer=
echo %1|findstr /r "^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$" >nul
if not errorlevel 1 (set nodeVer=%1)
echo %1|findstr /r "^[0-9][0-9]*\.[0-9][0-9]*$" >nul
if not errorlevel 1 (set nodeVer=%1.0)
echo %1|findstr /r "^[0-9][0-9]*$" >nul
if not errorlevel 1 (set nodeVer=%1.0.0)
IF "%nodeVer%"=="" goto failedUnkVer
goto verFound
:findArch
IF "%2"=="x64" goto 64bit
IF "%2"=="64" goto 64bit
IF "%2"=="x32" goto 32bit
IF "%2"=="32" goto 32bit
IF "%2"=="x86" goto 32bit
IF "%2"=="86" goto 32bit
IF "%2"=="" goto detect
goto failedArchUnk
:detect
if %OS%==32BIT goto 32bit
if %OS%==64BIT goto 64bit
goto failedArch
:64bit
if %OS%==32BIT goto failedOS
set nodeArch=x64
goto archFound
:32bit
set nodeArch=x86
goto archFound
:what
REM find the npm version
type "%nodeDir%\node_modules\npm\package.json"|^
findstr /r "\"version\": \"([^,]*)\"">"%~dp0nvmtempasd.txt"
set /p npmVersion=<"%~dp0nvmtempasd.txt"
del "%~dp0nvmtempasd.txt"
rem isolate the version code.
set npmVersion=%npmVersion:"=%
set npmVersion=%npmVersion: =%
set npmVersion=%npmVersion:,=%
set npmVersion=%npmVersion:version:=%
REM print the versions
if "%OS10%"=="1" (
echo Current Configuration: 
echo|set /p="Node: " & call node -v
echo|set /p="Arch: " & call node -p -e "process.arch"
echo|set /p=" NPM: " & echo %npmVersion%
) else (
echo Current Configuration:
echo|set /p="Node: " & call node -v
echo|set /p="Arch: " & call node -p -e "process.arch"
echo|set /p="NPM: " & echo %npmVersion%
)
goto complete
REM Failed notices
:failedAdmin
if "%OS10%"=="1" echo|set /p=""
echo|set /p="The node version has been found and extracted, but "
echo admin permissions are required to make a 'symlink'.
echo|set /p="Please either re-run this in an elevated "
(type 2>&1 -ea ig .|goto failedAdminCMD);&<# rem #>goto failedAdminPS
:failedAdminCMD
echo|set /p="command prompt "
goto failedAdminCont
:failedAdminPS
echo|set /p="powershell "
goto failedAdminCont
:failedAdminCont
IF EXIST "%nodeDir%\" (
echo or run the following commands as an admin:
echo.
if "%OS10%"=="1" (
echo rmdir "%nodeDir%\"
) else (
echo rmdir "%nodeDir%\"
)
goto failedAdmin2
)
echo or run the following command as an admin:
:failedAdmin2
if "%OS10%"=="1" (
echo mklink /D "%nodeDir%\" "%nodeBin%\%nodeFile%\"
) else (
echo mklink /D "%nodeDir%\" "%nodeBin%\%nodeFile%\"
)
goto complete
:failedDownload
if "%OS10%"=="1" echo|set /p=""
echo The download for %nodeFile% failed
goto complete
:failedUnkVer
if "%OS10%"=="1" echo|set /p=""
echo Unknown Version"
IF NOT "%1"=="" (
echo : "%1"
)
goto complete
:failedArchUnk
if "%OS10%"=="1" echo|set /p=""
echo Unknown Architecture: "%2"
goto complete
:failedArch
if "%OS10%"=="1" echo|set /p=""
echo Failed to detect this Architecture
goto complete
:failedOS
if "%OS10%"=="1" echo|set /p=""
echo Cannot install x64 on a x32 computer
goto complete
:complete
set nodeDir=""
set nodeFile=""
set nodeBin=""
set nodeVer=""
set npmVersion=""
if "%OS10%"=="1" echo|set /p=""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment