I have this batch to compare the modified dates of two files that works great on an old version of Windows 10 '10.0.10240' but not at all on a slightly newer version of Windows 10 '10.0.17134.1304', so what am I missing here? Does the slightly newer version of Windows 10 require the installation of any additional software?
The batch file is as follows:
@echo off
Set _File1="D:\Steam\steamapps\common\dota 2 beta\game\dota\bin\win64\client.dll"
Set _File2="D:\Programs\client.dll"
For /F "Delims=" %%I In ('xcopy /DHYL %_File1% %_File2% ^|Findstr /I "File"') Do set /a _Newer=%%I 2>Nul
If %_Newer%==1 (Set _Newer=%_File1%) Else (Set _Newer=%_File2%)
Echo The newest file is %_Newer%
Pause
works perfectly on 'Windows 10.0.10240' but fails to start on 'Windows 10.0.17134.1304' (only opens for a fraction of a second and then immediately closes)
CodePudding user response:
By including the /Q
option with XCOPY
, there is no need to pipe through to FINDSTR
.
You could therefore use this modification of your chosen FOR /F
idea:
@Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "_File1=D:\Steam\steamapps\common\dota 2 beta\game\dota\bin\win64\client.dll"
Set "_File2=D:\Programs\client.dll"
For %%G In ("%_File1%" "%_File2%") Do If Not Exist %%G (Echo A file is missing.& GoTo :EndIt)
Set "_Newer="
For /F %%G In ('%SystemRoot%\System32\xcopy.exe "%_File1%" "%_File2%" /DHLQY 2^>NUL') Do If %%G Equ 1 (Set "_Newer=%_File1%") Else Set "_Newer=%_File2% or neither"
If Not Defined _Newer (Echo An error occurred.& GoTo :EndIt)
Echo %_Newer% is the newer file.
:EndIt
Pause
EndLocal
GoTo :EOF
I have added some additional 'debugging' code to help you to determine what happens on each different system version, and to correct your assumption that 0
means that %_File2%
is newer, when both may be datestamped the same.
CodePudding user response:
Your problem appears to be that the response from xcopy
, as filtered through findstr
will either be 1 File(s)
or 0 File(s)
and this string is applied to newer
Your if
statement then is resolved to
if 1 File(s)==1 ....
So you get a syntax error.
To resolve, remove the "delims="
from the for /f
which will then use the default delimiters which includes Space and return the default first token, which is 1
or 0
.
Only real puzzle is how it ever worked in your earlier Win10.
Obligatory sermon:
Use set "var=value"
for setting string values - this avoids problems caused by trailing spaces. Don't assign a terminal \
, Space or "
- build pathnames from the elements - counterintuitively, it is likely to make the process easier.
When you use the point-click-and-giggle method of executing a batch, the batch window will close if a syntax-error is found or the script runs to completion. You can put a pause
after statements and home in on the error, but better to open a 'command prompt' and run your batch from there so that the window remains open and any (error) messages will be displayed.
--- Revision ---
After a little experimentation, I looked a little closer at the code.
The "delims="
delivers the strings I described - BUT - the set /a
(rather than what I expected, set
) would grab that number, then fail (hence the 2>nul
)
So - what I found is that if file2
does not exist, the script stops waiting for a response to xcopy
's question "is file2 a file or directory?`
This may be the cause of the failure on clicking the batch.
So - I'd suggest
set "_newer="
if exist %_file1% set "newer=1"&if exist %_file2% for ...
if defined _newer (if _%_newer%==1....) else Echo %_file1% not found