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!
Use double percent signs ( %% ) to carry out the for command within a batch file. Variables are case sensitive, and they must be represented with an alphabetical value such as %a, %b, or %c. Required. Specifies one or more files, directories, or text strings, or a range of values on which to run the command.
batch-file Echo @Echo off @echo off prevents the prompt and contents of the batch file from being displayed, so that only the output is visible. The @ makes the output of the echo off command hidden as well.
When used in a command line, script, or batch file, %1 is used to represent a variable or matched string. For example, in a Microsoft batch file, %1 can print what is entered after the batch file name.
%* expands to the complete list of arguments passed to the script. You typically use it when you want to call some other program or script and pass the same arguments that were passed to your script.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With