How to get file name of an icon file in a folder for creating/updating desktop.ini for folder(s)?

后端 未结 1 1026
长情又很酷
长情又很酷 2020-12-21 09:30

I need help returning the file name of a file located in a folder.

I have read other questions asked a few times and the answer seems to be:

for /d %         


        
相关标签:
1条回答
  • 2020-12-21 10:09

    Here is a fully commented batch code for creating or updating desktop.ini for a folder icon and optionally also for folder type for either a specified folder or all folders in root of current drive (or current directory with deleting/commenting a single line).

    Creating a desktop.ini is quite simple as it can be seen by looking on code. Updating an existing INI file to replace lines or add them if necessary in correct section is much more difficult on using only internal commands of Windows command processor cmd.exe which is not designed for such tasks.

    @echo off
    
    rem CreateDesktopIni.bat [FolderName | FolderType] [FolderType]
    
    rem This batch file can be started without any parameter to create or
    rem update desktop.ini for all subfolders in root of current drive or
    rem current working directory with removing or commenting one line in
    rem code below, see comment below label AllFolders.
    
    rem But the batch file can be also started with a folder name
    rem to create or update file desktop.ini of this folder only.
    
    rem Optionally it is possible to specify as only parameter a folder type
    rem or append as second parameter after folder name the folder type.
    
    rem The folder type can be one of the following strings (not verified):
    
    rem CommonDocuments, Contacts, Documents, Music, MusicAlbum, MusicArtist,
    rem MusicIcons, MyDocuments, MyMusic, MyPictures, MyVideos, PhotoAlbum,
    rem Pictures, UseLegacyHTT, VideoAlbum, Videos
    
    setlocal EnableExtensions DisableDelayedExpansion
    set "FolderType=%~2"
    
    rem Define the subfolder containing the icon for the folder.
    set "IconFolder=Icon"
    
    rem Is the batch file called with at least one parameter?
    if "%~1" == "" goto AllFolders
    
    rem Yes! It could be a folder name or the folder type.
    if not exist "%~1" set "FolderType=%~1" & goto AllFolders
    
    rem First parameter specifies a folder (most likely as not verified).
    set "Folder=%~1"
    rem Remove trailing backslash if there is one.
    rem The batch file should not be called with just \ as folder path.
    if "%Folder:~-1%" == "\" set "Folder=%Folder:~0,-1%"
    
    rem Call subroutine to create or update the desktop file for this folder.
    call :DesktopINI "%Folder%"
    goto EndBatch
    
    :AllFolders
    rem Change working directory to root of current drive. Remove or comment
    rem the next line to process instead all subfolders in current directory.
    cd \
    rem Call subroutine to create/update the desktop file for each subfolder.
    for /F "eol=| delims=" %%I in ('dir /AD /B 2^>nul') do call :DesktopINI "%%I"
    goto EndBatch
    
    
    rem Subroutine to create or update the desktop file for a folder.
    
    rem This subroutine first searches for the icon file and does nothing
    rem if no icon file could be found in the defined subfolder because
    rem the subfolder does not exist at all or there is no *.ico file.
    
    rem After determining the icon file (first found *.ico file) with full path
    rem including drive letter (remove character d for relative path without
    rem drive letter in line with %%~dpnxI), this subroutine checks next for
    rem existence of file desktop.ini (case-insensitive) in current folder.
    
    rem desktop.ini with the two or three lines is simply created if this file
    rem does not already exist and the user of the batch file has permissions
    rem to create this file in the current folder.
    
    rem For an already existing desktop.ini the necessary process to update it
    rem is much more complex. All lines outside the section [.ShellClassInfo]
    rem must be kept and are therefore just copied to a temporary file, except
    rem empty lines ignored by command FOR. Also all lines within the section
    rem [.ShellClassInfo] not starting with the string IconFile= or optionally
    rem FolderType= (both case-insensitive) must be also simply kept by copying
    rem them to the temporary file.
    
    rem An existing line starting with IconFile= in section [.ShellClassInfo]
    rem is not copied to temporary file, but instead this line is written to
    rem the temporary file with determined icon file name with path.
    
    rem An existing line starting with FolderType= in section [.ShellClassInfo]
    rem is also not copied to temporary file, but instead this line is written
    rem to the temporary file with folder type as specified on starting batch.
    
    rem If section [.ShellClassInfo] was found and beginning of a new section is
    rem detected because of a line starting with an opening square bracket and
    rem the line with IconFile= and/or the line with FolderType= was not found
    rem in this section during processing the existing desktop.ini, the lines
    rem are written next to temporary file to insert them before continuing
    rem with the next section.
    
    rem Finally it could happen that section [.ShellClassInfo] is missing in
    rem existing desktop.ini and must be therefore added to the file. And it
    rem could be that this section exists at end of desktop.ini, but either
    rem the line with IconFile= or with FolderType= or both are missing and
    rem those lines must be therefore appended to the file.
    
    rem The temporary file is next copied over the existing desktop.ini and
    rem then deleted as not further needed. Finally the system and hidden
    rem attributes are set on file desktop.ini and the system attribute is
    rem set on the current folder as otherwise desktop.ini would be ignored.
    
    :DesktopINI
    set "Folder=%~1"
    
    for %%I in ("%Folder%\%IconFolder%\*.ico") do (
        set "IconFile=%%~dpnxI"
        goto IconFound
    )
    goto :EOF
    
    :IconFound
    set "DesktopFile=%Folder%\desktop.ini"
    
    if not exist "%DesktopFile%" (
        echo [.ShellClassInfo]>"%DesktopFile%"
        if not exist "%DesktopFile%" goto :EOF
        echo Iconfile=%IconFile%>>"%DesktopFile%"
        if defined FolderType echo FolderType=%FolderType%>>"%DesktopFile%"
        %SystemRoot%\System32\attrib.exe +h +s "%DesktopFile%"
        %SystemRoot%\System32\attrib.exe +s "%Folder%"
        goto :EOF
    )
    
    set "IconLine="
    set "ShellClassInfo="
    set "UpdateComplete="
    set "TempFile=%TEMP%\Desktop.tmp"
    if exist "%TempFile%" del /F "%TempFile%"
    if not defined FolderType (set "TypeLine=1") else set "TypeLine="
    %SystemRoot%\System32\attrib.exe -h -s "%DesktopFile%"
    
    (for /F "usebackq delims=" %%L in ("%DesktopFile%") do (
        set "LineOutput="
        if defined ShellClassInfo (
            for /F "delims==" %%V in ("%%L") do (
                if /I "%%V" == "IconFile" (
                    echo Iconfile=%IconFile%
                    set "IconLine=1"
                    set "LineOutput=1"
                ) else if /I "%%V" == "FolderType" (
                    if defined FolderType (
                        echo FolderType=%FolderType%
                        set "TypeLine=1"
                        set "LineOutput=1"
                    )
                ) else (
                    set "NewSection=1"
                    for /F "eol=[" %%G in ("%%V") do set "NewSection="
                    if defined NewSection (
                        if not defined IconLine echo Iconfile=%IconFile%
                        if not defined TypeLine echo FolderType=%FolderType%
                        set "ShellClassInfo="
                        set "UpdateComplete=1"
                    )
                )
            )
        ) else if /I "%%L" == "[.ShellClassInfo]" (
            echo [.ShellClassInfo]
            set "ShellClassInfo=1"
            set "LineOutput=1"
        )
        if not defined LineOutput echo(%%L
    )) >"%TempFile%"
    
    if not defined UpdateComplete if not defined ShellClassInfo (
        echo [.ShellClassInfo]>>"%TempFile%"
        set "ShellClassInfo=1"
    )
    
    if defined ShellClassInfo (
        if not defined IconLine echo Iconfile=%IconFile%
        if not defined TypeLine echo FolderType=%FolderType%
    ) >>"%TempFile%"
    
    move /Y "%TempFile%" "%DesktopFile%" >nul
    if exist "%TempFile%" del "%TempFile%"
    
    %SystemRoot%\System32\attrib.exe +h +s "%DesktopFile%"
    %SystemRoot%\System32\attrib.exe +s "%Folder%"
    goto :EOF
    
    :EndBatch
    endlocal
    

    It is advisable to remove all comments which are the lines starting with command rem for faster processing of the batch file.

    The command line cd \ must be removed or commented out if the batch file should process all subfolders of the current folder on starting the batch file instead of the subfolders of the current drive.

    The DIR option /S can be appended to dir /AD /B to process the entire directory tree of current folder or current drive on start of this batch file.

    The environment variable IconFolder can be defined with just . instead of Icon to search for first *.ico file in the folder itself instead of a subfolder Icon.

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

    • attrib /?
    • call /?
    • cd /?
    • del /?
    • dir /?
    • echo /?
    • endlocal /?
    • for /?
    • goto /?
    • if /?
    • move /?
    • rem /?
    • set /?
    • setlocal /?

    Read the Microsoft article about Using command redirection operators for an explanation of > and >> and 2>nul. The redirection operator > must be escaped with caret character ^ on FOR command line with 2^>nul 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 in a separate command process started in background.

    0 讨论(0)
提交回复
热议问题