So I took the above & have been using this batch file for a while now.
XXhash64.BAT:
Code: Select all
@echo off
rem "carot.bat" (heh) "carat.bat"
rem SjB 10-3-2022
rem cause
rem a filename, with a ^ (carat), but NOT followed by a <sp> (somewhere in the filename)
rem is NOT parsed correctly
rem when used with a 'SendTo' or a 'drag & drop'
rem file names such as: "x^x" or "x^x.txt", FAIL, where "x^ x x" (contains spaces) or "x^ - test 123.TXT" are just fine
rem probably - ONLY with batch files (using %* or %1...), where doing the same directly to a .exe is not an issue
rem
rem go.bat (drag & drop files to go.bat & observe results):
rem @echo off
rem echo %*
rem pause
rem
rem work-around, per void, per xxx, noted up, VERY ROUGHLY, & NOT understood very well - by me ;-)
@echo off
:: do note that originally, when i was echoing, /I/ used parms, where /he/ used params
:: and that is why, at first, i was getting NOTHING echoed back with my PARMS (dumy!)
:: and to confuse things more, i've not kept both my PARMS & his params ;-)
:: in my comments below, "BOTH" or "2"... all depend on how many files were sent to carot.bat
:: & whether they contained spaced or not...
setlocal DisableDelayedExpansion
set index=0
setlocal EnableDelayedExpansion
rem *** Take the cmd-line, remove all until the first parameter
rem *** Copy cmdcmdline without any modifications, as cmdcmdline has some strange behaviour
set "params=!cmdcmdline!"
rem echo parms: %params%
rem echo parms: !params!
rem echo cmd : !cmdcmdline!
rem echo.
rem echo ...........cmd is the FULL command line, incl. cmd.exe /c itself...
rem :: so %cmdcmdline% == e:/.../cmd.exe == %ComSpec%
rem :: but how/why does !cmdcmdline! get resolved to "everything"?
rem pause
set "params=!params:~0,-1!"
rem echo.
rem echo parms01: %params%
rem echo parms01: !params:~0,-1!
rem echo ...........not sure what is going on here?
rem echo ...........in this case parms01 /IS/ being set (and can be read back - SANS the closing ")
rem echo ...........and what, ~0 is the full command line?
rem echo ...........as is ~0,-1? (where ~0,1 would be the first parameter, or something ?)
rem echo ...........ah no! that says ~0, the full command line /MINUS/ the final character (the closing ")
rem echo ...........and ~0,-2 would be the full command line /MINUS/ the final 2 characters - so similar to a seg$(len-1)
rem pause
set "params=!params:*" =!"
rem echo.
rem echo parms02: %params%
rem echo parms02: !params:*" =!
rem echo ...........shows the 2ND filenmame, but not the first - not sure why?
rem echo ...........but if there were 2 non-quoted files, they do both display here?
rem echo ...........oh, and PARMS02 contains the "bastardized", wrong name, where params... contains the "correct" names
rem echo ...........maybe, params... contains only the "non-quoted" parameters?
rem pause
rem echo.
rem echo params: !params!
rem echo.
rem echo ...........now, why do BOTH names show up here?
rem pause
rem echo.
rem echo parms03: %params%
rem echo.
rem echo ...........at this point, PARMS03 is the same as params
rem pause
rem xxh %params%
rem echo.
rem echo ...........so, NO, this does not work, cause as soon as you use PARMS03, it again gets bastardized
rem pause
rem echo.
rem Split the parameters on spaces but respect the quotes
for %%G IN (!params!) do (
for %%# in (!index!) do (
endlocal
set /a index+=1
set "item_%%#=%%~G"
setlocal EnableDelayedExpansion
)
)
rem :: so... !index! is incremented for each filename passed (initially set to 0)
set /a max=index-1
rem :: makes the max (math) correct
rem list the parameters
for /L %%n in (0,1,!max!) DO (
xxh "!item_%%n!"
)
rem :: oh, so item_%%n, where %n is an index (array) number, holds the passed filenames from %G
rem :: so is this a "round-about" way, or a "robust" way to do things?
rem :: could you just combine the %G parts with xxh.exe %G, or does the "expansion" play in?
echo Done!
pause
REM ** The exit is important, so the cmd.exe doesn't try to execute commands after ampersands
exit
Dealing with %1, shift or %* could fail with drag&drop, because the explorer is not very smart, when it creates the command line.
Files like Cool&stuff.cue are not quoted by the explorer so you get a cmdline like
pcutmp3.bat Cool&stuff.cue
So in %1 is only Cool even in %* is only Cool, but after the pcutmp3.bat ends, cmd.exe tries to execute a stuff.cue.
To handle with this stuff you could use this, it catch all filenames by using the cmdcmdline variable.
Btw. there is a line limit for drag&drop operations of ~2048 characters, in spite of the "standard" batch line limit of 8191 characters.
Not a big deal, but (at least with what I've got above), you cannot run XXhash64.BAT from a command-line itself?
You can SendTo, you can drop a file(s) onto the .bat, but you can't XXhash64.BAT <filename>?
You can also:
Code: Select all
echo abc | XXhash64
or
dir /b abc | XXhash64
& you do get a hash, but you're getting a of a data stream (STDIN), rather then a
file named "abc".
If I try to:
XXhash64.BAT xxhash64.bat
I get:
Code: Select all
C:\BIN>xxhash64.bat xxhash64.bat
Error: Could not open 'E:\Windows\system32\cmd.ex': No such file or directory.
Done
Press any key to continue . . .
Note cmd.ex vs cmd.exe ?