Search code examples
batch-filecmd

How to escape spaces while Set a parameter in Bat file


I'm trying to do this:

@echo off
Set ^"Processes=Sample.exe ^
The Sample Program.exe^"

But The Sample Program.exe acting as three separate files The Sample and Program.exe.

What is the procedure to escape the spaces?

Full code:

for %%a in (%Processes%) Do (
    for /f %%b in ('tasklist /NH /FI "imagename eq %%a"') Do (
        if [%%b]==[%%a] (
            echo %%b is running
            Color 0C
            echo  Killing %%b ...
            Taskkill /f /im "%%b"
        ) else (
            Color 0A
            echo %%a is not running
        )
    )
)
pause & exit

Something along this line? for /F "tokens=1* delims=," %%b


Solution

  • A simple demonstration code for what I think you want to achieve is:

    @echo off
    setlocal EnableExtensions DisableDelayedExpansion
    set Processes="cmd.exe Windows Command Processor" "cscript.exe Console Based Script Host"
    for %%G in (%Processes%) do for /F "eol=| tokens=1*" %%H in (%%G) do (
        echo File name is: %%H
        echo Process name: %%I
    )
    endlocal
    

    The output of this batch file on execution is:

    File name is: cmd.exe
    Process name: Windows Command Processor
    File name is: cscript.exe
    Process name: Console Based Script Host
    

    So the environment variable Processes is defined with multiple strings enclosed in double quotes. Each string has first the file name of an executable without path and separated by a space (could be also a different character) the process name or whatever is needed to be associated with the executable file name which should not contain ? or *.

    The outer FOR loop assigns one after the other a string enclosed in double quotes to the specified loop variable G.

    The inner FOR loop splits up the string assigned currently to loop variable G into two substrings and assigns the first normal space/horizontal tab delimited string to specified loop variable H and everything else after one or more spaces/tabs to next but one loop variable I.

    The executable file name assigned to H and the associated string assigned to I can be used for whatever purpose in the command block of the inner FOR loop.

    This method applied to what the batch file should do:

    @echo off
    setlocal EnableExtensions DisableDelayedExpansion
    set Processes="notepad.exe Windows Notpad" "cscript.exe Console Based Script Host"
    for %%G in (%Processes%) do for /F "eol=| tokens=1*" %%H in (%%G) do (
        %SystemRoot%\System32\tasklist.exe /NH /FI "imagename eq %%H" 2>nul | %SystemRoot%\System32\find.exe /I "%%H" >nul
        if not errorlevel 1 (
            echo %%I is running.
            color 0C
            echo Terminating %%I ...
            %SystemRoot%\System32\taskkill.exe /IM "%%H" >nul
        ) else (
            color 0A
            echo %%I is not running.
        )
    )
    color
    endlocal
    

    The option /F to force a brutal kill of the running process by the operating system is removed from this code. The most applications gracefully terminate itself on TASKKILL sending the WM_CLOSE message to the running application.

    Please note that closing all instances of script interpreters like cmd.exe, cscript.exe, wscript.exe, powershell.exe as done by the TASKKILL with just image name passed as argument is in general not good. For example the cmd.exe instance currently processing the batch file would be terminated also on using this batch code to terminate a cmd.exe running with a different console window parallel.

    Example for the unusual cases of executable file names with one or more spaces with using | as delimiter between file name and associated string which no file name can contain ever:

    @echo off
    setlocal EnableExtensions DisableDelayedExpansion
    set Processes="notepad.exe|Windows Notpad" "cscript.exe|Console Based Script Host" "show time.exe|Show Time Information"
    for %%G in (%Processes%) do for /F "eol=| tokens=1* delims=|" %%H in (%%G) do (
        %SystemRoot%\System32\tasklist.exe /NH /FI "imagename eq %%H" 2>nul | %SystemRoot%\System32\find.exe /I "%%H" >nul
        if not errorlevel 1 (
            echo %%I is running.
            color 0C
            echo Terminating %%I ...
            %SystemRoot%\System32\taskkill.exe /IM "%%H" >nul
        ) else (
            color 0A
            echo %%I is not running.
        )
    )
    color
    endlocal
    

    To understand the commands used and how they work, open a command prompt window, execute there the following commands, and read the displayed help pages for each command, entirely and carefully.

    • echo /?
    • endlocal /?
    • find /?
    • for /?
    • setlocal /?
    • taskkill /?
    • tasklist /?