Windows command for file size only - windows

Is there a Windows command that will output the size in bytes of a specified file like this?
> filesize test.jpg
65212
I know that the dir command outputs this information, but it outputs other information also.
I could easily write such a program, but I would prefer to use a native Windows command if possible, or only what is available in a fresh install of Windows XP.

If you are inside a batch script, you can use argument variable tricks to get the filesize:
filesize.bat:
#echo off
echo %~z1
This gives results like the ones you suggest in your question.
Type
help call
at the command prompt for all of the crazy variable manipulation options. Also see this article for more information.
Edit:
This only works in Windows 2000 and later

If you don't want to do this in a batch script, you can do this from the command line like this:
for %I in (test.jpg) do #echo %~zI
Ugly, but it works. You can also pass in a file mask to get a listing for more than one file:
for %I in (*.doc) do #echo %~znI
Will display the size, file name of each .DOC file.

Use a function to get rid off some limitation in the ~z operator. It is especially useful with a for loop:
#echo off
set size=0
call :filesize "C:\backup\20120714-0035\error.log"
echo file size is %size%
goto :eof
:: Set filesize of first argument in %size% variable, and return
:filesize
set size=%~z1
exit /b 0

Try forfiles:
forfiles /p C:\Temp /m file1.txt /c "cmd /c echo #fsize"
The forfiles command runs command c for each file m in directory p.
The variable #fsize is replaced with the size of each file.
If the file C:\Temp\file1.txt is 27 bytes, forfiles runs this command:
cmd /c echo 27
Which prints 27 to the screen.
As a side-effect, it clears your screen as if you had run the cls command.

Since you're using Windows XP, Windows PowerShell is an option.
(Get-Item filespec ).Length
or as a function
function Get-FileLength { (Get-Item $args).Length }
Get-FileLength filespec

Create a file named filesize.cmd (and put into folder C:\Windows\System32):
#echo %~z1

C:\>FORFILES /C "cmd /c echo #fname #fsize"
C:\>FORFILES /?
FORFILES [/P pathname] [/M searchmask] [/S]
[/C command] [/D [+ | -] {MM/dd/yyyy | dd}]
Description:
Selects a file (or set of files) and executes a
command on that file. This is helpful for batch jobs.
Parameter List:
/P pathname Indicates the path to start searching.
The default folder is the current working
directory (.).

Taken from here:
The following command finds folders that are greater than 100 MB in size on the D: drive:
diruse /s /m /q:100 /d d:
The /s option causes subdirectories to be searched, the /m option displays disk usage in megabytes, the /q:100 option causes folders that are greater than 100 MB to be marked, and the /d option displays only folders that exceed the threshold specified by /q.
Use the diskuse command to find files over a certain size. The following command displays files over 100 MB in size on the D: drive:
diskuse D: /x:104857600 /v /s
The /x:104857600 option causes files over 104,857,600 bytes to be displayed and is valid only if you include the /v option (verbose). The /s option means subdirectories from the specified path (in this case, the D: drive) are searched.
Using VBScript
' This code finds all files over a certain size.
' ------ SCRIPT CONFIGURATION ------
strComputer = "**<ServerName>**"
intSizeBytes = 1024 * 1024 * 500 ' = 500 MB
' ------ END CONFIGURATION ---------
set objWMI = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
set colFiles = objWMI.ExecQuery _
("Select * from CIM_DataFile where FileSize > '" & intSizeBytes & "'")
for each objFile in colFiles
Wscript.Echo objFile.Name & " " & objFile.Filesize / 1024 / 1024 & "MB"
next

This is not exactly what you were asking about and it can only be used from the command line (and may be useless in a batch file), but one quick way to check file size is just to use dir:
> dir Microsoft.WindowsAzure.Storage.xml
Results in:
Directory of C:\PathToTheFile
08/10/2015 10:57 AM 2,905,897 Microsoft.WindowsAzure.Storage.xml
1 File(s) 2,905,897 bytes
0 Dir(s) 759,192,064,000 bytes free

In PowerShell you can do:
$imageObj = New-Object System.IO.FileInfo("C:\test.jpg")
$imageObj.Length

In a batch file, the below works for local files, but fails for files on network hard drives
for %%I in ("test.jpg") do #set filesize=%~z1
However, it's inferior code, because it doesn't work for files saved on a network drive (for example, \\Nas\test.jpg and \\192.168.2.40\test.jpg). The below code works for files in any location, and I wrote it myself.
I'm sure there are more efficient ways of doing this using VBScript, or PowerShell or whatever, but I didn't want to do any of that; good ol' batch for me!
set file=C:\Users\Admin\Documents\test.jpg
set /a filesize=
set fileExclPath=%file:*\=%
:onemoretime
set fileExclPath2=%fileExclPath:*\=%
set fileExclPath=%fileExclPath2:*\=%
if /i "%fileExclPath%" NEQ "%fileExclPath2%" goto:onemoretime
dir /s /a-d "%workingdir%">"%temp%\temp.txt"
findstr /C:"%fileExclPath%" "%temp%\temp.txt" >"%temp%\temp2.txt"
set /p filesize= <"%temp%\temp2.txt"
echo set filesize=%%filesize: %fileExclPath%%ext%=%% >"%temp%\temp.bat"
call "%temp%\temp.bat"
:RemoveTrailingSpace
if /i "%filesize:~-1%" EQU " " set filesize=%filesize:~0,-1%
if /i "%filesize:~-1%" EQU " " goto:RemoveTrailingSpace
:onemoretime2
set filesize2=%filesize:* =%
set filesize=%filesize2:* =%
if /i "%filesize%" NEQ "%filesize2%" goto:onemoretime2
set filesize=%filesize:,=%
echo %filesize% bytes
SET /a filesizeMB=%filesize%/1024/1024
echo %filesizeMB% MB
SET /a filesizeGB=%filesize%/1024/1024/1024
echo %filesizeGB% GB

In PowerShell you should do this:
(Get-ChildItem C:\TEMP\file1.txt).Length

I'm not sure about remote ones, but for local Windows trough {File Sharing / Network}, %~z does work
for %%x in ("\\ComputerName\temp\temp.txt") do set "size=%%~zx"
More generalized version of this . The previous version may be not requiring enableDelayedExpansion enableExtensions, but can't run in for loops .
Some clarification --
| can't be used to pass an output value to set ; for /f doesn't support some characters in it's subject value (the path to edit), if without in-text Escaping ; for /l doesn't allow to change the count/condition values (after start) ; !<<variableName>>:<<escaped text>>*! doesn't work .
at keepOnlyAllBefore1stSpace, %%%%x is passed instead of !nu_f!, because that is needed for the same reason/use as %%%%x is made to be created .
#setLocal enableDelayedExpansion enableExtensions
#echo off
set "file=C:\Users\Admin\Documents\test.jpg"
for %%x in ("!file!") do set "name=%%~nxx"
for %%x in ("!file!") do set "storage=%%~pdx"
set "storage=!storage:~0,-1!"
dir "!storage!" > "!temp!\fileInfo.txt"
findstr /c:"!name!" "!temp!\fileInfo.txt" > "!temp!\fileInfo_1.txt"
del "!temp!\fileInfo.txt"
set /p "size=" < "!temp!\fileInfo_1.txt"
del "!temp!\fileInfo_1.txt"
call :for 1 2 "call :deleteCollumnFromStart size"
call :for 1 1 "call :keepOnlyAllBefore1stSpace %%%%x size"
:removeSpacesFromEnd
if /i "!size:~-1!" equ " " set "size=!size:~0,-1!"
if /i "!size:~-1!" equ " " goto removeSpacesFromEnd
echo(!size:,= ! bytes
pause
exit /b
:deleteCollumnFromStart
set "%~1=!%~1:* =!"
:removeAllSpacesFromStart
if /i "!%~1:~0,1!" equ " " set "%~1=!%~1:~1!"
if /i "!%~1:~0,1!" equ " " goto removeAllSpacesFromStart
goto :eof
:keepOnlyAllBefore1stSpace
if /i "!%~2:~%~1,1!" equ " " (
set "%~2=!%~2:~0,%~1!"
) else (
set /a "nu1_f= !nu1_f! + 1"
)
goto :eof
:for
set "nu_f=%~1"
set "nu1_f=%~2"
:f_repeatTimes
if not !nu1_f! lss !nu_f! (
rem echo(f_repeatTimes !nu_f! !nu1_f! %*
for %%x in (!nu_f!) do (
%~3
)
set /a "nu_f= !nu_f! + 1"
goto f_repeatTimes
)
goto :eof

wmic datafile where name='c:\\windows\\system32\\cmd.exe' get filesize /format:value

Related

CMD: Popupmessage IF file created < 5 minutes AND file > 1 MB

I want a pop up notification when a .GEO file comes into a folder that was created 5 minutes ago (or less) AND is larger than 1 MB.
Folder: T:\Klanten
This is what I've found so far:
I run a CMD every 5 minutes that checks if there is a file larger than 1MB.
If he found one, it will run another CMD:
forfiles /S /M * /C "cmd /c if #fsize GEQ 1048576 start test2.cmd"
The second CMD gives the pop up message:
echo calling popup
START /WAIT CMD /C "ECHO File in Watch CADMAN too big && ECHO. && PAUSE"
echo we are back!
I need to build a function in the first CMD where it checks if the file larger than 1 MB was created 5 minutes ago or less.
If someone can send a working CMD code that would be great!
#ECHO OFF
SETLOCAL
rem The following settings for the source directory, destination directory, target directory,
rem batch directory, filenames, output filename and temporary filename [if shown] are names
rem that I use for testing and deliberately include names which include spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.
SET "sourcedir=u:\your files"
SET "monitor=%sourcedir%\monitor.txt"
:: list files larger than required
(
FOR /f "tokens=1*delims=" %%b IN (
'dir /b /s /a-d "%sourcedir%\*.geo" 2^>nul'
) DO IF %%~zb gtr 10 ECHO "%%b"
)>"%monitor%.new"
:: Compare list against previous list (if any)
IF EXIST "%monitor%" FC "%monitor%" "%monitor%.new" >NUL 2>nul
IF ERRORLEVEL 1 ECHO START "GEO monitor report" ...whatever...
:: replace monitor list
MOVE /y "%monitor%.new" "%monitor%" >nul
GOTO :eof
The for locates files in the required directory and subdirectories (/s) in basic form /b (ie. filename-only) and reports any that have a size (%~zb) greater than - I used 10 for testing. The filenames are gathered into the ...new file and are quoted. The 2>nul suppresses error messages from dir - the ^ is required to tell cmd that the > is part of the dir command, not of the for.
See for /? from the prompt to learn about metavariable modifiers.
Then compare against the previous list, suppressing reports from fc.
fc will set errorlevel to zero if the files are the same, so detect that the files are not the same, and generate your pop-up.
Then replace the previous monitor file with the new version.
Of course, the monitor files may be placed anywhere - I just used the source directory for my convenience.

Why does my batch file fail to get file size?

I'm trying to write a Windows batch file that uses ffmpeg to convert whole folders with old *.flv videos into *.mp4 videos.
The batch file more or less works, but I want to do some test before deleting the source file. One of these test is that the output file should be at least 2/3 of the original file, but I can't get it to work.
Here's my bat file (with all the debugging echo lines included):
#echo off
setlocal EnableExtensions EnableDelayedExpansion
::-------------------------------------------------------------------------------------
:: get options and folder path
set opzione=%~1%
set cartella=%~2%
:: who's who?
if "%opzione:~3,1%"=="" (
echo.
) else (
if "%opzione:~0,1%"=="/" (
echo.
) else (
set opzione=%~2%
set cartella=%~1%
)
)
::echo.
::echo Cartella = %cartella%
::echo Opzione = %opzione%
::echo.
::-------------------------------------------------------------------------------------
:Check_path
set FLV_FOLDER="%cartella%"
if %FLV_FOLDER% == "" (
echo ... Invalid
goto :uscita
) else (
echo ... OK.
)
::-------------------------------------------------------------------------------------
:Check_Options (STILL W.I.P.)
set Lista=0
set Convert=0
set Delete=0
if "%opzione%"=="/c" (set Convert=1)
if "%opzione%"=="/l" (set Lista=1)
if "%opzione%"=="/d" (set Delete=1)
::echo Lista = %Lista%
::-------------------------------------------------------------------------------------
:Loop_path
#cls
echo Looping all .flv files in %FLV_FOLDER%...
for /R %FLV_FOLDER% %%a IN (*.flv) do call :Converting_Function "%%a"
goto :uscita
::-------------------------------------------------------------------------------------
:Converting_Function
set infile="%~1"
set outfile="%~dpn1.mp4"
set outsize=0
set insize=0
set minsize=0
if not %Lista%==0 goto :just_list
echo Converting %infile% to %outfile%
ffmpeg -v error -i %infile% -c copy -copyts %outfile%
::....................CHECKS........................................................
echo Errors from ffmpeg?
if errorlevel 1 goto :error_ffmpeg
echo Do the outfile exist?
if not exist %outfile% goto :error_exist
echo Is outfile big enough?
:: (say yes if outfile size > infile size*2/3)
for /f %%S in (%outfile%) do set "outsize=%%~zS"
echo %outfile% size is %outsize%
for /f %%S in (%infile%) do set insize=%%~zS
echo %infile% size is %insize%
set /A "minsize=(%insize%*3)/2"
echo minsize is %minsize%
if not %outsize% GTR %minsize% goto :error_size
ren "%~1" "%~n1.todelete"
:: del /q %infile%
goto :eof
:error_ffmpeg
echo Convertion error
pause
if exist %outfile% del /q %outfile%
goto :eof
:error_exist
echo %outfile% does not exist
pause
goto :eof
:error_size
echo Size of %outfile% is 0
pause
goto :eof
:just_list
echo %infile%
goto :eof
:uscita
pause
This is the output:
Converting "T:\C++Stuffs\_PROVACONV_\Monaco - Machine_#1 - Monday Morning.flv" to "T:\C++Stuffs\_PROVACONV_\Monaco - Machine_#1 - Monday Morning.mp4"
[flv # 0000000000577320] Packet mismatch 107347968 1638 1638
Errors from ffmpeg?
Do the outfile exist?
Is outfile big enough?
"T:\C++Stuffs\_PROVACONV_\Monaco - Machine_#1 - Monday Morning.mp4" size is
"T:\C++Stuffs\_PROVACONV_\Monaco - Machine_#1 - Monday Morning.flv" size is
Operando mancante.
minsize is 0
0 non atteso.
D:\ffmpeg-20170204-b1e2192-win64-static\bin>
Operando mancante means Missing Operand, 0 non atteso means Unexpected 0
Why do I not have the file size in the variables? What is the missing operand?
The environment variables infile and outfile are defined with file name being enclosed in double quotes. That is not recommended as explained in answer on Why is no string output with 'echo %var%' after using 'set var = text' on command line? But it is valid and works here as expected.
The command line to get file size of output file
for /f %%S in (%outfile%) do set "outsize=%%~zS"
is processed before execution by Windows command interpreter for example to
for /f %S in ("C:\Path\File Name.mp4") do set "outsize=%~zS"
It can be read on executing in a command prompt window for /? that for /F interprets the set (string between round brackets) as string to process if enclosed in double quotes except the option usebackq is used which is not done here. For that reason FOR splits up the string C:\Path\File Name.mp4 into tokens using space/tab as delimiters and assigns the first token to loop variable S. So assigned to S for the example is C:\Path\File. The file size for this file can't be determined by Windows command interpreter as this file does not exist.
The solution is using FOR without option /F:
for %%S in (%outfile%) do set "outsize=%%~zS"
And the command line to get file size of input file
for /f %%S in (%infile%) do set insize=%%~zS
can be replaced by
set "insize=%~z1"
The help output on running in a command prompt window call /? explains this argument modifier for getting the size of a file passed as first argument to the batch file on calling it.
The help output on running set /? explains that in arithmetic expressions the current values of environment variables can be referenced by specifying the environment variables with just their names without using % or !. This works even within a command block beginning with ( and ending with matching ).
The command line with the arithmetic expression
set /A "minsize=(%insize%*3)/2"
can result on insize not being defined in execution of
set /A "minsize=(*3)/2"
This explains the error message because there is indeed missing the left operand for the multiplication.
The solution is using the arithmetic expression as recommended by help of command SET.
set /A "minsize=(insize*3)/2"
This arithmetic expression never fails on evaluation. In case of environment variable insize is not defined, it is replaced by 0 on evaluation of the arithmetic expression as explained by the help.
See also Debugging a batch file.
And please note that Windows command interpreter supports only arithmetic expressions with 32-bit signed integer values. So video files with a file size of 2 GiB or more cannot be correct processed by your batch code.

Windows: start a file using a (non-default) shell verb like "edit" from .bat or command-line

How can I start a file with an associated non-default command (shell verb) like "edit", "print", ... from command-line or from a .bat script by using standard Windows means.
(Those extra actions which you get offered on top upon right-click on a file in the Windows Explorer.)
Thus getting the effect of
python -c "import os;os.startfile('somepic.png', 'edit')"
(ShellExecuteEx), but without using extra tools like python, powershell, or so.
The START command does not seem to offer that.
As learned from the comments and after further searching: there seems to be no direct command for that task in standard Windows indeed.
However using a VBScript snippet should be highly compatible and have lowest system requirements. (Works on all machines here directly - from XP - unlike JScript)
VBScript has been installed by default in every desktop release of
Microsoft Windows since Windows 98;1 in Windows Server since Windows
NT 4.0 Option Pack;[2] and optionally with Windows CE (depending on
the device it is installed on).
Example script shellexec.vbs :
' shellexec.vbs : starts a file using a (non-default) shell verb like "EDIT"
' Usage: shellexec.vbs FILE VERB
' Example: shellexec.vbs demo.png EDIT
fn = WScript.Arguments(0)
cmd = WScript.Arguments(1)
Wscript.Echo "ShellExecute """ + cmd + """ on " + fn
CreateObject("shell.application").ShellExecute fn, "", "", cmd, 1
Use from command-line or batch-file:
shellexec.vbs demo.png EDIT
or:
cscript.exe //Nologo shellexec.vbs demo.png EDIT
An example to show how to do it with an one-liner:
mshta vbscript:Execute("CreateObject(""shell.application"").ShellExecute""%SystemDrive%\autoexec.bat"","""","""",""edit"",1:close")
It will open the dummy autoexec.bat file with the application defined to edit .bat files (by default, Notepad).
It is possible to do with batch code what is done by command START for default action of opening a file with associated application.
In the commented batch code below the shell verb must be specified in third line being assigned to environment variable ActionCommand.
The name of the file to edit, printto, ... must be specified as first parameter of the batch file.
#echo off
setlocal EnableExtensions EnableDelayedExpansion
set "ActionCommand=edit"
rem Check if batch file was started with name of an existing file.
if "%~1" == "" set "ErrMsg=No file name specified as argument on starting %~nx0" & goto OutputError
if exist "%~1\" set "ErrMsg="%~f1" is a directory and not a file" & goto OutputError
if not exist "%~f1" set "ErrMsg=A file "%~f1" does not exist" & goto OutputError
rem Check if specified file has a file extension. Files starting with . and
rem not containing at least a second . are also files with no file extension.
if "%~n1" == "" set "ErrMsg=File "%~f1" has no file extension" & goto OutputError
if "%~x1" == "" set "ErrMsg=File "%~f1" has no file extension" & goto OutputError
rem On Windows Vista and later REG.EXE outputs without version info for example:
rem HKEY_CLASSES_ROOT\.txt
rem (Default) REG_SZ txtfile
rem There are only spaces used to separate value name, value type and value string.
rem But REG.EXE version 3.0 outputs on Windows XP with version info for example:
rem ! REG.EXE VERSION 3.0
rem
rem HKEY_CLASSES_ROOT\.txt
rem <NO NAME> REG_SZ txtfile
rem NOTE: There are 4 indent spaces and 2 separating tabs in REG 3.0 output line.
rem So either token 2 or token 3 contains value type REG_SZ
rem used to identify the line with the wanted information.
set "TypeToken=2"
rem Get name of registry key associated with extension of specified file.
:GetAssociatedKey
for /F "skip=1 tokens=%TypeToken%*" %%A in ('%SystemRoot%\System32\reg.exe query "HKCR\%~x1" /ve 2^>nul') do (
if "%%A" == "REG_SZ" set "KeyName=%%B" & goto GetCommand
if "%%A" == "NAME>" set "TypeToken=3" & goto GetAssociatedKey
)
set "ErrMsg=No file assocation found for %~x1 in registry" & goto OutputError
:GetCommand
for /F "skip=1 tokens=%TypeToken%*" %%A in ('%SystemRoot%\System32\reg.exe query "HKCR\!KeyName!\shell\%ActionCommand%\command" /ve 2^>nul') do (
if "%%A" == "REG_SZ" set "ActionCommand=%%B" & goto PrepareCommand
if "%%A" == "REG_EXPAND_SZ" set "ActionCommand=%%B" & goto PrepareCommand
)
set "ErrMsg=No edit command found for %~x1 in registry" & goto OutputError
rem Replace "%1" or %1 by full name of specified file in double quotes or
rem append a space and full name of specified file if the command string
rem does not contain "%1" or %1 at all. Then expand the command string.
:PrepareCommand
set "ActionCommand=!ActionCommand:"%%1"="%~f1"!"
set "ActionCommand=!ActionCommand:%%1="%~f1"!"
if "!ActionCommand:%~f1=!" == "!ActionCommand!" set "ActionCommand=!ActionCommand! "%~f1""
call set "ActionCommand=%ActionCommand%"
rem Run the command with current directory set for the application to folder
rem of specified file without checking if the executable file exists at all.
rem Command start displays an error message box which must be confirmed by
rem the user by a click on button OK and outputs the error message also to
rem console if the executable to start could not be found.
start "" /D"%~dp1" %ActionCommand%
endlocal
goto :EOF
:OutputError
echo %~f0
echo.
echo Error: !ErrMsg!.
echo.
echo Press any key to exit batch processing ...
endlocal
pause >nul
This batch file might not work for all possible action commands, but it should work for 99.5% of all edit, printto, ... commands.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /?
echo /?
endlocal /?
for /?
goto /?
if /?
pause /?
reg query /?
rem /?
set /?
setlocal /?
start /?
Not sure if this is what you are looking for, but using the START command opens the file I want to edit in the default program.
START "" "Mypdf.pdf"
START "" "Myfile.txt"
START "" "Myjpg.jpg"
ETCETERA ETCETERA........

How to get attributes of a file using batch file

I am trying to make a batch file to delete malicious files from pendrive. I know that these malicious files uses hidden,read only and system attributes mainly to hide itself from users. Currently i am deleting these files using cmd by removing malicious files attributes then deleting it. Now I am thinking to make a small batch file which can be used to remove these files just by entering the drive letter.
I have found this code in a website to find attributes of a file. But after entering the name of the file the batch file just exits without showing any results.
#echo off
setlocal enabledelayedexpansion
color 0a
title Find Attributes in Files
:start
set /p atname=Name of the file:
if not exist %atname% (
cls
echo No file of that name exists!
echo.
echo Press any key to go back
pause>nul
goto start
)
for /f %%i in (%atname%) do set attribs=%%~ai
set attrib1=!attribs:~0,1!
set attrib2=!attribs:~1,1!
set attrib3=!attribs:~2,1!
set attrib4=!attribs:~3,1!
set attrib5=!attribs:~4,1!
set attrib6=!attribs:~5,1!
set attrib7=!attribs:~6,1!
set attrib8=!attribs:~7,1!
set attrib9=!attribs:~8,1!
cls
if %attrib1% equ d echo Directory
if %attrib2% equ r echo Read Only
if %attrib3% equ a echo Archived
if %attrib4% equ h echo Hidden
if %attrib5% equ s echo System File
if %attrib6% equ c echo Compressed File
if %attrib7% equ o echo Offline File
if %attrib8% equ t echo Temporary File
if %attrib9% equ l echo Reparse point
echo.
echo.
echo Press any key to go back
pause>nul
goto start
can you tell me why this batch file is exiting without showing any results. Or can you give any better batch script for getting attributes of a file.
EDIT
I was able to work the above code only for a single file. As my purpose of my batch file is to remove malicious files by entering the drive letter. How can i use it to find what kind of attributes files are using in a particular drive.
For example:
In cmd we can use this command to find the file attributes of a given drive
attrib *.*
Advance thanks for your help
I tried the bat file (without inspecting the details) and it seems to work fine for me. What I noticed is that it closes instantly if you don't enclose file path with quotation marks - e.g. "file". Example:
Name of the file: path\file.txt // this will close immediately
Name of the file: "path\file.txt" // now it will stay open and display the result
This hopefully solves your problem.
As far as your question in EDIT is concerned, a simple option is to iterate a list of files and execute the batch on each one.
batch1.bat: (%1 refers to the first command-line parameter)
#echo off
setlocal enabledelayedexpansion
echo %1
set atname=%1
for %%i in ("%atname%") do set attribs=%%~ai
set attrib1=!attribs:~0,1!
set attrib2=!attribs:~1,1!
set attrib3=!attribs:~2,1!
set attrib4=!attribs:~3,1!
set attrib5=!attribs:~4,1!
set attrib6=!attribs:~5,1!
set attrib7=!attribs:~6,1!
set attrib8=!attribs:~7,1!
set attrib9=!attribs:~8,1!
cls
if %attrib1% equ d echo Directory
if %attrib2% equ r echo Read Only
if %attrib3% equ a echo Archived
if %attrib4% equ h echo Hidden
if %attrib5% equ s echo System File
if %attrib6% equ c echo Compressed File
if %attrib7% equ o echo Offline File
if %attrib8% equ t echo Temporary File
if %attrib9% equ l echo Reparse point
echo.
echo.
Next, generate a list of all files within a given path (say 'folder' including all subfolders):
dir /s /b folder > ListOfFiles.txt
main.bat (read ListOfFiles.txt line-by-line and pass each line to batch1.bat as a command line parameter):
#echo off
for /f "tokens=*" %%l in (ListOfFiles.txt) do (batch1.bat %%l)
Then, from cmd:
main.bat >> output.txt
The last step generates an output file with complete results. Granted, this can be done in a more polished (and probably shorter) way, but that's one obvious direction you could take.
You're using a for /f loop here, which isn't necessary (and may yield undesired results if the filename contains spaces). Change this:
for /f %%i in (%atname%) do set attribs=%%~ai
into this:
for %%i in ("%atname%") do set attribs=%%~ai
This is dangerous code - but it'll delete read only, hidden and system files.
It should fail to run on c: drive but I haven't tested it. Note that some Windows installs are on drives other than c:
#echo off
echo "%cd%"|find /i "c:\" >nul || (
del *.??? /ar /s /f
del *.??? /ah /s
del *.??? /as /s
)

Windows batch file - check if file has been modified

I'm configuring a windows machine to continuously run a powerpoint presentation. The ppt file is located on a samba share (windows file sharing) and will be updated periodically. I need a way to make a batch file that will restart the ppt slide show if the file has been changed. The batch script will run on a a regular interval, and will hopefully check to see if the file has been updated, and re-start the slideshow if it has.
If there is a way to do this in powershell, that would work too.
Well, in a batch, the easiest way I would think of would be to periodically check whether the file's last modification date and/or its size has changed.
You can get both via the following:
for %%X in (myfile) do set size=%%~zX&set filetime=%%~tX
You can then cache those values and compare whether they have changed since the last iteration. Using a delay (a few seconds maybe) via
ping -n 11 localhost >nul 2>nul
(for 10 seconds delay) can help in not checking too often.
So, it might look a little like the following:
#echo off
setlocal
set FileName=MyPresentation.pptx
set FileTime=-
:loop
for %%X in (%FileName%) do (
if %FileTime% NEQ %%~tX (
rem just an example
taskkill /f powerpnt.exe
start %FileName%
)
set FileTime=%%~tX
)
rem wait 5 seconds before checking again
ping -n 6 localhost >nul 2>nul
goto :loop
In PowerShell the code wouldn't look too different, except that you get to the relevant properties a little easier:
$FileName = "MyPresentation.pptx"
$FileTime = Get-Date
# endless loop
for () {
$file = Get-Item $FileName
if ($FileTime -ne $file.LastWriteTime) {
Get-Process powerpnt* | Stop-Process
Invoke-Item $file
}
$FileTime = $file.LastWriteTime
Start-Sleep 5
}
Try the code below. It checks for the current time and checks when the file was last modified. If the two values are the same it is assumed the file was altered.
#echo off &setlocal
TITLE File Monitor
Set file=Test.txt
:CheckforAlter
Set modif_time=
Set allm=
cls
for /f "tokens=1-3 delims=:,. " %%A in ("%time%") do (
set "Hour=%%A"
set "Min=%%B"
set "Sec=%%C"
)
set /a Hour = Hour %% 12
if %Hour%==0 set "Hour=12"
set "Allm=%Hour%:%Min%:%Sec%"
for /f %%i in ('"forfiles /m %file% /c "cmd /c echo #ftime" "') do set modif_time=%%i
echo.
echo.
IF %modif_time%==%Allm% (
echo File was altered.
start "" "%file%"
Timeout /t 1 >nul
)
echo file wasn't modified.
GOTO CheckforAlter
Found this:
#echo off
if not "%~1"=="" echo Modified date of %~1 is %~t1
on Experts exchange. Maybe a good point to start from.

Resources