2

What I'm trying to achieve is to check if Node.js is already is installed, and if so I wanna check for the version being up to date, let's say 8.x.x

From the question below I already achieved the initial check for it being installed at all. My Code looks pretty similar to the answer of the question.

Using Process Exit code to show error message for a specific File in [Run]

Now I'm struggling with reading the actual output of the node -v command (Expected result a string containing the version).

Is there a way to achieve that?

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
Ch3micaL
  • 311
  • 1
  • 15
  • 1
    BTW, in the worst case, you can create your executable in any programming language as part of your program to scan the system and report such, and simply call it instead of other external executable. – Lex Li Sep 18 '18 at 12:04

1 Answers1

3

Running an application and parsing its output is rather inefficient way to check, if it exists and its version. Use FileSearch (node.exe is added to PATH) and GetVersionNumbers functions instead.

[Code]

function CheckNodeJs(var Message: string): Boolean;
var
  NodeFileName: string;
  NodeMS, NodeLS: Cardinal;
  NodeMajorVersion, NodeMinorVersion: Cardinal;
begin
  { Search for node.exe in paths listed in PATH environment variable }
  NodeFileName := FileSearch('node.exe', GetEnv('PATH'));
  Result := (NodeFileName <> '');
  if not Result then
  begin
    Message := 'Node.js not installed.';
  end
    else
  begin
    Log(Format('Found Node.js path %s', [NodeFileName]));
    Result := GetVersionNumbers(NodeFileName, NodeMS, NodeLS);
    if not Result then
    begin
      Message := Format('Cannot read Node.js version from %s', [NodeFileName]);
    end
      else
    begin
      { NodeMS is 32-bit integer with high 16 bits holding major version and }
      { low 16 bits holding minor version }

      { shift 16 bits to the right to get major version }
      NodeMajorVersion := NodeMS shr 16; 
      { select only low 16 bits }
      NodeMinorVersion := NodeMS and $FFFF;
      Log(Format('Node.js version is %d.%d', [NodeMajorVersion, NodeMinorVersion]));
      Result := (NodeMajorVersion >= 8);
      if not Result then
      begin
        Message := 'Node.js is too old';
      end
        else
      begin
        Log('Node.js is up to date');
      end;
    end;
  end;
end;

function InitializeSetup(): Boolean;
var
  Message: string;
begin
  Result := True;
  if not CheckNodeJs(Message) then
  begin
    MsgBox(Message, mbError, MB_OK);
    Result := False;
  end;
end;

Since Inno Setup 6.1, you can use GetVersionComponents instead of GetVersionNumbers to avoid the bit magics.


For a similar question, see Checking if Chrome is installed and is of specific version using Inno Setup.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992