mirror of
				https://github.com/godotengine/godot.git
				synced 2025-11-04 07:31:16 +00:00 
			
		
		
		
	This partially addresses https://github.com/godotengine/godot-proposals/issues/1432. To fully address the proposal above, official Windows installers will have to be compiled and distributed.
		
			
				
	
	
		
			219 lines
		
	
	
	
		
			6.6 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			219 lines
		
	
	
	
		
			6.6 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
// ----------------------------------------------------------------------------
 | 
						|
//
 | 
						|
// 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;
 |