Mercurial > hg
view contrib/packaging/inno/modpath.iss @ 41847:0f49b56d5d74
inno: replace add_path.exe with a Pascal script
While attempting to build the Inno installer, I was unable to
find a copy of add_path.exe from the source site previously
listed in the docs.
Some quick Googling revealed that achieving this functionality
in native Pascal scripts seems to be preferred these days.
This commit vendors "Modify Path" (fetched from
https://www.legroom.net/software/modpath) and plugs it into
our Inno config file per its instructions.
The existing Inno installer appears to only modify PATH for
the current user (as opposed to at the system level). I've
maintained this behavior with Modify Path. Although it would
be trivial to change or add checkboxes to control the behavior.
I'll leave this as a follow-up.
Differential Revision: https://phab.mercurial-scm.org/D6060
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Thu, 28 Feb 2019 12:54:48 -0800 |
parents | |
children | 109315c41d5e |
line wrap: on
line source
// ---------------------------------------------------------------------------- // // Inno Setup Ver: 5.4.2 // Script Version: 1.4.2 // Author: Jared Breland <jbreland@legroom.net> // Homepage: http://www.legroom.net/software // License: GNU Lesser General Public License (LGPL), version 3 // http://www.gnu.org/licenses/lgpl.html // // Script Function: // Allow modification of environmental path directly from Inno Setup installers // // Instructions: // Copy modpath.iss to the same directory as your setup script // // Add this statement to your [Setup] section // ChangesEnvironment=true // // Add this statement to your [Tasks] section // You can change the Description or Flags // You can change the Name, but it must match the ModPathName setting below // Name: modifypath; Description: &Add application directory to your environmental path; Flags: unchecked // // Add the following to the end of your [Code] section // ModPathName defines the name of the task defined above // ModPathType defines whether the 'user' or 'system' path will be modified; // this will default to user if anything other than system is set // setArrayLength must specify the total number of dirs to be added // Result[0] contains first directory, Result[1] contains second, etc. // const // ModPathName = 'modifypath'; // ModPathType = 'user'; // // function ModPathDir(): TArrayOfString; // begin // setArrayLength(Result, 1); // Result[0] := ExpandConstant('{app}'); // end; // #include "modpath.iss" // ---------------------------------------------------------------------------- procedure ModPath(); var oldpath: String; newpath: String; updatepath: Boolean; pathArr: TArrayOfString; aExecFile: String; aExecArr: TArrayOfString; i, d: Integer; pathdir: TArrayOfString; regroot: Integer; regpath: String; begin // Get constants from main script and adjust behavior accordingly // ModPathType MUST be 'system' or 'user'; force 'user' if invalid if ModPathType = 'system' then begin regroot := HKEY_LOCAL_MACHINE; regpath := 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment'; end else begin regroot := HKEY_CURRENT_USER; regpath := 'Environment'; end; // Get array of new directories and act on each individually pathdir := ModPathDir(); for d := 0 to GetArrayLength(pathdir)-1 do begin updatepath := true; // Modify WinNT path if UsingWinNT() = true then begin // Get current path, split into an array RegQueryStringValue(regroot, regpath, 'Path', oldpath); oldpath := oldpath + ';'; i := 0; while (Pos(';', oldpath) > 0) do begin SetArrayLength(pathArr, i+1); pathArr[i] := Copy(oldpath, 0, Pos(';', oldpath)-1); oldpath := Copy(oldpath, Pos(';', oldpath)+1, Length(oldpath)); i := i + 1; // Check if current directory matches app dir if pathdir[d] = pathArr[i-1] then begin // if uninstalling, remove dir from path if IsUninstaller() = true then begin continue; // if installing, flag that dir already exists in path end else begin updatepath := false; end; end; // Add current directory to new path if i = 1 then begin newpath := pathArr[i-1]; end else begin newpath := newpath + ';' + pathArr[i-1]; end; end; // Append app dir to path if not already included if (IsUninstaller() = false) AND (updatepath = true) then newpath := newpath + ';' + pathdir[d]; // Write new path RegWriteStringValue(regroot, regpath, 'Path', newpath); // Modify Win9x path end else begin // Convert to shortened dirname pathdir[d] := GetShortName(pathdir[d]); // If autoexec.bat exists, check if app dir already exists in path aExecFile := 'C:\AUTOEXEC.BAT'; if FileExists(aExecFile) then begin LoadStringsFromFile(aExecFile, aExecArr); for i := 0 to GetArrayLength(aExecArr)-1 do begin if IsUninstaller() = false then begin // If app dir already exists while installing, skip add if (Pos(pathdir[d], aExecArr[i]) > 0) then updatepath := false; break; end else begin // If app dir exists and = what we originally set, then delete at uninstall if aExecArr[i] = 'SET PATH=%PATH%;' + pathdir[d] then aExecArr[i] := ''; end; end; end; // If app dir not found, or autoexec.bat didn't exist, then (create and) append to current path if (IsUninstaller() = false) AND (updatepath = true) then begin SaveStringToFile(aExecFile, #13#10 + 'SET PATH=%PATH%;' + pathdir[d], True); // If uninstalling, write the full autoexec out end else begin SaveStringsToFile(aExecFile, aExecArr, False); end; end; end; end; // Split a string into an array using passed delimeter procedure MPExplode(var Dest: TArrayOfString; Text: String; Separator: String); var i: Integer; begin i := 0; repeat SetArrayLength(Dest, i+1); if Pos(Separator,Text) > 0 then begin Dest[i] := Copy(Text, 1, Pos(Separator, Text)-1); Text := Copy(Text, Pos(Separator,Text) + Length(Separator), Length(Text)); i := i + 1; end else begin Dest[i] := Text; Text := ''; end; until Length(Text)=0; end; procedure CurStepChanged(CurStep: TSetupStep); var taskname: String; begin taskname := ModPathName; if CurStep = ssPostInstall then if IsTaskSelected(taskname) then ModPath(); end; procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep); var aSelectedTasks: TArrayOfString; i: Integer; taskname: String; regpath: String; regstring: String; appid: String; begin // only run during actual uninstall if CurUninstallStep = usUninstall then begin // get list of selected tasks saved in registry at install time appid := '{#emit SetupSetting("AppId")}'; if appid = '' then appid := '{#emit SetupSetting("AppName")}'; regpath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\'+appid+'_is1'); RegQueryStringValue(HKLM, regpath, 'Inno Setup: Selected Tasks', regstring); if regstring = '' then RegQueryStringValue(HKCU, regpath, 'Inno Setup: Selected Tasks', regstring); // check each task; if matches modpath taskname, trigger patch removal if regstring <> '' then begin taskname := ModPathName; MPExplode(aSelectedTasks, regstring, ','); if GetArrayLength(aSelectedTasks) > 0 then begin for i := 0 to GetArrayLength(aSelectedTasks)-1 do begin if comparetext(aSelectedTasks[i], taskname) = 0 then ModPath(); end; end; end; end; end; function NeedRestart(): Boolean; var taskname: String; begin taskname := ModPathName; if IsTaskSelected(taskname) and not UsingWinNT() then begin Result := True; end else begin Result := False; end; end;