flamey
flamey

Reputation: 2389

Strange value when parsing output in Windows batch script

Trying to make a script to unlock all locked files inside a folder, by using Windows' handle.exe. But when I split the output the filename value is .... weird (all other values are Ok).

The sample output of the handle.exe is this:

REM  perl.exe           pid: 12532  type: File          PCNAME\UserName          144: C:\dev\massunlocker\Eula.txt
REM  a perl.exe
REM  b pid:
REM  c 12532
REM  d type:
REM  e File
REM  f PCNAME\UserName
REM  g 144:
REM  h C:\dev\massunlocker\Eula.txt

So, from this I need c, g, and h.

@echo off
setlocal EnableDelayedExpansion

for /f "tokens=1,2,3,4,5,6,7,8 delims= " %%a in ( 'handle64.exe C:\dev\massunlocker\sample-dir -u -nobanner' ) do (
    REM echo a = "%%a"
    REM echo b = "%%b"
    REM echo c = "%%c"
    REM echo d = "%%d"
    REM echo e = "%%e"
    REM echo f = "%%f"
    REM echo g = "%%g"
    REM echo h = "%%h"
    echo [%%h]
)


:end
setlocal DisableDelayedExpansion

First 2 are fine, but the %%h is hmm weird (edited)?

]C:\dev\massunlocker\sample-dir\ae\pdf
]C:\dev\massunlocker\sample-dir
]C:\dev\massunlocker\sample-dir\ae

Why its not this? :

[C:\dev\massunlocker\sample-dir\ae\pdf]
[C:\dev\massunlocker\sample-dir]
[C:\dev\massunlocker\sample-dir\ae]

And I can't test it for being dir or a file, it's always comes as true for not exist, for example.

Edit: here's an output example with lines uncommented:

a = "cmd.exe"
b = "pid:"
c = "1624"
d = "type:"
e = "File"
f = "PCNAME\UserName"
g = "1FC:"
" = "C:\dev\massunlocker\sample-dir

note the last line...

P.S. Handle tool

Upvotes: 0

Views: 129

Answers (3)

Compo
Compo

Reputation: 38718

The output you're experiencing is the same as we get from the output of wmic.exe within a For loop. I'll assume therefore that handle64.exe also outputs an extra <CR>.

If that's the case, you should run the result through an additional For loop, in the same way as if it were WMIC. Take a look at some of the WMIC examples on this site for examples of it in use. Alternatively take a look at this topic over on dostips.com.

Here's an example of it in use:

For /F "Tokens=*" %%A In ('
    handle64.exe C:\dev\massunlocker\sample-dir -u -nobanner
')Do For /F "Tokens=1-8" %%B In ("%%A")Do (Rem Echo B = "%%B"
    Rem Echo C = "%%C"
    Rem Echo D = "%%D"
    Rem Echo E = "%%E"
    Rem Echo F = "%%F"
    Rem Echo G = "%%G"
    Rem Echo H = "%%H"
    Rem Echo I = "%%I"
    Echo [%%I])
Pause

Upvotes: 1

Se&#241;or CMasMas
Se&#241;or CMasMas

Reputation: 5178

I don't mean this as an answer.. I just needed the formatted text. As Compo points out.. there is indeed 0D 0D 0A at the end of the output but not in the middle where the parser should care about it.

Their parser should be better than that.

Hex dump of the output

As a workaround (as Compo mentioned), take the output of the call and run it through another for loop, it works just fine. I did the one below with a function call.

@echo off
Set THE_DIR=%TEMP%

for /f "delims=" %%a in ( 'handle64.exe %THE_DIR% -u -nobanner' ) do call :Process_Line "%%a"
goto :EOF

:Process_Line 
for /f "tokens=1,2,3,4,5,6,7,8 delims= " %%a in ( 'echo %*' ) do (
echo a = "%%a"
echo b = "%%b"
echo c = "%%c"
echo d = "%%d"
echo e = "%%e"
echo f = "%%f"
echo g = "%%g"
echo h = "%%h"
)
goto :EOF

Upvotes: 1

JosefZ
JosefZ

Reputation: 30238

The following code snippet could help.

@ECHO OFF
SETLOCAL EnableExtensions EnableDelayedExpansion

for /f "tokens=1-7,* delims= " %%a in ('
    handle64.exe C:\Windows\System32\en-US\Kernel -u -nobanner
  ' ) do (

    REM echo a = "%%a" 
    REM echo b = "%%b"
    REM echo c = "%%c"
    REM echo d = "%%d"
    REM echo e = "%%e"
    REM echo f = "%%f"
    REM echo g = "%%g"
    REM echo h = "%%h"
    for /F "tokens=*" %%H in ("%%~h") do echo h="%%H"  a="%%a"
)

Here the for loops are

  • %%a to retrieve the handle64.exe output values;
  • %%H to remove the ending carriage return in the %%h value returned at a line end.

wmic (and handle64 as well) behaviour: each output line ends with 0x0D0D0A (<CR><CR><LF>) instead of common 0x0D0A (<CR><LF>).

See Dave Benham's WMIC and FOR /F: A fix for the trailing <CR> problem

Output (truncated):

==> D:\bat\SO\55065841.bat
h="C:\Windows\System32\en-US\KernelBase.dll.mui"  a="GoldenDict.exe"
h="C:\Windows\System32\en-US\KernelBase.dll.mui"  a="chrome.exe"
h="C:\Windows\System32\en-US\kernel32.dll.mui"  a="chrome.exe"
h="C:\Windows\System32\en-US\KernelBase.dll.mui"  a="AppleChromeDAV.exe"    

==>

Upvotes: 1

Related Questions