0
@echo off
setlocal enableextensions enabledelayedexpansion

set CHECKSUM_TOOL=fciv.exe
set DESTINATION_DIR=C:\Documents and Settings\Users\Desktop\testfolder
set CHECKSUM=12345
set APP_NAME=price
set VERIFY_FILE=testfile.txt

for /f "tokens=1" %%m in ('call "%CHECKSUM_TOOL%" -md5 
"%DESTINATION_DIR%\!VERIFY_FILE!"') do (
      for /f "tokens=1 delims=/ " %%n in ("%%m") do (
        set CURRENT_CHECKSUM="%%n"
        if not !CURRENT_CHECKSUM!==!CHECKSUM! (
          echo %DATE% %TIME% [ERROR] %~nx0: Checksum of existing file !CURRENT_CHECKSUM! does not match manifest !CHECKSUM! for %APP_NAME%
          REM exit 1
        )
      )
    )

So i have the above batch script. The problem is when i print out the value of CURRENT_CHECKSUM the file directory is truncated and instead of echoing

C:\Documents and Settings\Users\Desktop\testfolder\testfile.txt

I instead get

c:\documents

output to the fciv call returns

bd4e8c3e9b3a880365619e48a779e8e0 c:\documents and settings\Users\desktop\testfolder\testfile.txt 
6
  • Have you tried putting delims= in your first loop? Try also: quoting the variables in set like set "var=value", quoting both values in if statement and a space after == like if not "!CURRENT_CHECKSUM!" == "!CHECKSUM!", e.t.c. !VERIFY_FILE! is not needed, also. Can you please explain what the output of the command parsed in the for /F loop will be? I am not familiar with fciv.exe Commented Feb 5, 2019 at 16:28
  • Huh? And you want to take the path next to the string? Commented Feb 5, 2019 at 16:37
  • it returns 2 tokens. first is the checksum. second is the filepath. I grab the file path but it truncates it after the first whitespace it sees (after documents) Commented Feb 5, 2019 at 16:42
  • I want the whole "C:\Documents and Settings\Users\Desktop\testfolder\testfile.txt" and not just "c:\documents" Commented Feb 5, 2019 at 16:43
  • Please add the output of fciv.exe in your question by editing it! You rissue is not related to escaping, it is the usage of for /F: for /F "tokens=1*" ... would return two tokens, separated by the first (sequence of) whitespace(s), so the second one may even contain whitespaces on its own... Commented Feb 5, 2019 at 16:43

3 Answers 3

2

Actually I cannot reproduce the output you described, because I get the (quoted) checksum of the file when echoing !CURRENT_CHECKSUM!, but not the partial file path as you describe.

Anyway, I believe you defined the for /F options wrongly; you need something like tokens=1*, so you will get two tokens, which are separated by the first (sequence of) whitespace(s), and the second token may even contain whitespaces on its own. By the way, there is no need to use two for /F loops, one is enough.

So here is my suggestion of the fixed code:

@echo off
setlocal EnableExtensions EnableDelayedExpansion

set "CHECKSUM_TOOL=fciv.exe"
set "DESTINATION_DIR=C:\Documents and Settings\Users\Desktop\testfolder"
set "CHECKSUM=12345"
set "APP_NAME=price"
set "VERIFY_FILE=testfile.txt"

for /F "tokens=1*" %%M in ('
    "%CHECKSUM_TOOL%" -md5 "%DESTINATION_DIR%\%VERIFY_FILE%"
') do if not "%%M"=="%CHECKSUM%" (
    echo !DATE! !TIME! [ERROR] %~nx0: Checksum %%M of existing file %%N does not match manifest %CHECKSUM% for %APP_NAME%
    rem exit /B 1
)

endlocal
exit /B

This is what I did:

  • one for /F loop with the proper options applied;
  • used the quoted set syntax (the quotes protect special characters but are not part of the values);
  • quoted both comparison expressions to avoid problems in case they are empty;
  • applied delayed expansion also on !DATE! and !TIME!;
  • removed interim variables and used for /F variables immediately;
  • replaced (commented out) exit by exit /B to quit the batch file but not the parent cmd instance;
  • removed call to run fciv.exe as it is not a batch file but an executable;
Sign up to request clarification or add additional context in comments.

Comments

0

Try setting with "":

set DESTINATION_DIR="C:\Documents and Settings\Users\Desktop\testfolder"

1 Comment

i am trying to escape the variable here here -> set CURRENT_CHECKSUM="%%n"
0

There are several solutions to this, but I will show you now the most general one, which works if you actually want to remove the first token:

@echo off
setlocal EnableDelayedExpansion

set "CHECKSUM_TOOL=fciv.exe"
set "DESTINATION_DIR=C:\Documents and Settings\Users\Desktop\testfolder
set "CHECKSUM=12345"
set "APP_NAME=price"
set "VERIFY_FILE=testfile.txt"

rem Loop to get the first token for substraction later:
for /F "delims=" %%A IN ('call "%CHECKSUM_TOOL%" -md5 "%DESTINATION_DIR%\%VERIFY_FILE%"') do (
    set "output=%%A"
    for /F "tokens=1" %%B IN ("%%A") do (
        set "token_to_substract=%%B"
    )
)
set "expected_output=!output:%token_to_substract% =!"

echo The string you wanted to obtain for a custom reason of yours is: %expected_output%

A shorter, but not so general solution, would be:

@echo off

set "CHECKSUM_TOOL=fciv.exe"
set "DESTINATION_DIR=C:\Documents and Settings\Users\Desktop\testfolder
set "CHECKSUM=12345"
set "APP_NAME=price"
set "VERIFY_FILE=testfile.txt"

for /F "tokens=2 delims=:" %%A IN ('call "%CHECKSUM_TOOL%" -md5 "%DESTINATION_DIR%\%VERIFY_FILE%"') do (
    set "expected_output=c:%%A"
)
echo The string you wanted to obtain for a custom reason of yours is: %expected_output%

It is also possible to replace the last for /F loop with the following one and with the same about meaning:

for /F "tokens=2 delims=\" %%A IN ('call "%CHECKSUM_TOOL%" -md5 "%DESTINATION_DIR%\%VERIFY_FILE%"') do (
    set "expected_output=c:\%%A"
)
echo The string you wanted to obtain for a custom reason of yours is: %expected_output%

which does exactly the same (difference with previous is 1 byte :)).

1 Comment

@L-Samuels Perhaps this meta question will help you understand why it is not mandatory to leave a comment.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.