Skip to content

Commit 22a43ef

Browse files
committed
Updated version
2 parents f31dd2a + be6a12c commit 22a43ef

File tree

1 file changed

+321
-0
lines changed

1 file changed

+321
-0
lines changed

nvm.iss

Lines changed: 321 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,321 @@
1+
#define MyAppName "NVM for Windows"
2+
#define MyAppShortName "nvm"
3+
#define MyAppLCShortName "nvm"
4+
#define MyAppVersion "1.1.10"
5+
#define MyAppPublisher "Ecor Ventures LLC"
6+
#define MyAppURL "https://github.com/coreybutler/nvm-windows"
7+
#define MyAppExeName "nvm.exe"
8+
#define MyIcon "bin\nodejs.ico"
9+
#define MyAppId "40078385-F676-4C61-9A9C-F9028599D6D3"
10+
#define ProjectRoot "."
11+
12+
[Setup]
13+
; NOTE: The value of AppId uniquely identifies this application.
14+
; Do not use the same AppId value in installers for other applications.
15+
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
16+
PrivilegesRequired=admin
17+
; SignTool=MsSign $f
18+
; SignedUninstaller=yes
19+
AppId={#MyAppId}
20+
AppName={#MyAppName}
21+
AppVersion={#MyAppVersion}
22+
AppVerName={#MyAppName} {#MyAppVersion}
23+
AppPublisher={#MyAppPublisher}
24+
AppPublisherURL={#MyAppURL}
25+
AppSupportURL={#MyAppURL}
26+
AppUpdatesURL={#MyAppURL}
27+
DefaultDirName={userappdata}\{#MyAppShortName}
28+
DisableDirPage=no
29+
DefaultGroupName={#MyAppName}
30+
AllowNoIcons=yes
31+
LicenseFile={#ProjectRoot}\LICENSE
32+
OutputDir={#ProjectRoot}\dist\{#MyAppVersion}
33+
OutputBaseFilename={#MyAppLCShortName}-setup
34+
SetupIconFile={#ProjectRoot}\{#MyIcon}
35+
Compression=lzma
36+
SolidCompression=yes
37+
ChangesEnvironment=yes
38+
DisableProgramGroupPage=yes
39+
ArchitecturesInstallIn64BitMode=x64 ia64
40+
UninstallDisplayIcon={app}\{#MyIcon}
41+
AppCopyright=Copyright (C) 2018-2021 Ecor Ventures LLC, Corey Butler, and contributors.
42+
43+
[Languages]
44+
Name: "english"; MessagesFile: "compiler:Default.isl"
45+
46+
[Tasks]
47+
Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1
48+
49+
[Files]
50+
Source: "{#ProjectRoot}\bin\*"; DestDir: "{app}"; BeforeInstall: PreInstall; Flags: ignoreversion recursesubdirs createallsubdirs; Excludes: "{#ProjectRoot}\bin\install.cmd"
51+
52+
[Icons]
53+
Name: "{group}\{#MyAppShortName}"; Filename: "{app}\{#MyAppExeName}"; IconFilename: "{#MyIcon}"
54+
Name: "{group}\Uninstall {#MyAppShortName}"; Filename: "{uninstallexe}"
55+
56+
[Code]
57+
var
58+
SymlinkPage: TInputDirWizardPage;
59+
60+
function IsDirEmpty(dir: string): Boolean;
61+
var
62+
FindRec: TFindRec;
63+
ct: Integer;
64+
begin
65+
ct := 0;
66+
if FindFirst(ExpandConstant(dir + '\*'), FindRec) then
67+
try
68+
repeat
69+
if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY = 0 then
70+
ct := ct+1;
71+
until
72+
not FindNext(FindRec);
73+
finally
74+
FindClose(FindRec);
75+
Result := ct = 0;
76+
end;
77+
end;
78+
79+
//function getInstalledVErsions(dir: string):
80+
var
81+
nodeInUse: string;
82+
83+
procedure TakeControl(np: string; nv: string);
84+
var
85+
path: string;
86+
begin
87+
// Move the existing node.js installation directory to the nvm root & update the path
88+
RenameFile(np,ExpandConstant('{app}')+'\'+nv);
89+
90+
RegQueryStringValue(HKEY_LOCAL_MACHINE,
91+
'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
92+
'Path', path);
93+
94+
StringChangeEx(path,np+'\','',True);
95+
StringChangeEx(path,np,'',True);
96+
StringChangeEx(path,np+';;',';',True);
97+
98+
RegWriteExpandStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'Path', path);
99+
100+
RegQueryStringValue(HKEY_CURRENT_USER,
101+
'Environment',
102+
'Path', path);
103+
104+
StringChangeEx(path,np+'\','',True);
105+
StringChangeEx(path,np,'',True);
106+
StringChangeEx(path,np+';;',';',True);
107+
108+
RegWriteExpandStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', path);
109+
110+
nodeInUse := ExpandConstant('{app}')+'\'+nv;
111+
112+
end;
113+
114+
function Ansi2String(AString:AnsiString):String;
115+
var
116+
i : Integer;
117+
iChar : Integer;
118+
outString : String;
119+
begin
120+
outString :='';
121+
for i := 1 to Length(AString) do
122+
begin
123+
iChar := Ord(AString[i]); //get int value
124+
outString := outString + Chr(iChar);
125+
end;
126+
127+
Result := outString;
128+
end;
129+
130+
procedure PreInstall();
131+
var
132+
TmpResultFile, TmpJS, NodeVersion, NodePath: string;
133+
stdout: Ansistring;
134+
ResultCode: integer;
135+
msg1, msg2, msg3, dir1: Boolean;
136+
begin
137+
// Create a file to check for Node.JS
138+
TmpJS := ExpandConstant('{tmp}') + '\nvm_check.js';
139+
SaveStringToFile(TmpJS, 'console.log(require("path").dirname(process.execPath));', False);
140+
141+
// Execute the node file and save the output temporarily
142+
TmpResultFile := ExpandConstant('{tmp}') + '\nvm_node_check.txt';
143+
Exec(ExpandConstant('{cmd}'), '/C node "'+TmpJS+'" > "' + TmpResultFile + '"', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
144+
DeleteFile(TmpJS)
145+
146+
// Process the results
147+
LoadStringFromFile(TmpResultFile,stdout);
148+
NodePath := Trim(Ansi2String(stdout));
149+
if DirExists(NodePath) then begin
150+
Exec(ExpandConstant('{cmd}'), '/C node -v > "' + TmpResultFile + '"', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
151+
LoadStringFromFile(TmpResultFile, stdout);
152+
NodeVersion := Trim(Ansi2String(stdout));
153+
msg1 := SuppressibleMsgBox('Node '+NodeVersion+' is already installed. Do you want NVM to control this version?', mbConfirmation, MB_YESNO, IDYES) = IDNO;
154+
if msg1 then begin
155+
msg2 := SuppressibleMsgBox('NVM cannot run in parallel with an existing Node.js installation. Node.js must be uninstalled before NVM can be installed, or you must allow NVM to control the existing installation. Do you want NVM to control node '+NodeVersion+'?', mbConfirmation, MB_YESNO, IDYES) = IDYES;
156+
if msg2 then begin
157+
TakeControl(NodePath, NodeVersion);
158+
end;
159+
if not msg2 then begin
160+
DeleteFile(TmpResultFile);
161+
WizardForm.Close;
162+
end;
163+
end;
164+
if not msg1 then
165+
begin
166+
TakeControl(NodePath, NodeVersion);
167+
end;
168+
end;
169+
170+
// Make sure the symlink directory doesn't exist
171+
if DirExists(SymlinkPage.Values[0]) then begin
172+
// If the directory is empty, just delete it since it will be recreated anyway.
173+
dir1 := IsDirEmpty(SymlinkPage.Values[0]);
174+
if dir1 then begin
175+
RemoveDir(SymlinkPage.Values[0]);
176+
end;
177+
if not dir1 then begin
178+
msg3 := SuppressibleMsgBox(SymlinkPage.Values[0]+' will be overwritten and all contents will be lost. Do you want to proceed?', mbConfirmation, MB_OKCANCEL, IDOK) = IDOK;
179+
if msg3 then begin
180+
RemoveDir(SymlinkPage.Values[0]);
181+
end;
182+
if not msg3 then begin
183+
//RaiseException('The symlink cannot be created due to a conflict with the existing directory at '+SymlinkPage.Values[0]);
184+
WizardForm.Close;
185+
end;
186+
end;
187+
end;
188+
end;
189+
190+
procedure InitializeWizard;
191+
begin
192+
SymlinkPage := CreateInputDirPage(wpSelectDir,
193+
'Set Node.js Symlink', 'The active version of Node.js will always be available here.',
194+
'Select the folder in which Setup should create the symlink, then click Next.',
195+
False, '');
196+
SymlinkPage.Add('This directory will automatically be added to your system path.');
197+
SymlinkPage.Values[0] := ExpandConstant('{pf}\nodejs');
198+
end;
199+
200+
function InitializeUninstall(): Boolean;
201+
var
202+
path: string;
203+
nvm_symlink: string;
204+
begin
205+
SuppressibleMsgBox('Removing NVM for Windows will remove the nvm command and all versions of node.js, including global npm modules.', mbInformation, MB_OK, IDOK);
206+
207+
// Remove the symlink
208+
RegQueryStringValue(HKEY_LOCAL_MACHINE,
209+
'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
210+
'NVM_SYMLINK', nvm_symlink);
211+
RemoveDir(nvm_symlink);
212+
213+
// Clean the registry
214+
RegDeleteValue(HKEY_LOCAL_MACHINE,
215+
'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
216+
'NVM_HOME')
217+
RegDeleteValue(HKEY_LOCAL_MACHINE,
218+
'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
219+
'NVM_SYMLINK')
220+
RegDeleteValue(HKEY_CURRENT_USER,
221+
'Environment',
222+
'NVM_HOME')
223+
RegDeleteValue(HKEY_CURRENT_USER,
224+
'Environment',
225+
'NVM_SYMLINK')
226+
227+
RegQueryStringValue(HKEY_LOCAL_MACHINE,
228+
'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
229+
'Path', path);
230+
231+
StringChangeEx(path,'%NVM_HOME%','',True);
232+
StringChangeEx(path,'%NVM_SYMLINK%','',True);
233+
StringChangeEx(path,';;',';',True);
234+
235+
RegWriteExpandStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'Path', path);
236+
237+
RegQueryStringValue(HKEY_CURRENT_USER,
238+
'Environment',
239+
'Path', path);
240+
241+
StringChangeEx(path,'%NVM_HOME%','',True);
242+
StringChangeEx(path,'%NVM_SYMLINK%','',True);
243+
StringChangeEx(path,';;',';',True);
244+
245+
RegWriteExpandStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', path);
246+
247+
Result := True;
248+
end;
249+
250+
// Generate the settings file based on user input & update registry
251+
procedure CurStepChanged(CurStep: TSetupStep);
252+
var
253+
path: string;
254+
begin
255+
if CurStep = ssPostInstall then
256+
begin
257+
SaveStringToFile(ExpandConstant('{app}\settings.txt'), 'root: ' + ExpandConstant('{app}') + #13#10 + 'path: ' + SymlinkPage.Values[0] + #13#10, False);
258+
259+
// Add Registry settings
260+
RegWriteExpandStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'NVM_HOME', ExpandConstant('{app}'));
261+
RegWriteExpandStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'NVM_SYMLINK', SymlinkPage.Values[0]);
262+
RegWriteExpandStringValue(HKEY_CURRENT_USER, 'Environment', 'NVM_HOME', ExpandConstant('{app}'));
263+
RegWriteExpandStringValue(HKEY_CURRENT_USER, 'Environment', 'NVM_SYMLINK', SymlinkPage.Values[0]);
264+
265+
RegWriteStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{#MyAppId}_is1', 'DisplayVersion', '{#MyAppVersion}');
266+
267+
// Update system and user PATH if needed
268+
RegQueryStringValue(HKEY_LOCAL_MACHINE,
269+
'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
270+
'Path', path);
271+
if Pos('%NVM_HOME%',path) = 0 then begin
272+
path := path+';%NVM_HOME%';
273+
StringChangeEx(path,';;',';',True);
274+
RegWriteExpandStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'Path', path);
275+
end;
276+
if Pos('%NVM_SYMLINK%',path) = 0 then begin
277+
path := path+';%NVM_SYMLINK%';
278+
StringChangeEx(path,';;',';',True);
279+
RegWriteExpandStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'Path', path);
280+
end;
281+
RegQueryStringValue(HKEY_CURRENT_USER,
282+
'Environment',
283+
'Path', path);
284+
if Pos('%NVM_HOME%',path) = 0 then begin
285+
path := path+';%NVM_HOME%';
286+
StringChangeEx(path,';;',';',True);
287+
RegWriteExpandStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', path);
288+
end;
289+
if Pos('%NVM_SYMLINK%',path) = 0 then begin
290+
path := path+';%NVM_SYMLINK%';
291+
StringChangeEx(path,';;',';',True);
292+
RegWriteExpandStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', path);
293+
end;
294+
end;
295+
end;
296+
297+
function getSymLink(o: string): string;
298+
begin
299+
Result := SymlinkPage.Values[0];
300+
end;
301+
302+
function getCurrentVersion(o: string): string;
303+
begin
304+
Result := nodeInUse;
305+
end;
306+
307+
function isNodeAlreadyInUse(): boolean;
308+
begin
309+
Result := Length(nodeInUse) > 0;
310+
end;
311+
312+
[Run]
313+
Filename: "{cmd}"; Parameters: "/C ""mklink /D ""{code:getSymLink}"" ""{code:getCurrentVersion}"""" "; Check: isNodeAlreadyInUse; Flags: runhidden;
314+
315+
[UninstallDelete]
316+
Type: files; Name: "{app}\nvm.exe";
317+
Type: files; Name: "{app}\elevate.cmd";
318+
Type: files; Name: "{app}\elevate.vbs";
319+
Type: files; Name: "{app}\nodejs.ico";
320+
Type: files; Name: "{app}\settings.txt";
321+
Type: filesandordirs; Name: "{app}";

0 commit comments

Comments
 (0)