1

I'm working on an installer which automates the installation of Node.js, extracts a node application to a folder, and then installs it via npm install. However, the installer always needs to be run twice in order for npm to work. This is installing onto Windows.

During the lifetime of my installer app...

  • If Node.js wasn't already installed, it gets installed
  • In the same process, steps later, npm install is executed
  • If Node.js didn't already exist before installer started, it fails saying npm is not a valid command
  • If Node.js was already installed when installer started, it succeeds

What I'm assuming is that the installation of Node.js creates new environment variables, but my process has not yet obtained these new variables - until the process is restarted. Then, the second time it can see those variables. Otherwise, within the same process, it cannot find npm because it cannot see the new environment variables. At least this is what I've narrowed the issue down to and is the only explanation why I always have to run my installer twice.

Background: The installer is created using Inno Setup (Unicode). I created an application in Delphi to display the user an interface while the installation is being done, as a majority of the original installer just displayed a blank non-responsive page saying "Preparing to install...". This Delphi application performs the actual install process inside of a thread, and that thread uses events to update a grid visible to the user. This event-driven thread reports the progress of each installation step back to the main form, and displays a responsive user interface showing each step of the install process and its status. This application then returns back an exit code to the installer for further handling.

If it weren't for requiring the wait for each sub-process and obtaining their exit codes, this wouldn't be an issue. But since I need to do that, Windows naturally passes the cached environment variables to each sub-process, still rendering them useless.

How can I force my application to see the new environment variables which have been added since the process started?

Jerry Dodge
  • 25,720
  • 28
  • 139
  • 301
  • possible duplicate of [Is there a command to refresh environment variables from the command prompt in Windows?](http://stackoverflow.com/questions/171588/is-there-a-command-to-refresh-environment-variables-from-the-command-prompt-in-w) – SomeKittens May 05 '14 at 23:08
  • 1
    @SomeKittensUx2666 That proposed duplicate is related to using a command prompt and the answers are useless. – Jerry Dodge May 05 '14 at 23:12
  • How are you installing node.js from your installer? Are you chaining the node.js MSI, or distributing the .exe directly yourself? – Chris Tavares May 06 '14 at 04:00
  • @Chris I'm chaining the MSI, and every step in this app returns an exit code to monitor the success. I am doing this within a thread in a Delphi application which displays a grid in a form to the user to view the progress of each step, updating the status. The Delphi application is then called from an Inno Setup installer, which passes the Exit Code through, and every external call waits for a result before it continues. – Jerry Dodge May 06 '14 at 04:05
  • Edited my question to explain. Unfortunately, it appears the only solution is to either require my app to be run twice, require a restart, or go through tons of chaos creating multiple EXE's to handle different install steps. – Jerry Dodge May 06 '14 at 04:20
  • Or, if I could make the installer re-launch its self, and then kill its self, that could solve it... I could save a registry entry for example `Restarting` which instructs the second instance to skip the install portion of Node.js and go straight to installing the node app. – Jerry Dodge May 06 '14 at 04:21
  • If you're installing your node app on the local machine anyway, why not just package up all the dependencies into the inno installer and deliver everything in one fell swoop? You can even package a private copy of node.exe and not disturb the global node installation on the machine at all. Basically, do the npm install step at compile (well, installer creation) time instead of at install time on the user's box. – Chris Tavares May 06 '14 at 04:36
  • @Chris It is an all-in-one installer with Node.js, that's the problem, since I install Node.js in the same process as using the `npm` command, it fails because the Windows environment variables aren't updated within my process - unless I re-launch my installer a second time after Node.js has been installed. – Jerry Dodge May 06 '14 at 04:38
  • For an example of an installer that does this, look at https://github.com/Azure/azure-sdk-tools-xplat/tree/master/tools/windows. This is a project I work on; we deliver via an MSI for windows or npm. In the MSI case we package all the dependencies together, so the end user doesn't have to install node themselves or run npm. – Chris Tavares May 06 '14 at 04:38
  • I shall pass that bit of info over to our developer who actually uses Node.js, as I know nothing about it, and am only trying to replicate my known manual process into an automated process. – Jerry Dodge May 06 '14 at 04:39
  • I'm just aiming for a responsive install UI that shows the user the progress of each specific step and does everything in just a couple clicks. What I have works well, it just has to be run twice in a row to work because of this hurdle. – Jerry Dodge May 06 '14 at 04:42
  • What I'm saying is you don't need to do the npm install step at all. Do it on the machine where you build the installer. Include the contents of the app's node_modules folder in your installer. That's it - everything that would have come down from NPM is already installed. That is assuming you're doing "npm install" and not "npm install -g" to set up your app on the path as a command line app. If you're doing install -g, you're doing the wrong thing in this case. – Chris Tavares May 06 '14 at 04:47
  • @Chris But it needs to install a service, the `npm install` process installs this service to Windows. – Jerry Dodge May 06 '14 at 04:49
  • @Chris I found the solution, see my answer below... – Jerry Dodge May 06 '14 at 13:34
  • Hm, I would say I found that solution... And offered you even [`more than one`](http://stackoverflow.com/q/23486233/960757). – TLama May 06 '14 at 13:48

1 Answers1

0

The solution without requiring any restart of your application is to pass the full path to the npm command in the nodejs program files folder. That way you won't need to rely on Windows and its environment variables - it's a direct route. Keep note of whether you're installing the 32bit or 64bit editions of Node.js, and make sure you look in the appropriate folder...

C:\Program Files\nodejs\npm
C:\Program Files (x86)\nodejs\npm
Jerry Dodge
  • 25,720
  • 28
  • 139
  • 301
  • Just note that with the `PATH` environment variable you would always get 32-bit path from a 32-bit installer. – TLama May 06 '14 at 13:39