Skip to content

Instantly share code, notes, and snippets.

@ikonst
Created November 9, 2012 15:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ikonst/4046350 to your computer and use it in GitHub Desktop.
Save ikonst/4046350 to your computer and use it in GitHub Desktop.
PuTTY InnoSetup "Add to PATH" patch
Index: putty.iss
===================================================================
--- putty.iss (revision 9586)
+++ putty.iss (working copy)
@@ -77,6 +77,9 @@
Name: desktopicon\user; Description: "For the current user only"; GroupDescription: "Additional icons:"; Flags: exclusive unchecked
Name: quicklaunchicon; Description: "Create a &Quick Launch icon for PuTTY (current user only)"; GroupDescription: "Additional icons:"; Flags: unchecked
Name: associate; Description: "&Associate .PPK files (PuTTY Private Key) with Pageant and PuTTYgen"; GroupDescription: "Other tasks:"
+Name: path; Description: "Add PuTTY to the system &path"; GroupDescription: "Other tasks:"
+Name: path\common; Description: "For all users"; GroupDescription: "Other tasks:"; Flags: exclusive unchecked
+Name: path\user; Description: "For the current user only"; GroupDescription: "Other tasks:"; Flags: exclusive unchecked
[Registry]
Root: HKCR; Subkey: ".ppk"; ValueType: string; ValueName: ""; ValueData: "PuTTYPrivateKey"; Flags: uninsdeletevalue; Tasks: associate
@@ -85,7 +88,7 @@
Root: HKCR; Subkey: "PuTTYPrivateKey\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\pageant.exe"" ""%1"""; Tasks: associate
Root: HKCR; Subkey: "PuTTYPrivateKey\shell\edit"; ValueType: string; ValueName: ""; ValueData: "&Edit"; Tasks: associate
Root: HKCR; Subkey: "PuTTYPrivateKey\shell\edit\command"; ValueType: string; ValueName: ""; ValueData: """{app}\puttygen.exe"" ""%1"""; Tasks: associate
-; Add to PATH on NT-class OS?
+Root: HKLM; Subkey: "SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\putty.exe"; ValueType: string; ValueName: ""; ValueData: "{app}\putty.exe"; Flags: uninsdeletekey
[UninstallRun]
; -cleanup-during-uninstall is an undocumented option that tailors the
@@ -104,3 +107,101 @@
FinishedRestartMessage=One or more [name] programs are still running.%nSetup will not replace these program files until you restart your computer.%n%nWould you like to restart now?
; ...and this comes up if you try to uninstall.
UninstalledAndNeedsRestart=One or more %1 programs are still running.%nThe program files will not be removed until your computer is restarted.%n%nWould you like to restart now?
+
+[Code]
+function IsPathEqual(const Path1,Path2:String): Boolean;
+begin
+ Result := CompareText(RemoveBackslashUnlessRoot(Path1), RemoveBackslashUnlessRoot(Path2)) = 0;
+end;
+
+function NextPath(const PathData: String; var P:Integer; var Path:String): Boolean;
+var
+ Start: Integer;
+begin
+ Start := P;
+
+ Result := Start <= Length(PathData);
+ if not Result then Exit;
+
+ for P:= Start to Length(PathData) do
+ if PathData[P] = ';' then
+ begin
+ P := P + 1;
+ Path := Copy(PathData, Start, P-Start-1);
+ Exit;
+ end;
+
+ P := P + 1;
+ Path := Copy(PathData, Start, P-Start-1);
+end;
+
+procedure EnvPathAdd(const RootKey: Integer; const SubKeyName:String; const AddedPath: String);
+var
+ PathData: String;
+ i: Integer;
+ Path: String;
+begin
+ if not RegQueryStringValue(RootKey, SubKeyName, 'Path', PathData) then
+ Exit;
+
+ i := 1;
+ while NextPath(PathData, i, Path) do
+ if IsPathEqual(Path, AddedPath) then Exit; { AddedPath is already in PATH }
+
+ { Add path and write back the value }
+ Insert(';' + AddedPath, PathData, Length(PathData)+1);
+ RegWriteStringValue(RootKey, SubKeyName, 'Path', PathData);
+end;
+
+procedure EnvPathRemove(const RootKey: Integer; const SubKeyName:String; const RemovedPath: String);
+var
+ PathData: String;
+ i, prev: Integer;
+ Path: String;
+ Changed: Boolean;
+begin
+ if not RegQueryStringValue(RootKey, SubKeyName, 'Path', PathData) then
+ Exit;
+
+ { Remove the path element when found }
+ Changed := False;
+ i := 1;
+ prev := 1;
+ while NextPath(PathData, i, Path) do
+ begin
+ if IsPathEqual(Path, RemovedPath) then
+ begin
+ if prev > 1 then
+ Delete(PathData, prev-1, i-prev) { delete with previous ';' }
+ else
+ Delete(PathData, prev, i-prev); { delete with next ';' }
+ i := prev;
+ Changed := True;
+ end;
+ prev := i;
+ end;
+
+ { If changed, write back the value }
+ if Changed then
+ RegWriteStringValue(RootKey, SubKeyName, 'Path', PathData);
+end;
+
+procedure CurStepChanged(CurStep: TSetupStep);
+begin
+ if CurStep = ssPostInstall then
+ begin
+ if IsTaskSelected('path\common') then
+ EnvPathAdd(HKLM, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', ExpandConstant('{app}'));
+ if IsTaskSelected('path\user') then
+ EnvPathAdd(HKCU, 'Environment', ExpandConstant('{app}'));
+ end;
+end;
+
+procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
+begin
+ if CurUninstallStep = usPostUninstall then
+ begin
+ EnvPathRemove(HKLM, 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', ExpandConstant('{app}'));
+ EnvPathRemove(HKCU, 'Environment', ExpandConstant('{app}'));
+ end;
+end;
\ No newline at end of file
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment