Page 1 of 1

A problem with symlink script

Posted: 09 Sep 2020 14:37
by tonymatthews3090
Hello everyone!

I have been using a Symlink script that I have found on Puvox Software Blog. I have come across an issue with the script that I am unable to fix. If a file/folder I created a symlink for features one of specific characters such as: ! % ^ & then the symlink gets corrupted because it skips/ignores these characters and as a result the symlink points at non-existing file/folder.

Could you help me with fixing it?

Re: A problem with symlink script

Posted: 09 Sep 2020 17:55
by Squashman
I think your best option is to ask the developer to fix his program.

Re: A problem with symlink script

Posted: 10 Sep 2020 01:54
by tonymatthews3090
I have already contacted the developer but the response was that they're busy at the moment so I'm on my own.

Re: A problem with symlink script

Posted: 10 Sep 2020 20:02
by Aacini
I think you should start indicating that your "symlink script" is really a Batch-file script (specifically, one called "Symlink-Creator.bat")

The problem with special Batch-file characters (like ! % & < > |) is very well known... I suggest you to list the problematic file names and post the Batch-file script you have problems with.

How we can help you to fix code if we can not see the code?

Antonio

Re: A problem with symlink script

Posted: 11 Sep 2020 02:09
by tonymatthews3090
symlink_creator.bat

Code: Select all

::  ================================================================== ::
::  ========================  iTask Software  ======================== ::
::  ================================================================== ::
::  ============== Symlink Creator with Drag&Drop v1.3 =============== ::
::  This script makes a symlink of any files/folders  ( instructions at:  https://goo.gl/8vYCDT  ) 
::  ================================================================== ::
::  ================================================================== ::

@echo off
setlocal enableextensions enabledelayedexpansion

if "%~1"=="" ( mshta "javascript:alert('You should drag desired files onto this');close();" && exit )

set /P inputed_target_dir= Path to folder, wherein the symlink will be created: 
set inputed_target_dir=%inputed_target_dir%\

for %%a in (%*) do  (

:: in PARENTHESIS we use ! instead % for set-ed variables  (read more: https://superuser.com/a/78509/249349 )
set original_path=%%a
set original_path_quoted=!original_path!
:: check if not queted, and if so, make it quoted
set original_path_quoted|find """" >nul || set original_path_quoted="!original_path!"

:: if directory
FOR %%i IN (!original_path_quoted!) DO IF EXIST %%~si\NUL (
	for /f "delims=" %%i in (!original_path_quoted!) do SET original_basename=%%~ni
)

:: if file
FOR %%i IN (!original_path_quoted!) DO IF NOT EXIST %%~si\NUL (
	for /f "delims=" %%i in (!original_path_quoted!) do SET original_basenameWithExt=%%~nxi
)


for /D %%i in ("%inputed_target_dir%") do SET target_drive=%%~di
for /D %%i in ("%inputed_target_dir%") do SET target_dir=!target_drive!%%~pi

@echo on
:: if directory
FOR %%i IN (!original_path_quoted!) DO IF EXIST %%~si\NUL (
	rmdir "!inputed_target_dir!\%%~ni"
	mklink /D "!target_dir!\!original_basename!" !original_path_quoted!
	)

:: if file
FOR %%i IN (!original_path_quoted!) DO IF NOT EXIST %%~si\NUL (
	del /P "!inputed_target_dir!\%%~nxi"
	mklink "!target_dir!\!original_basenameWithExt!" !original_path_quoted!
	)
)

pause
endlocal

Aacini wrote:
10 Sep 2020 20:02
The problem with special Batch-file characters (like ! % & < > |) is very well known... I suggest you to list the problematic file names and post the Batch-file script you have problems with.
Basically any file/folder with one of these characters. For example: a folder named !backup or a file named this&that. There are basically endless combinations where these characters show up. The batch script removes these characters and as a result the symlink points to a non-existing file/folder.

Re: A problem with symlink script

Posted: 13 Sep 2020 15:39
by pieh-ejdsch
Hi absolutelyrandom1234,
Is always problematic if the delayed variables are taken in the For-loop - but work is still delayed in "do".
All that comes out is gibberish. Mixing the delayed- with forvariables can be done if there are no special characters to be expected.
Always work with a delay in "in" and if problematic special characters are to be expected, this delayedExpansion must first be deactivated in "do".
Before the variables are declared again or comparisons take place.
It is also possible to work with a call, which means that the delay is no longer applicable - but that only works in very few cases.
If you are looking for batches that use drag and drop correctly, you should search for "drag and drop files".
There are tons of versions and approaches of such batches to transfer files orally.

This version has been modified a little and throws every file/folder onto the disk to match. I removed the unnecessary creation of variables.
If it has become illegible as a result, I may be tortured or forgiven.

Code: Select all

::  ================================================================== ::
::  ========================  Puvox.Software  ======================== ::
::  ================================================================== ::
::  ============== Symlink Creator with Drag&Drop v1.3 =============== ::
::  ======= This script makes a symlink of any files/folders ========= ::
::  ========= ( instructions at:  https://goo.gl/8vYCDT  ) =========== ::
::  ================================================================== ::
::  ================================================================== ::
 @rem has been reworked a bit
@echo off
setlocal enableextensions

if "%~1"=="" echo usage: drag and Drop Files to %0 & pause & exit /b 1
set "setMethod="
set /p inputedTargetDir= Path to folder, wherein the symlink will be created: ||goto :end
if ' lss ! setlocal enabledelayedexpansion
for /f eol^=^:delims^=^" %%T in ("!inputedTargetDir!") do (
 if ! lss ' endlocal
 if exist "%%~T\" ( call  :DragAndDropFiles
 ) else goto :end
)

echo done
:end
pause
exit /b

:DragAndDropFiles ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
@echo off
@set prompt=$g$s
if ! lss ' (setlocal disabledelayedexpansion) else setlocal
if : == so * what can i do & ( 
DragAndDropFiles 
Drag and drop files/folders through a batch file
the first two lines are skipped because only the cmd calls the batch there.
Quotation marks are included in the variable so that the forLoop recognizes
the variable as a string and not as a file.
Is also required to insert the line break into the variable.
In the for /f loop, all files are output line by line.
So the batch runs without goto.
)
( set \n=^^^
%= The empty line 2 is critical - DO NOT REMOVE =%
)
if ' lss ! setlocal enabledelayedexpansion
set drag="!cmdcmdline!"
set "drag=!drag: "=%\n%
 "!"
for /f skip^=2eol^=^:tokens^=1-2delims^=^" %%A in (!drag:" ="%\n%
!) do ( if ! lss ' endlocal
 set withoutQ="%%A"
 set quoted="%%B"
 setlocal enabledelayedexpansion
 for /f eol^=^:delims^=^" %%c in (!quoted!!withoutQ:^ ^=%\n%
!) do ( if ! lss ' endlocal
  set "NO="
  if NOT defined setmethod call :Linkmethod notDefault
  if /i "%%~dpc" == "%%~T\" (set prefix="-symlinked-") else set prefix=""
  if exist "%%c\" ( rem Folder "%%c"
   IF defined NOTdefault ( set linkOption="/J"
   ) ELSE set linkOption="/D"
  ) else if exist "%%c" ( rem -file- "%%c"
   if defined NOTdefault ( set linkOption="/H"
   ) ELSE set linkOption="" 
  ) else >&2 echo NOT found "%%c" & "set NO=1"
  if Not defined NO (
   if ' lss ! setlocal enabledelayedexpansion
   for /f "tokens=1,2" %%o in ("!linkOption! !prefix!") do (
    if ! lss ' endlocal
    mklink %%~o "%%~T\%%~p%%~nxc" "%%c"
   )
  )
 )
)
exit /b

:LinkMethod
set setmethod=1
set "NOTdefault="
 rem ::   If same drives, then allow user to choose HARD method. Otherwise, only SOFT can be used
for %%. in (.) do if /i "%%~dc" == "%%~dT" (
 >&3 echo  source and Destinaton drives are same, so you have an opportunity to  
 call :YesNo "create HARD-SYMLINK press " ", default SOFT-SYMLINK press "
 if errorlevel 1 set notDefault=1
)
exit /b


:YesNo Yes No query: [message]Y [message]N
setlocal
set "y=0"
for /f "eol=0 tokens=3,4,6delims=(/) " %%a  in (
 '"echo n|xcopy /L /-y %windir%\win.ini %windir%\system.ini"'
) do ( <nul set/p"=%~1[%%a]%~2[%%b]%%c "
 xcopy /Lpy "%~f0" nul:\* |findstr /b [1-9] >nul && (set /a "y=1" &echo %%a) || echo %%b
)
exit /b %y%

Re: A problem with symlink script

Posted: 14 Sep 2020 12:02
by tonymatthews3090
Hello pieh-ejdsch!
The script works flawlessly! I have tested it with files and folders that have those special characters and all of them are properly processed. Massive THANK YOU :!:

There are two things that I have already noticed, that might move the script forward:
  • It is not possible to create a symlink for a file/folder in a location where a file/folder with that name already exists. It says that it is not possible to create a file that already exists. Would it be possible to introduce a possibility for the script to ask user if it is OK to remove the file/folder in the inputedTargetDir in order to create a symlink there?
  • Which part of the script shall be commented-out/removed in order to skip asking about HARD/SOFT-symlinking? I am going to use soft-symlinking only and I would like to skip that question showing up with each use of the script.