0

How can I calculate checksum and verify against a register with a batch file? I'm trying to use a redirect/pipe inspired by https://stackoverflow.com/a/42706309/4539999 (best called from a batch file) and looking for something simpler than https://stackoverflow.com/a/42172138/4539999.

Many Views with No Answers to this Ascynchronous Thread Issue

...Each side of a pipe starts its own cmd.exe in its own ascynchronous thread...

Described here: Why does delayed expansion fail when inside a piped block of code? Best Checksum solution from @dbenham at https://stackoverflow.com/a/42172138/4539999

===== Back to the attempt:

 CertUtil -hashfile "path_to_file" MD5 | find /i /v "md5" | find /i /v "certutil"

How is the output from the first command used as the find string in the second command? For example using NestBat.bat:

C:\Users\User\Code\NestBat>certutil -hashfile NestBat.bat MD5 | find /i /v "md5" | find /i /v "certutil"
c19c099a7703768ef1b8dbeec3c45dba

C:\Users\User\Code\NestBat>find "c19c099a7703768ef1b8dbeec3c45dba" Manifest.MD5

---------- MANIFEST.MD5
c19c099a7703768ef1b8dbeec3c45dba  NestBat.bat

Something like:

@echo off
:: ValidateHashcode.bat    
setlocal enabledelayedexpansion
CertUtil -hashfile "%1" MD5 | find /i /v "md5" | find /i /v "certutil" ^> %temp%\Hashcode.tmp
set Hashcode=^<%temp%\Hashcode.tmp
del %temp%\Hashcode.tmp
find "%Hashcode%" Manifest.MD5
if NOT "%ERRORLEVEL%"=="0" echo *** Process Error ****
set Hashcode=
endlocal

(But it is never going to work - check the references above.)

flywire
  • 1,155
  • 1
  • 14
  • 38

2 Answers2

0

Answer from Stephan as testing scenario under Win7:

C:\Users\user\test>type test.bat
@echo off
:: ValidateHashcode.bat
setlocal enabledelayedexpansion
for /f "delims=" %%a in ('CertUtil -hashfile "%~1" MD5 ^| findstr /v "MD5 CertUtil"') do set "Hashcode=%%a"
set "Hashcode=%Hashcode: =%"
find "%Hashcode%" Manifest.MD5 > nul
if "%Errorlevel%"=="0" echo *** Valid file: %Hashcode% %~1
if NOT "%Errorlevel%"=="0" echo *** Invalid file: %Hashcode% %~1
set Hashcode=
endlocal

C:\Users\user\test>ver
*** Valid file: eb3074bbe51278a11326fda1b244cbae test.tmp

Test by removing find redirect to nul

find "%Hashcode%" Manifest.MD5

Output:

C:\Users\user\test>test test.tmp

---------- MANIFEST.MD5
eb3074bbe51278a11326fda1b244cbae test.tmp
*** Valid file: eb3074bbe51278a11326fda1b244cbae test.tmp

C:\Users\user\test>ver

Microsoft Windows [Version 6.1.7601]
flywire
  • 1,155
  • 1
  • 14
  • 38
0

there are two errors in your code:

CertUtil -hashfile "%1" MD5 | find /i /v "md5" | find /i /v "certutil" ^> %temp%\Hashcode.tmp

don't escape the redirection symbol:

CertUtil -hashfile "%1" MD5 | find /i /v "md5" | find /i /v "certutil" > "%temp%\Hashcode.tmp"

Same with

set Hashcode= ^<%temp%\Hashcode.tmp

Don't escape the redirection symbol. And it should be set /p to set the variable to the content of the file (the first line, to be exact):

set /p Hashcode= <"%temp%\Hashcode.tmp"

Note: I recommend using "%~1" instead of just "%1" (if you use Drag'n Drop, a file name with spaces will already have surrounding quotes. The ~ removes them (just to be sure to not have double-quoting like ""file with spaces.ext"")

EDIT I know that each side of the pipe... thing, but I fail to see, how it applies here. The following code runs fine here:

@echo off
:: ValidateHashcode.bat    
setlocal enabledelayedexpansion
CertUtil -hashfile "%~1" MD5 | find /i /v "md5" | find /i /v "certutil" > %temp%\Hashcode.tmp
set /p Hashcode=<%temp%\Hashcode.tmp
del %temp%\Hashcode.tmp
echo %Hashcode%

Output:

C:\Users\Stephan\test>test.bat temp.txt
da6d921549b68ed59213022297a956fb

Note: you can use a for /f loop to get the value without a temporary file:

@echo off  
for /f "delims=" %%a in ('CertUtil -hashfile "%~1" MD5 ^| findstr /v "MD5 CertUtil"') do set "Hashcode=%%a"
set "Hashcode=%Hashcode: =%"
echo %Hashcode%
Stephan
  • 53,940
  • 10
  • 58
  • 91
  • Escape character corrections noted. Real issue is _Each side of a pipe starts its own cmd.exe in its own asynchronous thread_. Each line executes at the command prompt but they will not execute within a batch file. Change first line to _echo on_ and try it. – flywire Feb 19 '18 at 12:04
  • I added verify code to your example and updated the output. This solution works on Win10. I agree the code is better by replacing the three lines after _setlocal enabledelayedexpansion_ with the _for ..._ code you provided. Win7 hashcode output is different having spaces after each two characters and the code tries to verify with two characters. It fails so badly that the ErrorLevel code is completely inverted! – flywire Feb 20 '18 at 09:47
  • Added `set "Hashcode=%Hashcode: =%"` to remove the spaces. – Stephan Feb 20 '18 at 10:00
  • ...and of course `"delims="` to get the whole line in the first place. – Stephan Feb 20 '18 at 11:18
  • Excellent - you solved what I thought was near impossible for Win7 and Win10. Where is best place to roll into final solution? – flywire Feb 20 '18 at 11:58