1

i'm trying to loop through all installed programs:

wmic /output:C:\temp\InstallList.txt product get name

for /F "tokens=*" %%G in (C:\temp\InstallList.txt) do echo %%G

the file is created, but the output is empty!

Squashman
  • 13,649
  • 5
  • 27
  • 36
Ariel
  • 165
  • 1
  • 3
  • 15
  • 1
    Don't use WMIC and batch and use PowerShell instead. – Bill_Stewart Oct 26 '15 at 17:08
  • @Bill_Stewart Switching to PowerShell fixed my issue with a poorly written installer. The installer prompts the user for various "0 / 1 / 2" options for continue / exit / reinstall. For some reason, using `echo 1 | setup.exe` was feeding blank input to the installer when run in Windows batch / cmd.exe. However running the exact same command in PowerShell worked. Possibly a similar Unicode issue described by the other answers. – jrbe228 Feb 04 '23 at 00:15

3 Answers3

0

The output is not empty. The output is in Unicode. Use more to convert into current local encoding.

If you would like the whitespace removed from the end of the strings, see How to remove trailing and leading whitespace for user-provided input in a batch file?

setlocal enabledelayedexpansion
wmic product get name | more >"C:\temp\InstallList.txt"
for /F "skip=1 usebackq tokens=*" %%G in (`type "C:\temp\InstallList.txt"`) do (
    set S=%%G
    set S=!S:~0,-1!
    if "!S!" NEQ "" (echo !S!)
)
Community
  • 1
  • 1
lit
  • 14,456
  • 10
  • 65
  • 119
  • 1. your second line will not work, the `usebackq` option is missing! 2. your first line works, although there is going to be some noise in the output file (superfluous carriage-returns); this may cause trouble when reading (e. g., use `echo "%%G"` in your second line, then you'll notice that some closing quotes will disappear...); – aschipfl Oct 27 '15 at 20:07
  • You are right @aschipfl. I have edited the code to change the for loop as well as handle the extraneous \r that wmic emits. – lit Oct 28 '15 at 18:04
  • Thank you, @Liturgist! there is an even easier and more secure approach to get rid of the additional CRs: inside of `for /F %%G`, just place another loop `for /F "delims=" %%F in ("%%G") do echo "%%F"; so you will not need delayed expansion, and there is no risk of removing too much; – aschipfl Oct 28 '15 at 18:26
0

Could just do it all in one

FOR /F "skip=1 delims=" %%G in ('wmic product get name') do @echo %%G
Squashman
  • 13,649
  • 5
  • 27
  • 36
0

The problem is the Unicode format of the output of the wmic command. Hence your file InstallList.txt contains many 0x00 bytes which cause the for /F loop to terminate.

To work around that, capture the wmic output with a for /F loop, so it becomes converted to non-Unicode format:

@echo off
for /F "skip=1 delims=" %%G in ('
    wmic PRODUCT GET Name
') do echo %%G

The skip=1 option removes the header Name from the output.

Unfortunately, the output still contains some disturbing artefacts (in fact, there are some orphaned carriage-returns). To get rid of them, nest another for /F loop:

@echo off
for /F "skip=1 delims=" %%G in ('
    wmic PRODUCT GET Name
') do (
    for /F "delims=" %%F in ("%%G") do echo %%F
)

Of course you can parse your Unicode output file InstallList.txt with for /F, but you cannot do it directly, you need to use the type command to do the conversion to non-Unicode:

for /F "skip=1 delims=" %%G in ('
    type "C:\temp\InstallList.txt"
') do rem the rest is the same as above

You can also use the more command to achieve that, by simply writing more instead of type.


You might notice that each line returned by the echo command contains trailing spaces. If they disturb you, you might use the following code:

@echo off
setlocal EnableDelayedExpansion
set "REPL=    "
for /F "skip=1 delims=" %%G in ('
    wmic PRODUCT GET Name
') do (
    for /F "delims=" %%F in ("%%G") do (
        set "LINE=%%F%REPL%"
        set "TRNC=!LINE:*%REPL%=%REPL%!"
        call echo %%LINE:!TRNC!=%%
    )
)
endlocal

What I am doing here is:

  • to specify a sequence of spaces (4 in this example, assuming that each line contains less spaces in its part of interest) in variable REPL;
  • to read each line, to append the sequence of spaces and to store the augmented line in LINE;
  • to retrieve the actual sequence of trailing spaces per line (by seeking the sequence in REPL) and to store it in TRNC;
  • to replace the actual sequence of spaces of each line by nothing, that is, to truncate it, and then to actually output the remaining string portion;

Of course you can do this too when parsing the file InstallList.txt as described above.

aschipfl
  • 33,626
  • 12
  • 54
  • 99