Powered by GeSHi

Source code for dircomp.bat

(view source code of dircomp.bat as plain text)

  1. @ECHO OFF
  2. :: Check Windows version
  3. IF NOT "%OS%"=="Windows_NT" GOTO Syntax
  4.  
  5. :: Only /DEBUG is valid as optional third argument
  6. IF NOT "%~3"=="" IF /I NOT "%~3"=="/C" IF /I NOT "%~3"=="/DEBUG" GOTO Syntax
  7.  
  8. :: Two command line arguments are mandatory
  9. IF "%~1"=="" GOTO Syntax
  10. IF "%~2"=="" GOTO Syntax
  11.  
  12. :: If the first argument is not a folder, it should end with \*.ext
  13. IF NOT "%~x1"=="" (
  14. 	ECHO.%~1| FINDSTR /R /E /I /C:"\\\*\%~x1" >NUL || GOTO Syntax
  15. )
  16.  
  17. SETLOCAL ENABLEDELAYEDEXPANSION
  18.  
  19. :: Reset the variables we are going to use
  20. SET Dir1=
  21. SET Dir2=
  22. SET FileType=*.*
  23. SET NumFiles1=0
  24. SET NumFiles2=0
  25. SET TotalFiles1=
  26. SET TotalFiles2=
  27. SET TotalLine1=
  28. SET TotalLine2=
  29. SET TotalSize1=
  30. SET TotalSize2=
  31. SET Type=
  32.  
  33. :: Check if FCIV is available, and if not, prompt to open its download page
  34. :: Code corrected in version 3.10, as the earlier versions failed to detect
  35. :: the absence of FCIV.EXE (thanks Ron Guggisberg for finding this bug)
  36. ECHO Checking availability of FCIV utility . . .
  37. SET Answer=
  38. FCIV.EXE -h >NUL 2>&1
  39. IF ERRORLEVEL 1 (
  40. 	ECHO This batch file requires Microsoft's File Checksum Integrity Verifier utility
  41. 	ECHO ^(FCIV.EXE^), available at http://support.microsoft.com/kb/841290
  42. 	ECHO.
  43. 	SET Answer=N
  44. 	SET /P Answer=Do you want to open the download page now? [y/N] 
  45. 	IF /I NOT "!Answer!"=="Y" GOTO Syntax
  46. 	CLS
  47. 	ECHO.
  48. 	ECHO You are about to open Microsoft's FCIV download page.
  49. 	ECHO Download and install FCIV.EXE and restart this batch file.
  50. 	ECHO.
  51. 	PAUSE
  52. 	START http://support.microsoft.com/kb/841290
  53. 	ENDLOCAL
  54. 	GOTO:EOF
  55. )
  56.  
  57. :: Quick and dirty way to check if directories exist and remove trailing backslashes in one go
  58. PUSHD "%~dp1"
  59. IF ERRORLEVEL 1 (
  60. 	ENDLOCAL
  61. 	GOTO Syntax
  62. ) ELSE (
  63. 	SET Dir1=!CD!
  64. 	POPD
  65. )
  66. PUSHD "%~f2"
  67. IF ERRORLEVEL 1 (
  68. 	ENDLOCAL
  69. 	GOTO Syntax
  70. ) ELSE (
  71. 	SET Dir2=!CD!
  72. 	POPD
  73. )
  74. IF NOT "%~nx1"=="" (
  75. 	SET FileType=*%~x1
  76. 	SET Type=-type *%~x1
  77. )
  78.  
  79. :: :: :: :: :: :: :: :: :: :: :: :: :: :: ::
  80. ::                                        ::
  81. :: Part I: just check the total file size ::
  82. ::                                        ::
  83. :: :: :: :: :: :: :: :: :: :: :: :: :: :: ::
  84.  
  85. ECHO Checking number of files and total file size for both directories . . .
  86.  
  87. :: Get number of matching files and total file size for first directory
  88. FOR /F %%A IN ('DIR "%~1" /S ^| FIND /C "("') DO SET /A TotalLine1 = %%A - 1
  89. FOR /F "tokens=2,4" %%A IN ('DIR "%~1" /-C /S ^| FIND "(" ^| FIND /N "(" ^| FIND "[%TotalLine1%]"') DO (
  90. 	SET TotalFiles1=%%A
  91. 	SET TotalSize1=%%B
  92. )
  93.  
  94. :: Get number of matching files and total file size for second directory
  95. FOR /F %%A IN ('DIR "%Dir2%.\%FileType%" /S ^| FIND /C "("') DO SET /A TotalLine2 = %%A - 1
  96. FOR /F "tokens=2,4" %%A IN ('DIR "%Dir2%.\%FileType%" /-C /S ^| FIND "(" ^| FIND /N "(" ^| FIND "[%TotalLine2%]"') DO (
  97. 	SET TotalFiles2=%%A
  98. 	SET TotalSize2=%%B
  99. )
  100.  
  101. :: Abort if the NUMBER of matching files does not match
  102. IF NOT %TotalFiles1% EQU %TotalFiles2% (
  103. 	ECHO Number of files is different:
  104. 	ECHO %TotalFiles1% files in %Dir1%
  105. 	ECHO %TotalFiles2% files in %Dir2%
  106. 	ECHO.
  107. 	ECHO Aborting comparison . . .
  108. 	ECHO.
  109. 	ENDLOCAL
  110. 	EXIT /B 2
  111. )
  112.  
  113. :: Warn if the TOTAL SIZE of the files does not match
  114. IF NOT %TotalSize1% EQU %TotalSize2% (
  115. 	ECHO Total file size is different:
  116. 	ECHO %TotalSize1% bytes in %Dir1%
  117. 	ECHO %TotalSize2% bytes in %Dir2%
  118. 	ECHO.
  119. 	IF /I "%~3"=="/C" (
  120. 		ECHO Continuing comparison . . .
  121. 		ECHO.
  122. 	) ELSE (
  123. 		ECHO Aborting comparison . . .
  124. 		ECHO.
  125. 		ENDLOCAL
  126. 		EXIT /B 2
  127. 	)
  128. )
  129.  
  130. :: :: :: :: :: :: :: :: :: :: :: :: ::
  131. ::                                  ::
  132. :: Part II: compare file timestamps ::
  133. ::                                  ::
  134. :: :: :: :: :: :: :: :: :: :: :: :: ::
  135.  
  136. ECHO Comparing files' timestamps for both directories . . .
  137.  
  138. :: XCOPY /D /Y /L just checks what is newer without actually copying anything
  139. FOR /F %%A IN ('XCOPY "%Dir1%\%FileType%" "%Dir2%\*.*" /S /D /H /R /Y /L 2^>NUL') DO SET NumFiles1=%%A
  140. FOR /F %%A IN ('XCOPY "%Dir2%\%FileType%" "%Dir1%\*.*" /S /D /H /R /Y /L 2^>NUL') DO SET NumFiles2=%%A
  141. IF %NumFiles1% EQU 0 IF %NumFiles2% EQU 0 (
  142. 	REM Do nothing if all timestamps match
  143. ) ELSE (
  144. 	IF %NumFiles2% GTR 0 ECHO %NumFiles2% files in "%Dir1%" are older
  145. 	IF %NumFiles1% GTR 0 ECHO %NumFiles1% files in "%Dir2%" are older
  146. )
  147.  
  148. :: :: :: :: :: :: :: :: :: :: :: :: :: :: ::
  149. ::                                        ::
  150. :: Part III: compare checksums per file   ::
  151. ::                                        ::
  152. :: :: :: :: :: :: :: :: :: :: :: :: :: :: ::
  153.  
  154. :: Go to the TEMP directory to create the required temporary files here
  155. PUSHD "%Temp%"
  156.  
  157. :: Remove previous versions of the temporary files
  158. FOR %%A IN (~Dir1.md5 ~Dir1.tmp ~Dir2.md5 ~Dir2.tmp fciv.err) DO IF EXIST %%A DEL %%A
  159.  
  160. ECHO Scanning "%Dir1%" and subdirectories . . .
  161. FCIV.EXE "%Dir1%" -md5 -r %Type% | FINDSTR /R /B /I /C:"[0-9a-f][0-9a-f][0-9a-f]* [a-z\\][:\\]" | SORT /+33 > ~Dir1.md5
  162.  
  163. ECHO Scanning "%Dir2%" and subdirectories . . .
  164. FCIV.EXE "%Dir2%" -md5 -r %Type% | FINDSTR /R /B /I /C:"[0-9a-f][0-9a-f][0-9a-f]* [a-z\\][:\\]" | SORT /+33 > ~Dir2.md5
  165.  
  166. :: Abort if no files were found in either directory (i.e. if either checksums list is 0 bytes)
  167. FOR %%A IN (~Dir1.tmp) DO SET Size1=%%~zA
  168. FOR %%A IN (~Dir2.tmp) DO SET Size2=%%~zA
  169. IF %Size1%0 NEQ 0 IF %Size2%0 NEQ 0 (
  170. 	REM Do nothing if both files are larger than 0 bytes
  171. ) ELSE (
  172. 	IF %Size1%0 EQU 0 ECHO No files found in %Dir1%
  173. 	IF %Size2%0 EQU 0 ECHO No files found in %Dir2%
  174. 	ENDLOCAL
  175. 	EXIT /B 3
  176. )
  177.  
  178. TYPE NUL > ~Dir1.tmp
  179. TYPE NUL > ~Dir2.tmp
  180. IF /I "%~3"=="/DEBUG" (
  181. 	SET Count=0
  182. 	ECHO Removing specified path from ~Dir1.md5
  183. )
  184. FOR /F "tokens=*" %%A IN (~Dir1.md5) DO (
  185. 	IF /I "%~3"=="/DEBUG" SET /A Count += 1
  186. 	SET Line=%%A
  187. 	IF /I "%~3"=="/DEBUG" ECHO [!Count!]!Line!
  188. 	SET Line=!Line:%Dir1%=!
  189. 	IF /I "%~3"=="/DEBUG" ECHO [!Count!]!Line!
  190. 	>> ~Dir1.tmp ECHO.!Line!
  191. )
  192. IF /I "%~3"=="/DEBUG" (
  193. 	SET Count=0
  194. 	ECHO Removing specified path from ~Dir2.md5
  195. )
  196. FOR /F "tokens=*" %%A IN (~Dir2.md5) DO (
  197. 	IF /I "%~3"=="/DEBUG" SET /A Count += 1
  198. 	SET Line=%%A
  199. 	IF /I "%~3"=="/DEBUG" ECHO [!Count!]!Line!
  200. 	SET Line=!Line:%Dir2%=!
  201. 	IF /I "%~3"=="/DEBUG" ECHO [!Count!]!Line!
  202. 	>> ~Dir2.tmp ECHO.!Line!
  203. )
  204.  
  205. ECHO Comparing checksums . . .
  206. SET Error=0
  207. FC.EXE /C ~Dir1.tmp ~Dir2.tmp | MORE +1 || SET Error=2
  208.  
  209. :: Remove trash
  210. IF /I NOT "%~3"=="/DEBUG" (
  211. 	DEL ~Dir1.md5
  212. 	DEL ~Dir1.tmp
  213. 	DEL ~Dir2.md5
  214. 	DEL ~Dir2.tmp
  215. 	DEL fciv.err
  216. )
  217.  
  218. POPD
  219.  
  220. :: Exit with error level 2 in case of mismatch
  221. ENDLOCAL & EXIT /B %Error%
  222.  
  223.  
  224. :Syntax
  225. IF /I "%~3"=="/DEBUG" SET Dir1
  226. IF /I "%~3"=="/DEBUG" SET Dir2
  227. IF /I "%~3"=="/DEBUG" SET Type
  228. ECHO.
  229. ECHO DirComp.bat,  Version 3.21 for Windows NT
  230. ECHO Compare the contents of 2 directories
  231. ECHO.
  232. ECHO Usage:  DIRCOMP  d:\path\*.ext  e:\otherfolder  [/C]
  233. ECHO    or:  DIRCOMP  d:\path\       e:\otherfolder  [/C]
  234. ECHO.
  235. ECHO Where:  /C       Continues comparison even if total file size does not match
  236. ECHO.
  237. ECHO Notes:  Note the trailing backslash if the first argument is a folder.
  238. ECHO         Compares number of files,  file size, timestamp and contents of files.
  239. ECHO         Requires Microsoft's File Checksum Integrity Verifier utility (FCIV),
  240. ECHO         available at http://support.microsoft.com/kb/841290
  241. ECHO         If FCIV is not available, you will be prompted to download it.
  242. ECHO         Uses FC to compare FCIV's checksum listings; so if differences are
  243. ECHO         found, the lines immediately preceeding and following a line that
  244. ECHO         differs are displayed as well.
  245. ECHO.
  246. ECHO Written by Rob van der Woude
  247. ECHO http://www.robvanderwoude.com
  248.  
  249. IF "%OS%"=="Windows_NT" EXIT /B 1
  250.