1;This file has been created by Adam Twardoch <adam@twardoch.com> 2;See README.TXT in this folder for instructions on building the setup 3 4[Setup] 5AppName=TTX 6AppVerName=TTX 2.0 r040926 for Windows 7AppPublisher=Just van Rossum 8AppPublisherURL=http://www.letterror.com/code/ttx/ 9AppSupportURL=http://www.font.org/software/ttx/ 10AppUpdatesURL=http://www.font.org/software/ttx/ 11DefaultDirName={pf}\TTX 12DefaultGroupName=TTX 13AllowNoIcons=false 14LicenseFile=..\LICENSE.txt 15InfoBeforeFile=fonttools-win-setup.txt 16InfoAfterFile=..\Doc\changes.txt 17OutputBaseFilename=WinTTX2.0r040926 18AppCopyright=Copyright 1999-2004 by Just van Rossum, Letterror, The Netherlands. 19UninstallDisplayIcon={app}\ttx.ico 20 21[Tasks] 22Name: desktopicon; Description: Create a &desktop icon; GroupDescription: Additional icons: 23 24[Files] 25Source: ..\dist\ttx\*.*; DestDir: {app}; Flags: ignoreversion promptifolder 26Source: ..\LICENSE.txt; DestDir: {app}; Flags: ignoreversion promptifolder 27Source: ..\Doc\documentation.html; DestDir: {app}; Flags: ignoreversion promptifolder 28Source: ..\Doc\changes.txt; DestDir: {app}; Flags: ignoreversion promptifolder 29Source: ..\Doc\bugs.txt; DestDir: {app}; Flags: ignoreversion promptifolder 30Source: fonttools-win-setup.txt; DestDir: {app}; Flags: ignoreversion promptifolder 31Source: ttx.ico; DestDir: {app}; Flags: ignoreversion promptifolder; AfterInstall: AddFolderToPathVariable 32 33[Icons] 34Name: {userdesktop}\ttx.exe; Filename: {app}\ttx.exe; Tasks: desktopicon; IconFilename: {app}\ttx.ico; IconIndex: 0 35Name: {group}\TTX; Filename: {app}\ttx.exe; Tasks: desktopicon; IconFilename: {app}\ttx.ico; IconIndex: 0 36Name: {group}\TTX documentation; Filename: {app}\documentation.html; IconIndex: 0 37Name: {group}\Changes; Filename: {app}\changes.txt; IconIndex: 0 38Name: {group}\Bugs; Filename: {app}\bugs.txt; IconIndex: 0 39Name: {group}\License; Filename: {app}\LICENSE.txt; IconIndex: 0 40Name: {group}\Uninstall TTX; Filename: {uninstallexe}; IconIndex: 0 41Name: {reg:HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders,SendTo}\TTX; Filename: {app}\ttx.exe; WorkingDir: {reg:HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders,SendTo}; IconFilename: {app}\ttx.ico; IconIndex: 0; MinVersion: 0,5.00.2195 42 43[_ISTool] 44EnableISX=true 45 46[Registry] 47Root: HKCR; Subkey: .ttx; ValueType: string; ValueData: {reg:HKCR\.xml,}; Flags: createvalueifdoesntexist uninsdeletekey 48 49[Code] 50 51// 52// InnoSetup Extensions Knowledge Base 53// Article 44 - Native ISX procedures for PATH modification 54// http://www13.brinkster.com/vincenzog/isxart.asp?idart=44 55// Author: Thomas Vedel 56// 57 58// Version log: 59// 03/31/2003: Initial release (thv@lr.dk) 60 61const 62 // Modification method 63 pmAddToBeginning = $1; // Add dir to beginning of Path 64 pmAddToEnd = $2; // Add dir to end of Path 65 pmAddAllways = $4; // Add also if specified dir is already included in existing path 66 pmAddOnlyIfDirExists = $8; // Add only if specified dir actually exists 67 pmRemove = $10; // Remove dir from path 68 pmRemoveSubdirsAlso = $20; // Remove dir and all subdirs from path 69 70 // Scope 71 psCurrentUser = 1; // Modify path for current user 72 psAllUsers = 2; // Modify path for all users 73 74 // Error results 75 mpOK = 0; // No errors 76 mpMissingRights = -1; // User has insufficient rights 77 mpAutoexecNoWriteacc = -2; // Autoexec can not be written (may be readonly) 78 mpBothAddAndRemove = -3; // User has specified that dir should both be removed from and added to path 79 80 81{ Helper procedure: Split a path environment variable into individual dirnames } 82procedure SplitPath(Path: string; var Dirs: TStringList); 83var 84 pos: integer; 85 s: string; 86begin 87 Dirs.Clear; 88 s := ''; 89 pos := 1; 90 while (pos<=Length(Path)) do 91 begin 92 if (Path[pos]<>';') then 93 s := s + Path[pos]; 94 if ((Path[pos]=';') or (pos=Length(Path))) then 95 begin 96 s := Trim(s); 97 s := RemoveQuotes(s); 98 s := Trim(s); 99 if (s <> '') then 100 Dirs.Add(s); 101 s := ''; 102 end; 103 Pos := Pos + 1; 104 end; 105end; // procedure SplitPath 106 107 108{ Helper procedure: Concatenate individual dirnames into a path environment variable } 109procedure ConcatPath(Dirs: TStringList; Quotes: boolean; var Path: string); 110var 111 Index, MaxIndex: integer; 112 s: string; 113begin 114 MaxIndex := Dirs.Count-1; 115 Path := ''; 116 for Index := 0 to MaxIndex do 117 begin 118 s := Dirs.Strings[Index]; 119 if ((Quotes) and (pos(' ',s) > 0)) then 120 s := AddQuotes(s); 121 Path := Path + s; 122 if (Index < MaxIndex) then 123 Path := Path + ';' 124 end; 125end; // procedure ConcatPath 126 127 128{ Helper function: Modifies path environment string } 129procedure ModifyPathString(OldPath, DirName: string; Method: integer; Quotes: boolean; var ResultPath: string); 130var 131 Dirs: TStringList; 132 DirNotInPath: Boolean; 133 i: integer; 134begin 135 // Create Dirs variable 136 Dirs := TStringList.Create; 137 138 // Remove quotes form DirName 139 DirName := Trim(DirName); 140 DirName := RemoveQuotes(DirName); 141 DirName := Trim(DirName); 142 143 // Split old path in individual directory names 144 SplitPath(OldPath, Dirs); 145 146 // Check if dir is allready in path 147 DirNotInPath := True; 148 for i:=Dirs.Count-1 downto 0 do 149 begin 150 if (uppercase(Dirs.Strings[i]) = uppercase(DirName)) then 151 DirNotInPath := False; 152 end; 153 154 // Should dir be removed from existing Path? 155 if ((Method and (pmRemove or pmRemoveSubdirsAlso)) > 0) then 156 begin 157 for i:=Dirs.Count-1 downto 0 do 158 begin 159 if (((Method and pmRemoveSubdirsAlso) > 0) and (pos(uppercase(DirName)+'\', uppercase(Dirs.Strings[i])) = 1)) or 160 (((Method and (pmRemove) or (pmRemoveSubdirsAlso)) > 0) and (uppercase(DirName) = uppercase(Dirs.Strings[i]))) 161 then 162 Dirs.Delete(i); 163 end; 164 end; 165 166 // Should dir be added to existing Path? 167 if ((Method and (pmAddToBeginning or pmAddToEnd)) > 0) then 168 begin 169 // Add dir to path 170 if (((Method and pmAddAllways) > 0) or DirNotInPath) then 171 begin 172 // Dir is not in path allready or should be added anyway 173 if (((Method and pmAddOnlyIfDirExists) = 0) or (DirExists(DirName))) then 174 begin 175 // Dir actually exsists or should be added anyway 176 if ((Method and pmAddToBeginning) > 0) then 177 Dirs.Insert(0, DirName) 178 else 179 Dirs.Append(DirName); 180 end; 181 end; 182 end; 183 184 // Concatenate directory names into one single path variable 185 ConcatPath(Dirs, Quotes, ResultPath); 186 // Finally free Dirs object 187 Dirs.Free; 188end; // ModifyPathString 189 190 191{ Helper function: Modify path on Windows 9x } 192function ModifyPath9x(DirName: string; Method: integer): integer; 193var 194 AutoexecLines: TStringList; 195 ActualLine: String; 196 PathLineNos: TStringList; 197 FirstPathLineNo: Integer; 198 OldPath, ResultPath: String; 199 LineNo, CharNo, Index: integer; 200 201 TempString: String; 202begin 203 // Expect everything to be OK 204 result := mpOK; 205 206 // Create stringslists 207 AutoexecLines := TStringList.Create; 208 PathLineNos := TStringList.Create; 209 210 // Read existing path 211 OldPath := ''; 212 LoadStringFromFile('c:\Autoexec.bat', TempString); 213 AutoexecLines.Text := TempString; 214 PathLineNos.Clear; 215 // Read Autoexec line by line 216 for LineNo := 0 to AutoexecLines.Count - 1 do begin 217 ActualLine := AutoexecLines.Strings[LineNo]; 218 // Check if line starts with "PATH=" after first stripping spaces and other "fill-chars" 219 if Pos('=', ActualLine) > 0 then 220 begin 221 for CharNo := Pos('=', ActualLine)-1 downto 1 do 222 if (ActualLine[CharNo]=' ') or (ActualLine[CharNo]=#9) then 223 Delete(ActualLine, CharNo, 1); 224 if Pos('@', ActualLine) = 1 then 225 Delete(ActualLine, 1, 1); 226 if (Pos('PATH=', uppercase(ActualLine))=1) or (Pos('SETPATH=', uppercase(ActualLine))=1) then 227 begin 228 // Remove 'PATH=' and add path to "OldPath" variable 229 Delete(ActualLine, 1, pos('=', ActualLine)); 230 // Check if an earlier PATH variable is referenced, but there has been no previous PATH defined in Autoexec 231 if (pos('%PATH%',uppercase(ActualLine))>0) and (PathLineNos.Count=0) then 232 OldPath := ExpandConstant('{win}') + ';' + ExpandConstant('{win}')+'\COMMAND'; 233 if (pos('%PATH%',uppercase(ActualLine))>0) then 234 begin 235 ActualLine := Copy(ActualLine, 1, pos('%PATH%',uppercase(ActualLine))-1) + 236 OldPath + 237 Copy(ActualLine, pos('%PATH%',uppercase(ActualLine))+6, Length(ActualLine)); 238 end; 239 OldPath := ActualLine; 240 241 // Update list of line numbers holding path variables 242 PathLineNos.Add(IntToStr(LineNo)); 243 end; 244 end; 245 end; 246 247 // Save first line number in Autoexec.bat which modifies path environment variable 248 if PathLineNos.Count > 0 then 249 FirstPathLineNo := StrToInt(PathLineNos.Strings[0]) 250 else 251 FirstPathLineNo := 0; 252 253 // Modify path 254 ModifyPathString(OldPath, DirName, Method, True, ResultPath); 255 256 // Write Modified path back to Autoexec.bat 257 // First delete all existing path references from Autoexec.bat 258 Index := PathLineNos.Count-1; 259 while (Index>=0) do 260 begin 261 AutoexecLines.Delete(StrToInt(PathLineNos.Strings[Index])); 262 Index := Index-1; 263 end; 264 // Then insert new path variable into Autoexec.bat 265 AutoexecLines.Insert(FirstPathLineNo, '@PATH='+ResultPath); 266 // Delete old Autoexec.bat from disk 267 if not DeleteFile('c:\Autoexec.bat') then 268 result := mpAutoexecNoWriteAcc; 269 Sleep(500); 270 // And finally write Autoexec.bat back to disk 271 if not (result=mpAutoexecNoWriteAcc) then 272 SaveStringToFile('c:\Autoexec.bat', AutoexecLines.Text, false); 273 274 // Free stringlists 275 PathLineNos.Free; 276 AutoexecLines.Free; 277end; // ModifyPath9x 278 279 280{ Helper function: Modify path on Windows NT, 2000 and XP } 281function ModifyPathNT(DirName: string; Method, Scope: integer): integer; 282var 283 RegRootKey: integer; 284 RegSubKeyName: string; 285 RegValueName: string; 286 OldPath, ResultPath: string; 287 OK: boolean; 288begin 289 // Expect everything to be OK 290 result := mpOK; 291 292 // Initialize registry key and value names to reflect if changes should be global or local to current user only 293 case Scope of 294 psCurrentUser: 295 begin 296 RegRootKey := HKEY_CURRENT_USER; 297 RegSubKeyName := 'Environment'; 298 RegValueName := 'Path'; 299 end; 300 psAllUsers: 301 begin 302 RegRootKey := HKEY_LOCAL_MACHINE; 303 RegSubKeyName := 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment'; 304 RegValueName := 'Path'; 305 end; 306 end; 307 308 // Read current path value from registry 309 OK := RegQueryStringValue(RegRootKey, RegSubKeyName, RegValueName, OldPath); 310 if not OK then 311 begin 312 result := mpMissingRights; 313 Exit; 314 end; 315 316 // Modify path 317 ModifyPathString(OldPath, DirName, Method, False, ResultPath); 318 319 // Write new path value to registry 320 if not RegWriteStringValue(RegRootKey, RegSubKeyName, RegValueName, ResultPath) then 321 begin 322 result := mpMissingRights; 323 Exit; 324 325 end; 326end; // ModifyPathNT 327 328 329{ Main function: Modify path } 330function ModifyPath(Path: string; Method, Scope: integer): integer; 331begin 332 // Check if both add and remove has been specified (= error!) 333 if (Method and (pmAddToBeginning or pmAddToEnd) and (pmRemove or pmRemoveSubdirsAlso)) > 0 then 334 begin 335 result := mpBothAddAndRemove; 336 Exit; 337 end; 338 339 // Perform directory constant expansion 340 Path := ExpandConstantEx(Path, ' ', ' '); 341 342 // Test if Win9x 343 if InstallOnThisVersion('4,0','0,0') = irInstall then 344 ModifyPath9x(Path, Method); 345 346 // Test if WinNT, 2000 or XP 347 if InstallOnThisVersion('0,4','0,0') = irInstall then 348 ModifyPathNT(Path, Method, Scope); 349end; // ModifyPath 350 351procedure AddFolderToPathVariable(); 352begin 353 ModifyPath('{app}', pmAddToBeginning, psAllUsers); 354 ModifyPath('{app}', pmAddToBeginning, psCurrentUser); 355end; 356