1

I am trying to make a bat file to sync a folder. I couldn't install WASL yet, so for now, rsync is not an option.

I wrote below code as neat as possible. Please check why it is not working? Note: On notepad++, On Encoding Menu, "UTF8" is chosen by default. And I tried to click "Convert to UTF8"; nothing happened.

Please Help!

CHCP 65001
REM @ECHO OFF

REM GLOBALS
SET V_PF=\\10.0.0.222\kalite_dokumanlar\
SET V_PT=C:\me\desk\KALİTE\

REM INIT
GOTO:F_MAIN

REM FUNCTIONS
:F_SYNC
    SETLOCAL ENABLEDELAYEDEXPANSION
        SET V_IN=%~1
        robocopy "%V_PF%%V_IN%\" "%V_PT%%V_IN%\" /MIR
    ENDLOCAL
EXIT /B 0

REM MAIN
:F_MAIN
call:F_SYNC "DESTEK"
call:F_SYNC "MÜŞTERİ ve TEDARİK"
call:F_SYNC "SİSTEM"
call:F_SYNC "ÜRETİM"

REM SAVE WITH NOTEPAD++ ENCODED UTF8 WITHOUT BOM

see the code at github

  • 2
    ENABLEDELAYEDEXPANSION but never use it? – Anders Dec 24 '21 at 11:21
  • 1
    Just to expand upon that, you are not using Unicode UTF-8 characters, those are simply Turkish characters available under OEM code page 857. So what you should do is write your batch file using that code page, and if you need to, ensure that the batch file identifies the current code page, and if it is not 857, change it to that. – Compo Dec 24 '21 at 12:06

1 Answers1

1

The directories synchronization task can be done with the following batch file:

@ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
@REM Get the current code page and remember it with the environment variable InitialCodePage.
FOR /F "tokens=*" %%I IN ('%SystemRoot%\System32\chcp.com') DO FOR %%J IN (%%I) DO SET /A "InitialCodePage=%%J" 2>NUL
@REM Change the code page to UTF-8.
%SystemRoot%\System32\chcp.com 65001 >NUL

@REM GLOBALS
SET "V_PF=\\10.0.0.222\kalite_dokumanlar\"
SET "V_PT=C:\me\desk\KALİTE\"

@REM INIT
GOTO:F_MAIN

@REM FUNCTIONS
:F_SYNC
    SET "V_IN=%~1"
    @REM /NDL /NFL: NO LOGS = NO GARBAGE CHARS CON:
    @REM /NJH /NJS: NO VERBOSE START-END 
    @REM /R:3: LIMIT RETRY 
    @REM /W:10: WAIT ON ERROR 
    %SystemRoot%\System32\robocopy.exe "%V_PF%%V_IN%" "%V_PT%%V_IN%" /MIR /R:3 /W:10
EXIT /B 0

@REM MAIN
:F_MAIN
CALL :F_SYNC "DESTEK"
CALL :F_SYNC "MÜŞTERİ ve TEDARİK"
CALL :F_SYNC "SİSTEM"
CALL :F_SYNC "ÜRETİM"

@REM Restore the initial code page.
%SystemRoot%\System32\chcp.com %InitialCodePage% >NUL
ENDLOCAL

@REM SAVE THAT CODE ENCODED UTF-8 WITHOUT BOM

The main correction is the removal of the backslashes at end of the source and destination paths on ROBOCOPY command line. %SystemRoot%\System32\robocopy.exe is different to most other Windows commands. It interprets \ left to " as an escape character for the double quote although no file/folder name can contain ever the character ". For that reason it is strongly recommended to avoid a backslash at end of the source and destination path. If that is not possible because of source or destination path is the root directory of a drive, then either the path is not enclosed in " at all or two backslashes are used at end of the path where the first backslash is escaping the second backslash to be interpreted as literal character. So working would be also:

%SystemRoot%\System32\robocopy.exe "%V_PF%%V_IN%\\" "%V_PT%%V_IN%\\" /MIR /R:3 /W:10

The usage of fully qualified file names for the executables reduces the number of file system accesses as the Windows command processor cmd.exe does not need to search for the executables in this case. The batch file becomes additionally independent on the environment variables PATH and PATHEXT with using fully qualified file names.

The commands SETLOCAL ENABLEDELAYEDEXPANSION and ENDLOCAL inside the subroutine F_SYNC are of no use and for that reason removed from the code. There are instead inserted a SETLOCAL at top and an ENDLOCAL at bottom which define completely the local execution environment required for this batch file. For more details about these two commands see my answer on
How to pass environment variables as parameters by reference to another batch file?

There is also inserted a space between the command CALL (argument 0) and the label (argument 1) to avoid two files system accesses with return value invalid file name. call:F_SYNC is interpreted first as file name of an executable or script because of the missing space. This string is interpreted a second time by cmd.exe just because of the invalid file name error returns and split up next into the two arguments call and :F_SYNC with detecting now that call is an internal command of cmd.

Mofi
  • 46,139
  • 17
  • 80
  • 143