Search code examples
batch-filecopysubdirectory

Copy a specific image among several images contained in different subfolders, in a specific folder (Batch)


How can I copy a particular image to a default position? The image, in question, is located in the folder at the deepest level. The folder in question is contained in other nested subfolders (e.g. packages, themes, variants, etc...), in a tree structure. This little program should ask which directory it should go to and continue until it gets to that directory that actually contains the image needed and then copy it.

Here is the directory structure:

MainFolder
 ┗ PluginFolder
   ┗ LauncherFolder
     ┣ Cosmetics
     ┃ ┣ Default Pack
     ┃ ┃ ┗ Default Theme
     ┃ ┃ ┃ ┣ Character
     ┃ ┃ ┃ ┃ ┗ Chara.png
     ┃ ┃ ┃ ┗ Launcher
     ┃ ┃ ┃   ┗ Launcher.png
     ┃ ┃ ┃
     ┃ ┗ Pack 1
     ┃ ┃ ┣ Default Theme
     ┃ ┃ ┃ ┣ Character
     ┃ ┃ ┃ ┃ ┣ Chara_A.png
     ┃ ┃ ┃ ┃ ┗ Chara_A1.png
     ┃ ┃ ┃ ┗ Launcher
     ┃ ┃ ┃   ┗ Launcher_1.png
     ┃ ┃ ┃
     ┃ ┃ ┣ NW Theme
     ┃ ┃ ┃ ┣ Default
     ┃ ┃ ┃ ┃ ┣ Character
     ┃ ┃ ┃ ┃ ┃ ┗ Chara_B.png
     ┃ ┃ ┃ ┃ ┗ Launcher
     ┃ ┃ ┃ ┃   ┣ Launcher_2.png
     ┃ ┃ ┃ ┃   ┗ Launcher_2b.png
     ┃ ┃ ┃ ┃  
     ┃ ┃ ┃ ┗ Alternative 1
     ┃ ┃ ┃   ┣ Character
     ┃ ┃ ┃   ┃ ┣ Chara_C.png
     ┃ ┃ ┃   ┃ ┗ Chara_C3.png
     ┃ ┃ ┃   ┗ Launcher
     ┃ ┃ ┃     ┣ Launcher_3.png
     ┃ ┃ ┃     ┗ Launcher_3c.png
     ┃ ┃ ┃     
     ┃ ┃ ┗ SW Theme
     ┃ ┃ ┃ ┣ Character
     ┃ ┃ ┃ ┃ ┣ Chara_E.png
     ┃ ┃ ┃ ┃ ┗ Chara_F.png
     ┃ ┃ ┃ ┗ Launcher
     ┃ ┃ ┃   ┣ Launcher_4.png
     ┃ ┃ ┃   ┗ Launcher_5.png
     ┃ ┃ ┃   
     ┣ Chara.png
     ┗ Launcher.png

This script is located in the MainFolder. The Cosmetics folder contains the Packs (for this example I put 2 but they can increase). The "png-searching" should start from here. Inside each Pack folder are Themes, and inside each one can be an Alternative Version. And finally we have the Character folder and the Launcher folder. The objective, as I said before, is to choose an image from those available in the Cosmetics directory and override the image (either Chara or Launcher) in the LauncherFolder with that. But to do that I have to direct the script to that specific png first. Then, after copying it, delete the old one and rename the new one.

Someone can help?


Solution

  • There needs to be created first the folders and files for developing and testing the batch file for this menu driven file copying task according to the user´s decisions. The following batch file creates the directory structure and the PNG files which of course are not really portable network graphic image files, but text files with file extension .png.

    @echo off
    setlocal EnableExtensions DisableDelayedExpansion
    set "BaseFolder=C:\Temp"
    md "%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Default Pack\Default Theme\Character"
    md "%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Default Pack\Default Theme\Launcher"
    md "%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\Default Theme\Character"
    md "%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\Default Theme\Launcher"
    md "%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\NW Theme\Default\Character"
    md "%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\NW Theme\Default\Launcher"
    md "%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\NW Theme\Alternative 1\Character"
    md "%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\NW Theme\Alternative 1\Launcher"
    md "%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\SW Theme\Character"
    md "%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\SW Theme\Launcher"
    echo "%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Default Pack\Default Theme\Character\Chara.png">"%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Default Pack\Default Theme\Character\Chara.png"
    echo "%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Default Pack\Default Theme\Launcher\Launcher.png">"%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Default Pack\Default Theme\Launcher\Launcher.png"
    echo "%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\Default Theme\Character\Chara_A.png">"%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\Default Theme\Character\Chara_A.png"
    echo "%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\Default Theme\Character\Chara_A1.png">"%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\Default Theme\Character\Chara_A1.png"
    echo "%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\Default Theme\Launcher\Launcher_1.png">"%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\Default Theme\Launcher\Launcher_1.png"
    echo "%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\NW Theme\Default\Character\Chara_B.png">"%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\NW Theme\Default\Character\Chara_B.png"
    echo "%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\NW Theme\Default\Launcher\Launcher_2.png">"%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\NW Theme\Default\Launcher\Launcher_2.png"
    echo "%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\NW Theme\Default\Launcher\Launcher_2b.png">"%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\NW Theme\Default\Launcher\Launcher_2b.png"
    echo "%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\NW Theme\Alternative 1\Character\Chara_C.png">"%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\NW Theme\Alternative 1\Character\Chara_C.png"
    echo "%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\NW Theme\Alternative 1\Character\Chara_C3.png">"%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\NW Theme\Alternative 1\Character\Chara_C3.png"
    echo "%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\NW Theme\Alternative 1\Launcher\Launcher_3.png">"%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\NW Theme\Alternative 1\Launcher\Launcher_3.png"
    echo "%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\NW Theme\Alternative 1\Launcher\Launcher_3c.png">"%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\NW Theme\Alternative 1\Launcher\Launcher_3c.png"
    echo "%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\SW Theme\Character\Chara_E.png">"%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\SW Theme\Character\Chara_E.png"
    echo "%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\SW Theme\Character\Chara_F.png">"%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\SW Theme\Character\Chara_F.png"
    echo "%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\SW Theme\Launcher\Launcher_4.png">"%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\SW Theme\Launcher\Launcher_4.png"
    echo "%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\SW Theme\Launcher\Launcher_5.png">"%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Cosmetics\Pack 1\SW Theme\Launcher\Launcher_5.png"
    echo "%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Chara.png">"%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Chara.png"
    echo "%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Launcher.png">"%BaseFolder%\MainFolder\PluginFolder\LauncherFolder\Launcher.png"
    endlocal
    

    The batch file for copying the PNG files is much more complex, especially when it should work with really all possible file and folder names with a space or one of these characters %&()[]{}^=;!'+,`~.

    @echo off
    setlocal EnableExtensions DisableDelayedExpansion
    set "TargetFolder=%~dp0PluginFolder\LauncherFolder"
    set "Workingfolder=%~dp0PluginFolder\LauncherFolder\Cosmetics"
    
    if exist "%WorkingFolder%\" goto CheckChoice
    echo(
    echo ERROR: Folder "%WorkingFolder%" does not exist!
    echo(
    pause
    exit /B 2
    
    :CheckChoice
    if exist %SystemRoot%\System32\choice.exe goto InitEnvironment
    echo(
    echo ERROR: The file "%SystemRoot%\System32\choice.exe" does not exist!
    echo        This batch script cannot be used without executable choice.
    echo(
    pause
    exit /B 3
    
    :InitEnvironment
    rem Delete all environment variables of which name starts with character #.
    for /F "delims==" %%I in ('set # 2^>nul') do set "%%=I"
    rem Initial number of PNG files in the Character or Launcher folder.
    set "FileCount=0"
    rem Initial number of subfolders in a pack or themes folder.
    set "FolderCount=0"
    rem A list of keys assigned to the files/folders whereby the first character
    rem is just a dummy to have first choice key character at character index 1.
    set "KeysList=#1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    rem The value below must be the number of keys listed above minus one.
    rem This value determines also the maximum number of files/folders
    rem from which the user can choose a file/folder.
    set "MaxKeys=36"
    
    rem Let the user choose a pack and next a theme folder.
    call :GetFolder pack || exit /B
    call :GetFolder theme || exit /B
    rem Let the user choose between default or an alternative if the
    rem theme folder does not contain already the "Character" folder.
    if not exist "%WorkingFolder%\Character\" call :GetFolder alternative || exit B
    
    if exist "%WorkingFolder%\Character\" goto CharacterFiles
    echo(
    echo ERROR: There is no folder "Character" in the folder:
    echo        "%WorkingFolder%"
    echo(
    pause
    exit /B 2
    
    :CharacterFiles
    if exist "%WorkingFolder%\Character\*.png" goto LauncherFolder
    echo(
    echo ERROR: There is no PNG file in the character folder:
    echo        "%WorkingFolder%\Character"
    echo(
    pause
    exit /B 1
    
    :LauncherFolder
    if exist "%WorkingFolder%\Launcher\" goto LauncherFiles
    echo(
    echo ERROR: There is no folder "Launcher" in the folder:
    echo        "%WorkingFolder%"
    echo(
    pause
    exit /B 2
    
    :LauncherFiles
    if exist "%WorkingFolder%\Launcher\*.png" goto CopyFiles
    echo(
    echo ERROR: There is no PNG file in the launcher folder:
    echo        "%WorkingFolder%\Launcher"
    echo(
    pause
    exit /B 1
    
    :CopyFiles
    call :CopyFile character Chara
    call :CopyFile launcher Launcher
    rem Exit the batch file after copying the two PNG files.
    exit /B 0
    
    
    :GetFolder
    rem Set up a new local environment for the subroutine GetFolder.
    setlocal
    rem Change the current working directory to the working folder.
    pushd "%WorkingFolder%"
    rem Search for non-hidden folders in the current working directory
    rem and create a list of folder names with counting the folders.
    rem Folders with an exclamation mark in name are supported too.
    for /D %%I in (*) do (
        set /A FolderCount+=1
        setlocal EnableDelayedExpansion
        for %%J in (!FolderCount!) do (
            endlocal
            set "#Folder%%J=%%I"
            if %%J == %MaxKeys% popd & goto FolderMenu
        )
    )
    popd
    rem Is there only one folder in the current working folder?
    if %FolderCount% == 1 goto SelectFolder
    if %FolderCount% == 0 goto NoFolder
    
    :FolderMenu
    echo(
    echo Available %1 folders:
    echo(
    rem Set up an environment with enabled delayed variable expansion for the menu.
    setlocal EnableDelayedExpansion
    for /L %%I in (1,1,%FolderCount%) do echo   !KeysList:~%%I,1! ... !#Folder%%I!
    echo(
    %SystemRoot%\System32\choice.exe /C !KeysList:~1,%FolderCount%! /N /M "Your choice:"
    if not errorlevel 1 goto FolderMenu
    set "WorkingFolder=!WorkingFolder!\!#Folder%ERRORLEVEL%!"
    rem End the environment with enabled delayed variable expansion for the
    rem menu and next the local environment of the subroutine with passing
    rem twice the extended working folder path to the previous environment.
    endlocal & set "WorkingFolder=%WorkingFolder%"
    endlocal & set "WorkingFolder=%WorkingFolder%"
    exit /B 0
    
    :SelectFolder
    rem Select the single available folder automatically without user prompt.
    endlocal & set "WorkingFolder=%WorkingFolder%\%#Folder1%"
    exit /B 0
    
    :NoFolder
    endlocal
    echo(
    echo ERROR: There is no %1 folder in the folder:
    echo        "%WorkingFolder%"
    echo(
    pause
    exit /B 2
    
    
    :CopyFile
    rem Set up a new local environment for the subroutine CopyFile.
    setlocal
    rem Change the current working directory to the working folder as defined
    rem by the environment variable WorkingFolder and the folder name passed
    rem as first argument to the subroutine CopyFile.
    pushd "%WorkingFolder%\%1"
    rem Search for non-hidden PNG files in the current working directory
    rem and create a list of file names with counting the files.
    rem Files with an exclamation mark in name are supported too.
    for %%I in (*.png) do (
        set /A FileCount+=1
        setlocal EnableDelayedExpansion
        for %%J in (!FileCount!) do (
            endlocal
            set "#File%%J=%%I"
            if %%J == %MaxKeys% goto FileMenu
        )
    )
    rem Is there more than one file in the current working folder?
    if not %FileCount% == 1 goto FileMenu
    
    rem Copy the single available PNG file to the target directory with file name
    rem as defined by the second argument string passed the subroutine GetFile.
    copy /B /Y "%#File1%" "%TargetFolder%\%2.png" >nul
    rem Restore the initial environment as on call of this subroutine.
    popd
    endlocal
    goto :EOF
    
    :FileMenu
    echo(
    echo Available %1 files:
    echo(
    rem Set up an environment with enabled delayed variable expansion for the menu.
    setlocal EnableDelayedExpansion
    for /L %%I in (1,1,%FileCount%) do echo   !KeysList:~%%I,1! ... !#File%%I!
    echo(
    %SystemRoot%\System32\choice.exe /C !KeysList:~1,%FileCount%! /N /M "Your choice:"
    if not errorlevel 1 goto FileMenu
    copy /B /Y "!#File%ERRORLEVEL%!" "!TargetFolder!\%2.png" >nul
    rem Restore the initial environment as on call of this subroutine.
    endlocal
    popd
    endlocal
    goto :EOF
    

    Please read the comment lines beginning with command rem to get a brief description on how this batch file works.

    The batch file processing can be exited with four different exit codes:

    • 0 ... no error.
    • 1 ... no PNG file in user selected Character or Launcher folder.
    • 2 ... a folder is missing in the directory structure selected by the user.
    • 3 ... the Windows command CHOICE is not available as it is the case by default on Windows XP.

    The batch file processing is always paused on an error before exiting because of the batch file is mainly used by a user with double clicking on the batch file and not called by another batch file or run from within an already opened command prompt window.

    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.

    • echo /?
    • endlocal /?
    • setlocal /?
    • set /?
    • if /?
    • goto /?
    • pause /?
    • exit /?
    • call /?
    • rem /?
    • copy /?
    • choice /?
    • pushd /?
    • popd /?

    There should be read additionally the following pages for a full understanding of the command lines in the batch file.