1

I noticed that some software I use, AutoDarkMode, doesn't randomize the first wallpaper it switches to, so I thought I'd write a batch file to do it by copying one wallpaper in the folder and renaming it as 0000.png or 0000.jpg.

So far I have created an array of filenames, but when I attempt to run the copy command, it does not add the extension.

@echo off

call:change D:\_Store\Backgrounds\Test
EXIT /B %ERRORLEVEL%

:change

set /a "i=0"
for %%f in (%~1\*.*) do (
    set "list[%%i%%]=%%~f"
    set /a "i+=1"
)

for %%i in (%%list[2]%%) DO (call copy %%list[2]%% %~1\0000%%~xi)

EXIT /B 0

I've tried replacing the destination filename with a variable and wrapping variable names in quotes, but I'm not a batch scripter and I'm at a bit of a loss. I've used a similar for statement in another batch file and it seems to add the extension just fine.

1
  • Well irrespective of whatever the for %%i ... line is supposed to be doing, you'd probably wish to change set "list[%%i%%]=%%~f" to call set "list[%%i%%]=%%~f". Commented Oct 8 at 1:15

1 Answer 1

1
@ECHO OFF
SETLOCAL

CALL :change "u:\your files"
EXIT /B %ERRORLEVEL%

:change

DEL "%~1\0000.*" >NUL 2>nul
set /a i=0
for %%f in ("%~1\*.*") do (
    CALL set "list[%%i%%]=%%~f"
    set /a i+=1
)

SET i
SET /a i=%RANDOM% %% i
SET i

CALL SET "i=%%list[%i%]%%"
SET i

FOR %%E IN ("%i%") DO ECHO Copy "%%~E" "%~1\0000%%~xE"
FOR %%E IN ("%i%") DO Copy "%%~E" "%~1\0000%%~xE" >nul

EXIT /B 0

Just a few changes...

Add a setlocal line after the @echo off line. This is simply good practice (but unlikely to be relevant here). Any changes to the environment (like adding new variables i and list[*]) of the cmd instance will be backed out after the batch ends. This means that these changes will not be retained from one batch if the cmd instance executes further commands.

I used a target directory u:\your files as a test (suits my system). Since this contains a space (deliberately), the string needs to be quoted. This means that the subroutine :change will see just one parameter ("u:\your files") instead of two (u:\your & files)

Quotes are not required for set /a - only for string-assignment set statements.

Delete the current 000.* file(s), otherwise if 0000.jpg already exists, then if 0000.png is created, the change won't be visible,as apparently only the very first file will be displayed (from your description)

The name in the list processed by %%f needs to be quoted (because the path contains a space) so the standard method is to quote the entire string (making it a single entity) and remove the quotes from %1 by using %~1.

Need to CALL the set list... What this does is to replace the %%i%%with the value of i.

Note the set i instructions. This is merely to display the value of i as it changes for edification and can be removed. Actually set i displays the setting of all variables starting i - it's an easier way of implementing echo i=%i%

So the first i is the count of entries of the form list[*]. Then set i to a random number mod i yielding a random number 0..i-1, and the list entries are list[0]..list[i-1] :)

Using this, set i again to the contents of list[randomisednumber] giving a random name

The first for %%E line is simply to display the intended action and can be deleted after testing.

The second creates the new file and job done.

Note that >NUL & 2>nul directives suppress command responses and error-reports respectively.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for this and the detailed description. I was going to add the DEL and random number in later, but I got stuck on the copy command.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.