Created
September 6, 2025 23:20
-
-
Save daemondevin/9389064b18b6e23b6d659cef1bb729b0 to your computer and use it in GitHub Desktop.
This function creates Windows symbolic links with flexible options for different link types and path configurations.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * CreateSymlink.nsh v1.0 | |
| * | |
| * This function creates Windows symbolic links with flexible | |
| * options for different link types and path configurations. | |
| * | |
| * Parameters: | |
| * LinkPath - Specifies the new symbolic link name. | |
| * TargetPath - Specifies the path that the new link points to. | |
| * Type - Specifies if this symlink is a file or directory. | |
| * Set to auto to let the function decide. | |
| * Relative - Specifies if using a relative or absolute path | |
| * | |
| * Macro Usage: | |
| * ${CreateSymlink} "$LinkPath" "$TargetPath" "$Type" "$Relative" $0 $1 | |
| * $0 holds true/false | |
| * $1 holds error message if failed, empty if success | |
| * | |
| * Function Usage: | |
| * Push $LinkPath | |
| * Push $TargetPath | |
| * Push $Type ; "file"|"directory"|"auto" | |
| * Push $Relative ; "true"|"false" | |
| * Call CreateSymlink | |
| * Pop $R0 ; Result ("true"/"false") | |
| * Pop $R1 ; Error message if failed, "" if success | |
| */ | |
| ; --- Defines | |
| !ifndef CREATESYMLINK_NSH_INCLUDED | |
| !define CREATESYMLINK_NSH_INCLUDED | |
| ; --- Includes | |
| !ifndef LOGICLIB | |
| !include LogicLib.nsh | |
| !endif | |
| !define CreateSymlink "!insertmacro _CreateSymlink" | |
| !macro _CreateSymlink _LinkPath _TargetPath _TYPE _RELATIVE _RESULT _ERROR | |
| Push `${_LinkPath}` | |
| Push `${_TargetPath}` | |
| Push `${_TYPE}` | |
| Push `${_RELATIVE}` | |
| Call CreateJunction | |
| Pop `${_RESULT}` | |
| Pop `${_ERROR}` | |
| !macroend | |
| Function CreateSymlink | |
| Exch $3 ; Relative flag | |
| Exch | |
| Exch $2 ; Type | |
| Exch | |
| Exch 2 | |
| Exch $1 ; TargetPath | |
| Exch | |
| Exch 3 | |
| Exch $0 ; LinkPath | |
| Push $4 | |
| Push $5 | |
| Push $6 | |
| Push $7 | |
| StrCpy $R0 "false" | |
| StrCpy $R1 "" | |
| ${IfNot} ${FileExists} "$1" | |
| StrCpy $R1 "Target path does not exist: $1" | |
| Goto _SYMLINK_DONE | |
| ${EndIf} | |
| ; Decide flags: 0=file, 1=dir | |
| StrCpy $4 0 | |
| ${If} "$2" == "directory" | |
| StrCpy $4 1 | |
| ${ElseIf} "$2" == "auto" | |
| ${If} ${FileExists} "$1\*.*" | |
| StrCpy $4 1 | |
| ${EndIf} | |
| ${EndIf} | |
| ; Relative path (optional) | |
| ${If} "$3" == "true" | |
| ${GetRelativePath} "$0" "$1" $5 | |
| StrCpy $1 "$5" | |
| ${EndIf} | |
| ; Call CreateSymbolicLinkW | |
| System::Call 'kernel32::CreateSymbolicLinkW(w "$0", w "$1", i $4) i .r6' | |
| ${If} $6 <> 0 | |
| StrCpy $R0 "true" | |
| ${Else} | |
| System::Call 'kernel32::GetLastError() i .r7' | |
| ${If} $7 = 183 | |
| StrCpy $R1 "Link path already exists" | |
| ${ElseIf} $7 = 1314 | |
| StrCpy $R1 "Insufficient privileges to create symbolic link" | |
| ${Else} | |
| StrCpy $R1 "Failed to create symbolic link (Error $7)" | |
| ${EndIf} | |
| ${EndIf} | |
| _SYMLINK_DONE: | |
| Pop $7 | |
| Pop $6 | |
| Pop $5 | |
| Pop $4 | |
| Exch $R1 | |
| Exch | |
| Exch $R0 | |
| FunctionEnd | |
| !endif ; CREATESYMLINK_NSH_INCLUDED |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment