Hashim Hashim - 1 month ago 15
Bash Question

What are these lines of batch code for?

I came across the following batch code on SuperUser, the purpose of which is to programmatically replace a folder's icon.

CD "%userprofile%\desktop"
MKDIR "TEST FOLDER"
ATTRIB +s "TEST FOLDER"
CD "TEST FOLDER"
COPY /Y "%userprofile%\desktop\image.ico" "./image.ico"
ECHO [.ShellClassInfo] >> desktop.txt
ECHO ConfirmFileOp=0 >> desktop.txt
ECHO NoSharing=1 >> desktop.txt
ECHO IconFile=image.ico >> desktop.txt
ECHO IconIndex=0 >> desktop.txt
ECHO InfoTip= >> desktop.txt
CHCP 1252 >NUL
CMD.EXE /D /A /C (SET/P=ÿþ)<NUL > desktop.ini 2>NUL
CMD.EXE /D /U /C TYPE desktop.txt >> desktop.ini
DEL /F /Q desktop.txt
ATTRIB +S +H desktop.ini image.ico


I get the rest of the script easily enough, but I'm having trouble understanding these three lines:

CHCP 1252 >NUL
CMD.EXE /D /A /C (SET/P=ÿþ)<NUL > desktop.ini 2>NUL
CMD.EXE /D /U /C TYPE desktop.txt >> desktop.ini


SS64 tells me
chcp 1252
is related to something called a "code page", 1252 corresponding to "West European Latin", so my best guess is that this forces the script to use a Latin character set. The second two lines open instances of CMD; SS64 says the /A switch on the first makes it output in ANSI while the /U on the second makes it output Unicode. That's about as much as I can speculate on, and I'd really appreciate it if someone could go through each major part of these three lines and tell me what they're doing.

Thanks!

Answer

In short, the code[1] :

  • creates a temporary desktop.txt file whose content will eventually become desktop.ini, but with a different encoding.

  • the commands in question then convert the current-console-codepage-encoded file desktop.txt (e.g., on an en-US system, CP-437) to UTF-16 LE-encoded file desktop.ini, which is the (culture-independent) file File Explorer uses to control display of the folder at hand.

  • sets the system (+S) and hidden (+H) attributes for both the desktop.ini file and the associated icon file, image.ico, because that's how these files should be marked (given that they only control display of the containing folder, and aren't data files themselves).

Specifically, the 3 lines of interest do the following:

  • CHCP 1252 >NUL (silently) changes to the Windows-1252 code page.

  • CMD.EXE /D /A /C (SET/P=ÿþ)<NUL > desktop.ini 2>NUL effectively sends string ÿþ to output file desktop.ini - ÿþ, when interpreted as a Windows-1252-encoded string, amounts to bytes 0xFF 0xFE, which is the BOM (byte-order mark) used to identify UTF-16 LE-encoded files; in other words: sending this string to file desktop.ini marks it as an UTF-16 LE-encoded file.

    • /D simply suppresses any auto-run functionality that may be defined via the registry
    • /A tells cmd.exe to output "ANSI"-encoded strings, where "ANSI" refers to the default codepage - which is now set to Windows-1252
    • /C means that the following arguments should be executed as a command, and that cmd.exe should exit after the command terminates.
  • CMD.EXE /D /U /C TYPE desktop.txt >> desktop.ini then appends the contents of the previously created desktop.txt file to desktop.ini, using "Unicode" (UTF-16 LE) encoding (thanks to /U), which completes the conversion of temporary file desktop.txt to UTF-16 LE-encoded desktop.ini (after which desktop.txt is removed).


[1]
This answer interprets the code's intent, which doesn't mean that it necessarily works, especially in Windows 10; for instance, interactively assigning an icon seems to set a different, single property that combines the image file and the index of its specific internal resource: e.g., IconResource=C:\Users\jdoe\Desktop\image.ico,0

As for the need to create UTF-16 LE-encoded files: it's not a strict requirement - apparently, Windows itself, when you use File Explorer to assign an icon, creates files in the current legacy - single-byte - encoding (e.g., Windows-1252).
That said, using a culture-independent encoding such as UTF-16 LE is at least in principle the most robust approach.
However, if all the values you're writing to desktop.ini are ASCII-only characters (7-bit range), it's safe to simply pipe echo output to desktop.ini directly.

At the end of the day, using a batch file to determine folder display attributes is a fragile approach, given that it is essentially based on reverse-engineering the official APIs - which may change.

More generally, using batch files to do anything is best avoided these days - use PowerShell instead.