Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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!

like image 559
Hashim Aziz Avatar asked Oct 18 '16 22:10

Hashim Aziz


People also ask

What does %% do in batch?

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.

What is @echo off in batch script?

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.

What does %1 mean in a batch file?

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.

What does %* mean in batch?

%* 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.


1 Answers

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.

like image 80
mklement0 Avatar answered Oct 22 '22 04:10

mklement0