batch-filecmd

CMD AutoRun hang


I am working on a program that hooks into CMD using a doskey macro. I want to set up that macro using a for /f loop to run the output of my program in an AutoRun script file.

I golfed the code in question down to

FOR /f "delims=" %%i in ('echo echo hi') do %%i

The command works when typing it into the CMD window directly. It also works when putting it into a file and running it using CALL script.cmd.

But when I automatically load that file using the Registry key "Computer\HKEY_CURRENT_USER\Software\Microsoft\Command Processor" AutoRun, CMD hangs when starting (the HDD LED flashes wildly in the process). When pressing CTRL+C in that situation loads of ^s and Cs are written to the CMD window (screens full of them) and some The process tried to write to a nonexistent pipe. mixed in.

I suspected the Windows Defender virus scanner, but disabling it didn't change much.

What can I do?

I am on Windows 10. (Version 1803, OS build 17134.885)


Solution

  • The problem is, FOR /F starts a new instace of cmd.exe and that instance also starts your auto run script, this can result into an endless loop.

    You can't avoid the start of the script itself, but the script can detect if it was called by a FOR /F or directly.
    I check the cmdcmdline variable if it contains an option (searching for a slash).
    The value of the cmdcmdline variable should always be copied, else you would modify the variable with the expression !cmdcmdline:/=! !

    Btw. a pipe starts a new instance, too, but it doesn't start the auto run script.

    @echo off
    setlocal EnableDelayedExpansion EnableExtensions
    set "cmd=!cmdcmdline!"
    
    if "!cmd!" == "!cmd:/=!" (
      REM *** Stuff for AutoRun in interactive mode
      REM *** Loading doskey macros
      %SystemRoot%\System32\doskey.exe /macrofile=myMacros.txt
    
      REM *** Restore to original environment
      endlocal
    
      REM *** Changing the directory
      cd /d c:\temp
    
      REM *** Set some etxra default variables
      SET "PRJ=C:\myProjects"
    ) ELSE (
      REM *** Restore to original environment
      endlocal
    )