1

The code below should archive some files by moving them into a subfolder. The batch file asks the user for the folder path. Then a subfolder should be created and if that was successful, it should move all files in the user input directory into the subdirectory. It works, but it closes although using pause. It does not output anything about a syntax error or anything at all. Please let me know if somebody notices something.

@echo off

SETLOCAL EnableDelayedExpansion

echo Insert path: 
set /p path=
echo the path is %path%
cd %path%

echo The files will be moved to a new folder
pause
mkdir %path%\archived_files
IF EXIST "archived_files" ( 
    for /f %%A in ('DIR /A /D /B') do (
        echo %%A && move /Y %path%\%%A %path%\archived_files) 
    echo Folder "archived_files" created or already exists
) else ( echo Folder "archived_files" does not exist )

echo the files have been transferred

pause
ENDLOCAL
Mofi
  • 46,139
  • 17
  • 80
  • 143
  • 2
    Never, ever use `path` as a user-variable. It's a "magic variable" set by the operating system that tells windows where to look for executables that are not located in the current directory. Use another name. – Magoo Jan 21 '21 at 23:43
  • 3
    The first step to debugging batch scripts is to delete the `@echo off` line and running it to see what it does. The second step is to remember that `%PATH%` is a system variable and you should never change its value unless you know what you're doing. – SomethingDark Jan 21 '21 at 23:44
  • One of the best ways to debug your file is to check the usage information for each of the commands it uses. You can do that by invoking those commands with their built-in help argument. Please open a Command Prompt window, type `dir /?` and read the presented information. You should note that you very likely do not want to list files in wide column sorted format, `/D`, and more likely wished to output content which did not carry a directory attribute instead, i.e. `/A` with `-D`. For example `DIR /A:-D /B`, or `DIR /A-D /B`. You can do that similarly with `cd /?`, which also has a `/D` option. – Compo Jan 22 '21 at 03:45
  • ... and of course: don't execute it by "doubleclicking". Open a `cmd` window and start it from there. This way, the Window will stay open, enabling you to read any errormessages. – Stephan Jan 22 '21 at 07:22
  • Thank you all, I made the changes and I found the error – helpmypoorsoul Jan 22 '21 at 19:31

1 Answers1

1

I suggest to use this batch file for the file moving task.

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "BatchFileName=%~nx0"
set "BatchFilePath=%~dp0"
set "UserPath=%~1"
if defined UserPath goto ChangeFolder
:UserPrompt
set "UserPath="
set /P "UserPath=Enter path: "
rem Has the user not entered a string?
if not defined UserPath goto UserPrompt
rem Remove all double quotes from input string.
set "UserPath=%UserPath:"=%"
rem Has the user entered just one or more double quotes?
if not defined UserPath goto UserPrompt
:ChangeFolder
pushd "%UserPath%" 2>nul || (echo Folder "%UserPath%" does not exist.& goto UserPrompt)
for /F "eol=| delims=" %%I in ('dir /A-D /B 2^>nul') do goto CreateSubfolder
echo The folder does not contain any file to archive.& goto EndBatch
:CreateSubfolder
md "archived_files" 2>nul
if not exist "archived_files\" echo Failed to create subfolder: "archived_files"& goto EndBatch
rem It must be avoided that the currently running batch file is moved too.
set "ExcludeFileOption="
for %%I in ("%UserPath%\") do set "CurrentFolderPath=%%~dpI"
if "%CurrentFolderPath%" == "%BatchFilePath%" set "ExcludeFileOption= /XF "%BatchFileName%""
rem The command MOVE used with wildcard * does not move hidden files. A FOR loop
rem with MOVE is slow in comparison to usage of ROBOCOPY to move really all files.
rem The ROBOCOPY option /IS can be removed to avoid moving same files existing
rem already in the subfolder archived_files from a previous batch execution.
echo The files are moved to a new folder.
%SystemRoot%\System32\robocopy.exe . archived_files%ExcludeFileOption% /MOV /R:2 /W:5 /IS /NDL /NFL /NJH /NJS
if not errorlevel 2 if errorlevel 1 echo All files are moved successfully.
:EndBatch
popd
endlocal
pause

The batch file can be started with a a folder path as argument. So it is possible to right click on the batch file and click in opened context menu in submenu Send to on item Desktop (create shortcut). The .lnk file created on the user´s desktop can be renamed now also via context menu or key F2 to whatever name is useful like Archive files. Then the shortcut file can be cut with Ctrl+X and pasted with Ctrl+V in the folder %APPDATA%\Microsoft\Windows\SendTo to have in Send to context submenu the menu item Archive files. This makes it possible to right click on a folder and click in opened context menu in submenu Send to on Archive files to run the batch file without the need to enter a folder path manually.

The batch file prompts the user for the path if not started with a folder path as first argument or the folder cannot be found at all. This user prompt is done using a safe method. The batch file makes the passed or entered folder temporarily the current folder for the remaining commands using PUSHD and POPD instead of CD to work also with UNC paths.

There is checked next if the folder contains any file at all. Otherwise the user is informed that the directory does not contain files to archive and batch file ends without any further action.

The file movement is done with ROBOCOPY for the reasons described in a remark in the batch file which requires Windows Vista or a newer Windows version or Windows Server 2003 or a newer Windows server version.

I recommend to see also:

To understand the commands used and how they work, open a command prompt window, execute there the following commands, and read the displayed help pages for each command, entirely and carefully.

  • call /? ... explains %~nx0, %~dp0 and %~1 whereby argument 0 is always the batch file itself.
  • dir /?
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • md /?
  • pause /?
  • popd /?
  • pushd /?
  • rem /?
  • robocopy /?
  • set /?
  • setlocal /?

Other useful documentations used to write this code:

Note: The redirection operator > must be escaped with caret character ^ on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded dir command line with using a separate command process started in background with %ComSpec% /c and the command line within ' appended as additional arguments.

Mofi
  • 46,139
  • 17
  • 80
  • 143