How do I retrieve the version of a file from a batch file on Windows Vista? - windows-vista

Binary files have a version embedded in them - easy to display in Windows Explorer.
How can I retrieve that file version, from a batch file?

and three ways without external tools
1.WMIC
WMIC DATAFILE WHERE name="C:\\install.exe" get Version /format:Textvaluelist
Pay attention to the double slashes of file name.
Ready to use script:
#echo off
:wmicVersion pathToBinary [variableToSaveTo]
setlocal
set "item=%~1"
set "item=%item:\=\\%"
for /f "usebackq delims=" %%a in (`"WMIC DATAFILE WHERE name='%item%' get Version /format:Textvaluelist"`) do (
for /f "delims=" %%# in ("%%a") do set "%%#"
)
if "%~2" neq "" (
endlocal & (
echo %version%
set %~2=%version%
)
) else (
echo %version%
)
2.MAKECAB
as the WMIC is not installed on home versions of windows here's a way with makecab that will run on every windows machine:
; #echo off
;;goto :end_help
;;setlocal DsiableDelayedExpansion
;;;
;;;
;;; fileinf /l list of full file paths separated with ;
;;; fileinf /f text file with a list of files to be processed ( one on each line )
;;; fileinf /? prints the help
;;;
;;:end_help
; REM Creating a Newline variable (the two blank lines are required!)
; set NLM=^
; set NL=^^^%NLM%%NLM%^%NLM%%NLM%
; if "%~1" equ "/?" type "%~f0" | find ";;;" | find /v "find" && exit /b 0
; if "%~2" equ "" type "%~f0" | find ";;;" | find /v "find" && exit /b 0
; setlocal enableDelayedExpansion
; if "%~1" equ "/l" (
; set "_files=%~2"
; echo !_files:;=%NL%!>"%TEMP%\file.paths"
; set _process_file="%TEMP%\file.paths"
; goto :get_info
; )
; if "%~1" equ "/f" if exist "%~2" (
; set _process_file="%~2"
; goto :get_info
; )
; echo incorect parameters & exit /b 1
; :get_info
; set "file_info="
; makecab /d InfFileName=%TEMP%\file.inf /d "DiskDirectory1=%TEMP%" /f "%~f0" /f %_process_file% /v0>nul
; for /f "usebackq skip=4 delims=" %%f in ("%TEMP%\file.inf") do (
; set "file_info=%%f"
; echo !file_info:,=%nl%!
; )
; endlocal
;endlocal
; del /q /f %TEMP%\file.inf 2>nul
; del /q /f %TEMP%\file.path 2>nul
; exit /b 0
.set DoNotCopyFiles=on
.set DestinationDir=;
.set RptFileName=nul
.set InfFooter=;
.set InfHeader=;
.Set ChecksumWidth=8
.Set InfDiskLineFormat=;
.Set Cabinet=off
.Set Compress=off
.Set GenerateInf=ON
.Set InfDiskHeader=;
.Set InfFileHeader=;
.set InfCabinetHeader=;
.Set InfFileLineFormat=",file:*file*,date:*date*,size:*size*,csum:*csum*,time:*time*,vern:*ver*,vers:*vers*,lang:*lang*"
example output (it has a string version which is a small addition to wmic method :) ):
c:> fileinfo.bat /l C:\install.exe
file:install.exe
date:11/07/07
size:562688
csum:380ef239
time:07:03:18a
vern:9.0.21022.8
vers:9.0.21022.8 built by: RTM
lang:1033
3 Using shell.application and hybrid batch\jscript.Here's tooptipInfo.bat :
#if (#X)==(#Y) #end /* JScript comment
#echo off
rem :: the first argument is the script name as it will be used for proper help message
cscript //E:JScript //nologo "%~f0" %*
exit /b %errorlevel%
#if (#X)==(#Y) #end JScript comment */
//////
FSOObj = new ActiveXObject("Scripting.FileSystemObject");
var ARGS = WScript.Arguments;
if (ARGS.Length < 1 ) {
WScript.Echo("No file passed");
WScript.Quit(1);
}
var filename=ARGS.Item(0);
var objShell=new ActiveXObject("Shell.Application");
/////
//fso
ExistsItem = function (path) {
return FSOObj.FolderExists(path)||FSOObj.FileExists(path);
}
getFullPath = function (path) {
return FSOObj.GetAbsolutePathName(path);
}
//
//paths
getParent = function(path){
var splitted=path.split("\\");
var result="";
for (var s=0;s<splitted.length-1;s++){
if (s==0) {
result=splitted[s];
} else {
result=result+"\\"+splitted[s];
}
}
return result;
}
getName = function(path){
var splitted=path.split("\\");
return splitted[splitted.length-1];
}
//
function main(){
if (!ExistsItem(filename)) {
WScript.Echo(filename + " does not exist");
WScript.Quit(2);
}
var fullFilename=getFullPath(filename);
var namespace=getParent(fullFilename);
var name=getName(fullFilename);
var objFolder=objShell.NameSpace(namespace);
var objItem=objFolder.ParseName(name);
//https://msdn.microsoft.com/en-us/library/windows/desktop/bb787870(v=vs.85).aspx
WScript.Echo(fullFilename + " : ");
WScript.Echo(objFolder.GetDetailsOf(objItem,-1));
}
main();
used against cmd.exe :
C:\Windows\System32\cmd.exe :
File description: Windows Command Processor
Company: Microsoft Corporation
File version: 6.3.9600.16384
Date created: ?22-?Aug-?13 ??13:03
Size: 347 KB

The file version could be simply read without external tools by PowerShell like this:
(Get-Item myFile.exe).VersionInfo.FileVersion
and if you want to read it from an Batch file use:
powershell -NoLogo -NoProfile -Command (Get-Item myFile.exe).VersionInfo.FileVersion
and to save the file version to a variable use:
FOR /F "USEBACKQ" %%F IN (`powershell -NoLogo -NoProfile -Command ^(Get-Item "myFile.exe"^).VersionInfo.FileVersion`) DO (SET fileVersion=%%F)
echo File version: %fileVersion%
I've taken a realtive path here, you could also define it absolutely, like: C:\myFile.dll
More information about the file is shown if you omit .FileVersion

Check out sigcheck.exe from Sysinternals Suite. This is a command-line utility that shows file version number, timestamp information, and digital signature details.

Here is a solution in PowerShell using FileVersionInfo.

I think filever is what you need. It can get the file version for multiple items at the same time and locate files (e.g. EXE, DLL) that differ in size or version number.

Here is my try using WMIC to get file version of all *.exe and *.dll inside the directory of Skype as example :
#echo off
Mode 75,3 & color 9E
Title Get File Version of any Program from file list using WMIC by Hackoo
Set "RootFolder=%ProgramFiles%\Skype"
#for %%a in (%RootFolder%) do set "FolderName=%%~na"
Set "File_Version_List=%~dp0%FolderName%_File_Version_List.txt"
Set "ErrorFile=%~dp0%FolderName%_Error.txt
Set Extensions="*.exe" "*.dll"
If exist "%ErrorFile%" Del "%ErrorFile%"
If exist "%File_Version_List%" Del "%File_Version_List%"
echo(
echo Please wait a while ... Process to get file version ...
set "BuildLineWith=call :BuildLine "
setlocal enabledelayedexpansion
CD /D "%RootFolder%"
#for /f "delims=" %%F in ('Dir /b /s %Extensions%') do (
set "Version="
Call :Get_AppName "%%F" AppName
Call :Add_backSlash "%%F"
Call :GetVersion !Application! Version
Call :Remove_backSlash !Application!
If defined Version (
(
echo !Application!
echo !AppName! ==^> !Version!
%BuildLineWith%*
)>> "%File_Version_List%"
) else (
(
echo Version is not defined in !Application!
%BuildLineWith%#
)>> "%ErrorFile%"
)
)
If Exist "%ErrorFile%" Start "" "%ErrorFile%"
If Exist "%File_Version_List%" Start "" /MAX "%File_Version_List%" & Exit
::*******************************************************************
:GetVersion <ApplicationPath> <Version>
Rem The argument %~1 represente the full path of the application
Rem without the double quotes
Rem The argument %2 represente the variable to be set (in our case %2=Version)
FOR /F "tokens=2 delims==" %%I IN (
'wmic datafile where "name='%~1'" get version /format:Textvaluelist 2^>^nul'
) DO FOR /F "delims=" %%A IN ("%%I") DO SET "%2=%%A"
Exit /b
::*******************************************************************
:Add_backSlash <String>
Rem Subroutine to replace the simple "\" by a double "\\" into a String
Set "Application=%1"
Set "String=\"
Set "NewString=\\"
Call Set "Application=%%Application:%String%=%NewString%%%"
Exit /b
::*******************************************************************
:Remove_backSlash <String>
Rem Subroutine to replace the double "\\" by a simple "\" into a String
Set "Application=%1"
Set "String=\\"
Set "NewString=\"
Call Set "Application=%%Application:%String%=%NewString%%%"
Exit /b
::*******************************************************************
:Get_AppName <FullPath> <AppName>
Rem %1 = FullPath
Rem %2 = AppName
for %%i in (%1) do set "%2=%%~nxi"
exit /b
::*******************************************************************
:BuildLine
set "LineChar=%1"
if "%LineChar%"=="" set "LineChar=_"
for /f "tokens=2 skip=4" %%A in ('mode con: /status') do set "WindowColumns=%%A" & goto :GotColumnCount
:GotColumnCount
set "CharLine="
setlocal EnableDelayedExpansion
for /L %%A in (1,1,%WindowColumns%) do set "CharLine=!CharLine!!LineChar:~0,1!"
setlocal DisableDelayedExpansion
endlocal
echo %CharLine%
goto :eof
::*******************************************************************

I've found this code from Rob Vanderwoude's site:
#ECHO OFF
IF [%1]==[] GOTO Syntax
IF NOT [%2]==[] GOTO Syntax
ECHO.%1 | FIND "?" >NUL
IF NOT ERRORLEVEL 1 GOTO Syntax
IF NOT EXIST %1 GOTO Syntax
IF NOT "%OS%"=="Windows_NT" GOTO Syntax
SETLOCAL
SET FileVer=
FOR /F "tokens=1 delims=[]" %%A IN ('STRINGS %1 ^| FIND /N /V "" ^| FIND /I "FileVersion"') DO SET LineNum=%%A
SET /A LineNum += 1
FOR /F "tokens=1* delims=[]" %%A IN ('STRINGS %1 ^| FIND /N /V "" ^| FIND "[%LineNum%]"') DO SET FileVer=%%B
SET FileVer
ENDLOCAL
GOTO:EOF
:Syntax
ECHO.
ECHO FileVer.bat, Version 1.00 for NT 4 / 2000 / XP
ECHO Display the specified file's version number
ECHO.
ECHO Usage: FILEVER progfile
ECHO.
ECHO Where: "progfile" is the name of a Windows executable, DLL, or system file
ECHO.
ECHO Uses SysInternal's STRINGS.EXE, avalable at http://www.sysinternals.com
ECHO.
ECHO Written by Rob van der Woude
ECHO http://www.robvanderwoude.com
Looks interesting as it uses STRINGS from SysInternals.

Related

How can I automatically uninstall all programs containing "VNC" in their displayname using a batch file?

I am attempting to create a batch script that will query the registry for uninstall packages. The goal is to create a batch script that will uninstall all VNC programs (UltraVNC, RealVNC, and TightVNC). This must be compatible with both Windows XP and Windows 7.
I started with the script from this StackOverflow solution Reg Query script for batch script . I am trying to alter the code to allow it to search for "VNC" in the DisplayName, strip the text between the {} in its corresponding UninstallPath, and then run msiexec.exe /qn /x {package-identifier} to silently uninstall the program.
When running the following code, it retrieves several programs that do not contain "VNC" in their DisplayName. The issue appears to lie in the following line of code:
if not "x!str1:VNC=!"=="x!str1!" (
Source of this line of code: How can I check if a variable contains another variable within a windows batch file?
I have tried the following code found at as an alternative, but it also listed way too many packages and did not properly pick only packages with "VNC" in their names.
set str1 = !product[%counter%]!
echo str1 > temp.dat
findstr /c:"VNC" "temp.dat" >nul 2>&1
if %errorlevel% == 0 (
Note: Many of the echo commands are there simply for testing purposes.
#echo off
setlocal
set regVar=HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
set excluded=/c:" Microsoft" /c:"MDOP" /c:"Dell"
set count=1
for /f "tokens=1,2,*" %%a in ('Reg Query %regVar% /S ^| findstr "DisplayName HKEY_ UninstallString"') do (
setlocal EnableDelayedExpansion
for %%n in (!count!) do (
ENDLOCAL
SET HKEY=Y
IF "%%a"=="DisplayName" SET "HKEY="&set product[%%n]=%%c
IF "%%a"=="UninstallString" SET "HKEY="&IF NOT DEFINED uninstall[%%n] set uninstall[%%n]=%%c
IF "%%a"=="QuietUninstallString" SET "HKEY="&IF NOT DEFINED uninstall[%%n] set uninstall[%%n]=%%c
IF DEFINED hkey IF DEFINED product[%%n] IF defined uninstall[%%n] SET /a count+=1&SET "hkey="
IF DEFINED hkey set "product[%%n]="&SET "uninstall[%%n]="
)
)
IF NOT DEFINED product[%count%] SET "uninstall[%count%]="&SET /a count-=1
IF NOT DEFINED uninstall[%count%] SET "product[%count%]="&SET /a count-=1
ECHO %count% entries found
set counter=%count%
pause
#setlocal enableextensions enabledelayedexpansion
:while
if %counter% GTR 0 (
set str1 = !product[%counter%]!
echo str1
if not "x!str1:VNC=!"=="x!str1!" (
echo !product[%counter%]!
echo !uninstall[%counter%]!
set UninstallString=!uninstall[%counter%]!
echo !UninstallString!
set RunUninstall = ""
for /f "tokens=2 delims={}" %%A in ("!uninstall[%counter%]!") do echo %%A REM set RunUninstall="msiExec.exe /qn /x{%%A}" (commented for testing purposes)
call !RunUninstall!
set /a counter-=1
GOTO While
) Else (
set /a counter-=1
GOTO While
)
)
Output Snippet:
Intel(R) Network Connections 15.7.176.0
MsiExec.exe /X{26A24AE4-039D-4CA4-87B4-2F86418051F0}
MsiExec.exe /X{26A24AE4-039D-4CA4-87B4-2F86418051F0}
26A24AE4-039D-4CA4-87B4-2F86418051F0 REM set RunUninstall="msiExec.exe /qn /x{26
A24AE4-039D-4CA4-87B4-2F86418051F0}"
ECHO is off.
Microsoft .NET Framework 4.5.2
MsiExec.exe /X{26784146-6E05-3FF9-9335-786C7C0FB5BE}
MsiExec.exe /X{26784146-6E05-3FF9-9335-786C7C0FB5BE}
26784146-6E05-3FF9-9335-786C7C0FB5BE REM set RunUninstall="msiExec.exe /qn /x{26
784146-6E05-3FF9-9335-786C7C0FB5BE}"
ECHO is off.
Lenovo ThinkVantage Toolbox
MsiExec.exe /I{23170F69-40C1-2702-0920-000001000000}
MsiExec.exe /I{23170F69-40C1-2702-0920-000001000000}
23170F69-40C1-2702-0920-000001000000 REM set RunUninstall="msiExec.exe /qn /x{23
170F69-40C1-2702-0920-000001000000}"
ECHO is off.
OSFMount v1.5
MsiExec.exe /I{1B8ABA62-74F0-47ED-B18C-A43128E591B8}
MsiExec.exe /I{1B8ABA62-74F0-47ED-B18C-A43128E591B8}
1B8ABA62-74F0-47ED-B18C-A43128E591B8 REM set RunUninstall="msiExec.exe /qn /x{1B
8ABA62-74F0-47ED-B18C-A43128E591B8}"
UPDATE:
I modified the code provided by wOxxOm in an attempt to make an exception for TightVNC and uninstall it quietly. Since there is not a QuietUninstallString in the registry for TightVNC, I am attempting to accomplish this by utilizing the msiexec.exe /qn /x options. However it keeps throwing the following error:
else was unexpected at this time.
My modified version of wOxxOm's code is listed below:
#echo off
setlocal enableDelayedExpansion
for %%a in ("" "\Wow6432Node") do (
for /f "delims=" %%b in ('
reg query HKLM\SOFTWARE%%~a\Microsoft\Windows\CurrentVersion\Uninstall ^
/s /d /f "VNC" ^| findstr "HKEY_ DisplayName"
') do (
set "line=%%b"
if "!line:~0,4!"=="HKEY" (
set "key=!line!"
) else (
set Uninstall=
rem Sort /r makes QuietUninstallString the last line
for /f "tokens=2*" %%c in ('
reg query "!key!" ^| find "UninstallString" ^| sort /r
') do if not "%%d"=="" set "Uninstall=%%d"
if defined Uninstall (
for /f "tokens=2*" %%c in ("!line!") do (
set product=%%d
if "x!product:TightVNC=!"=="x!product!" (
for /f "tokens=2 delims={}" %%A in ("!Uninstall!") do (
echo Found !product!
Running msiExec.exe /qn /x{%%A} REM (COMMENTED FOR TESTING)
REM CALL msiExec.exe /qn /x{%%A}
)
) else (
echo Found %%d
echo Running !Uninstall! (COMMENTED FOR TESTING)
rem call !Uninstall!
echo.
)
)
)
)
)
Don't use spaces around = in set str1=!product[%counter%]!
Instead of if %counter% GTR 0 ( which doesn't work and makes the loop infinite)
use if %counter%==0 goto done and a :done label after the loop
With quotes you don't need to add x to the comparison.
Don't forget about 64-bit Windows and check Wow6432Node tree too (see the alternative code)
:while
if %counter%==0 goto done
set str1=!product[%counter%]!
if not "!str1:VNC=!"=="!str1!" (
..............................
rem call !RunUninstall!
)
set /a counter-=1
GOTO While
:done
Alternatively you can make the batch file much faster (the "arrays" are slow in case of many strings) by listing only the products with VNC in DisplayName first and then fetch the UninstallString:
#echo off
setlocal enableDelayedExpansion
for %%a in ("" "\Wow6432Node") do (
for /f "delims=" %%b in ('
reg query HKLM\SOFTWARE%%~a\Microsoft\Windows\CurrentVersion\Uninstall ^
/s /d /f "VNC" ^| findstr "HKEY_ DisplayName"
') do (
set "line=%%b"
if "!line:~0,4!"=="HKEY" (
set "key=!line!"
) else (
set Uninstall=
rem Sort /r makes QuietUninstallString the last line
for /f "tokens=2*" %%c in ('
reg query "!key!" ^| find "UninstallString" ^| sort /r
') do if not "%%d"=="" set "Uninstall=%%d"
if defined Uninstall (
for /f "tokens=2*" %%c in ("!line!") do echo Found %%d
echo Running !Uninstall! (COMMENTED FOR TESTING)
rem call !Uninstall!
echo.
)
)
)
)
pause
Modifying wOxxOm's code, I was able to create the following code to quietly uninstall TightVNC, UltraVNC, and RealVNC. It will also start the uninstaller for any other software with "VNC" in the DisplayName in the Windows registry under HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall and HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall.
Hopefully this is handy to someone else out there as well.
#echo off
setlocal enableDelayedExpansion
for %%a in ("" "\Wow6432Node") do (
for /f "delims=" %%b in ('
reg query HKLM\SOFTWARE%%~a\Microsoft\Windows\CurrentVersion\Uninstall ^
/s /d /f "VNC" ^| findstr "HKEY_ DisplayName"
') do (
set "line=%%b"
if "!line:~0,4!"=="HKEY" (
set "key=!line!"
) else (
set Uninstall=
rem Sort /r makes QuietUninstallString the last line
for /f "tokens=2*" %%c in ('
reg query "!key!" ^| find "UninstallString" ^| sort /r
') do if not "%%d"=="" set "Uninstall=%%d"
if defined Uninstall (
for /f "tokens=2*" %%c in ("!line!") do (
set product=%%d
if NOT "x!product:TightVNC=!"=="x!product!" (
for /f "tokens=2 delims={}" %%A in ("!Uninstall!") do (
echo Found !product!
CALL msiExec.exe /qn /x{%%A}
echo.
)
) else (
if NOT "x!product:UltraVNC=!"=="x!product!" (
for /f "tokens=1 delims=." %%A in ("!Uninstall!") do (
echo Found !product!
CALL %%A.exe" /VERYSILENT /NORESTART
echo.
)
) else (
if NOT "x!Uninstall:RealVNC=!"=="x!Uninstall!" (
for /f "tokens=1 delims=." %%A in ("!Uninstall!") do (
echo Found !product!
CALL %%A.exe" /VERYSILENT
echo.
)
) else (
echo Found %%d
CALL !Uninstall!
echo.
)
)
)
)
)
)
)
)

Windows batch script issue

I am having an issue with the following Windows batch script. I have multiple XML files in the %indir% that I want to import one at a time and email the report. Basically the section starting with "if /I %v_continue% == y" is not executing as expected. I did some debugging step by step with echo on, and it goes through the script till the %BLAT% command without executing any of the steps, and then it starts execution with the first "copy %script_path%.....". It executes the import.exe correctly, but then nothing gets assigned to %subj% and subsequently the %BLAT% command fails. Any advice?
Thanks!
#echo off
set environment=%1
set domain=%2
if [%environment%] == [] goto :endofscript
rem - Get the script path
set script_path=%~dp0
rem - Get the script name without the extension
set script_name=%~n0
rem - Get the script name with the extension
rem set script_name=%~nx0
rem - get the script extension
set script_ext=%~x0
rem - Set environment variables
call %script_path%\setenv.cmd
set cnt=0
set filemask=*.xml
for /f %%a in ('dir /b /a-d %indir%\%filemask%') do call :procfile %%a
goto :EOF
:procfile
set impfile=%1
set v_continue=n
set emailyn=y
set trset=%impfile:~0,3%
set /A cnt + = 1
if 1%cnt% lss 100 set cnt=0%cnt%
if %trset% == RCT (
set "subtxt=Receipt Confirmation"
set v_continue=y
)
if %trset% == SHP (
set "subtxt=Shipment Confirmation"
set v_continue=y
setlocal EnableDelayedExpansion
set MOFound=
for /f "tokens=3 delims= " %%f in ('find /i /c "<RefID>MO-ORD</RefID>" %indir%\%impfile%') do (set MOFound=%%f)
if !MOFound! GTR 0 (
copy %indir%\%impfile% %inarchdir%
move %indir%\%impfile% %S_INDIR%\FX%dttmstamp%%cnt%.xml 2>NUL
goto :EOF
)
endlocal
)
if /I %v_continue% == y (
copy %script_path%\%script_name%.dat %infile%
cscript %REPLACEVBS% %infile% "DOMAIN" "%domain%" 1>NUL 2>&1
cd /d %rptdir%
%DLC%\bin\import.exe -b -T d:\tmp -p %pfile%
rem - Check for errors
find /i /c "ERROR:" %rptfile% > NUL
if %ERRORLEVEL% NEQ 0 (
set "subj=SUCCESS: %subtxt% Import Report (%environment%/%domain%)"
set emailyn=y
) else (
set "subj=ERROR: %subtxt% Import Report (%environment%/%domain%)"
set emailyn=y
)
move %rptfile% %logdir%\%script_name%_%datestamp%_%cnt%.prn 2>NUL
move %outfile% %logdir%\%script_name%_%datestamp%_%cnt%.out 2>NUL
if /I %emailyn% == y (
echo Report location: %logdir%\%script_name%_%datestamp%_%cnt%.prn > %msgfile%
%BLAT% %msgfile% -server abc-com.mail.protection.outlook.com -f donotreply#abc.com -s "%subj%" -t %INBEMAIL% -attachi %logdir%\%script_name%_%datestamp%_%cnt%.prn
)
)
del /f /q %infile%
del /f /q %pfile%
del /f /q %msgfile%
:delfiles
rem - Delete log files that are older than 10 days.
PushD "%logdir%" && (
forfiles /M %script_name%_*.prn /D -10 /C "CMD /C del /f /q #PATH" 2>NUL
) & PopD
:endofscript
exit /B

Rename File with Creation Date & Time in Windows Batch

I have a directory tree with thousands of pdfs and tifs. A folder may contain multiple pdfs or tifs in that case they are numbered 1.pdf, 2.pdf etc... I have to make them available and making sure they are maually processed oldest files first - so I want to rename them with their creation date and time (1.pdf -> 20150415481876.pdf):
Currently I use
#echo off
set datetime=%~t1
set name=%~n1
set extension=%~x1
set year=%datetime:~6,4%
set month=%datetime:~3,2%
set day=%datetime:~0,2%
set hour=%datetime:~11,2%
set min=%datetime:~14,2%
ren %1 "%year%%month%%day%%hour%%min%%name%%extension%"
This can now properly rename a file 1.tif to 2014052513241.tif (file created 25.05.2014 13:24). But how can i make this able to handle multiple file in the same folder (e.g. 1.tif 2.tif 3.tif) if i call the batch with batch.bat *.tif?
Thank you
#if (#X)==(#Y) #end /* JScript comment
#echo off
set "extension=tiff"
set "directory=c:\somedir"
pushd "%directory%"
setlocal enableDelayedExpansion
for %%a in (*%extension%) do (
for /f %%# in ('cscript //E:JScript //nologo "%~f0" %%a') do set "cdate=%%#"
echo ren "%%a" "!cdate!%%~xa"
)
rem cscript //E:JScript //nologo "%~f0" %*
exit /b %errorlevel%
#if (#X)==(#Y) #end JScript comment */
FSOObj = new ActiveXObject("Scripting.FileSystemObject");
var ARGS = WScript.Arguments;
var file=ARGS.Item(0);
var d1=FSOObj.GetFile(file).DateCreated;
d2=new Date(d1);
var year=d2.getFullYear();
var mon=d2.getMonth();
var day=d2.getDate();
var h=d2.getHours();
var m=d2.getMinutes();
var s=d2.getSeconds();
var ms=d2.getMilliseconds();
if (mon<10){mon="0"+mon;}
if (day<10){day="0"+day;}
if (h<10){h="0"+h;}
if (m<10){m="0"+m;}
if (s<10){s="0"+s;}
if (ms<10){ms="00"+ms;}else if(ms<100){ms="0"+ms;}
WScript.Echo(""+year+mon+day+h+m+s+ms);
set your own extension and directory to rename all files with given extension in directory to their creation date.The format will be YYYYMMDDhhmm.Renaming is echoed so you can see if everything is ok.If it is remove the echo word from the 9th line.
Here is a native Windows CMD Method of doing this (no vb/java script needed).
If you want to be really quick and simple just use this at the CMD window instead of writing a batch at all:
FOR /R "Drive:\folder\subfolder\" %Z IN (*.tiff) DO #( FOR /F "Tokens=1-6 delims=:-\/. " %A IN ("%~tZ") DO #( ren "%~dpnxZ" "%~C%~A%~B%~D%~E%~F%~nZ%~xZ") )
If you still prefer a batch/CMD file, this is a re-write of your script to work as the CMD, and re-write all of the files in a directory matching a certain search pattern to be in the format "YYYYMMDDHHM[Name][extention]"
#(
SETLOCAL
echo off
SET "_Skip=NO"
Set "_elvl=0"
)
IF /I "%~2" EQU "" (
SET "_Skip=YES"
)
IF /I "%~1" EQU "/?" (
SET "_Skip=YES"
)
IF /I "%~1" EQU "?" (
SET "_Skip=YES"
)
IF /I "%_Skip%" EQU "YES" (
ECHO. Usage:
ECHO.
ECHO. Rename.bat "Drive:\Path\" "File Glob to match"
ECHO.
ECHO. Example:
ECHO.
ECHO. Rename.bat "C:\Users\%Username%\Desktop\" "*.lnk"
ECHO.
Set "_elvl=2"
GOTO :Finish
)
ECHO. Searching through "%~1" for Files matching this pattern: "%~2"
ECHO.
FOR /R "%~1" %%Z IN (%~2) DO ( FOR /F "Tokens=1-6 delims=:-\/. " %%A IN ("%%~tZ") DO ( REN "%%~dpnxZ" "%%~C%%~A%%~B%%~D%%~E%%~F%%~nZ%%~xZ) )
ECHO.
ECHO. Completed rename of all files matching pattern "%~2" which were found within path: "%~1"
ECHO.
:Finish
(
EndLocal
EXIT /B %_elvl%
)

Batch file to compare versions of MSI file and Installed version

I have an install script currently that only installs if the product isn't already installed (by checking for the presence of the app's EXE), but I'd like to take it a step further and have it only install if the MSI version is newer than the installed version. And although it would be nice for the script to query the MSI for this, if this isn't possible, I could always update the MSI version in a variable within the script...but it would be nice if it was active query that didn't need to be always updated.
I haven't been able to find anything that can get me the MSI version, and the only place I've seen the MSI version is when I do look at File Properties -> Details -> Subject line: Product XYZ 10.2.3.
For checking the installed version, I've found:
wmic datafile where name='c:\\windows\\system32\\notepad.exe' get version
Which returns two lines, second of which is 10,2,3 (using comma's instead of decimals).
If I use:
wmic product where "name like 'Product XYZ%%'" get version
I get the same result but in the expected decimal format, but the query takes MUCH longer to run. But in either case, I still need to figure out how to actually work off the queried result.
This might be easier with a VBS, which I'm ok with, as long as I can call it within my existing batch file as well as work off the VBS result within my batch file.
Thanks in advance!
Brian
This shows the principal of extracting specific info using findstr.
#echo off
If "%~1"=="" goto help
If "%~1"=="/?" goto help
If /i "%~1"=="/h" goto help
If "%~1"=="-?" goto help
If /i "%~1"=="-h" goto help
set filepath=%~f1
set file=%filepath:\=\\%
wmic datafile where name^="%file%" get version|findstr /i /v /c:"version"
echo %errorlevel%
goto finish
:help
Echo.
Echo. FileVer
Echo. -------
Echo.
Echo. By David Candy 2013
Echo.
Echo. Purpose:
Echo.
Echo. Reports the version number for an exe, dll, and similar files.
Echo.
Echo. Usage:
Echo.
Echo. filever ^<executable file^>
Echo.
Echo. filever [/h ^| -h ^| /? ^| -?] Starts this help
Echo.
echo. Examples:
Echo.
Echo. filever c:\windows\explorer.exe
Echo. filever "C:\Program Files\Windows NT\Accessories\wordpad.exe"
Echo. filever shell32.dll
Echo.
Echo. For Help
Echo.
Echo. filever
Echo. filever /?
Echo.
:finish
rem Pause if command double clicked
If /i "%cmdcmdline:~0,6%"=="cmd /c" pause
And this shows using For
set service=%1
for /f "skip=1 tokens=1,2,3* delims= " %%a in ('sc getkeyname %service%') do echo %%c
here's a way using makecab :
; #echo off
;;goto :end_help
;;setlocal DsiableDelayedExpansion
;;;
;;;
;;; fileinf /l list of full file paths separated with ;
;;; fileinf /f text file with a list of files to be processed ( one on each line )
;;; fileinf /? prints the help
;;;
;;:end_help
; REM Creating a Newline variable (the two blank lines are required!)
; set NLM=^
; set NL=^^^%NLM%%NLM%^%NLM%%NLM%
; if "%~1" equ "/?" type "%~f0" | find ";;;" | find /v "find" && exit /b 0
; if "%~2" equ "" type "%~f0" | find ";;;" | find /v "find" && exit /b 0
; setlocal enableDelayedExpansion
; if "%~1" equ "/l" (
; set "_files=%~2"
; echo !_files:;=%NL%!>"%TEMP%\file.paths"
; set _process_file="%TEMP%\file.paths"
; goto :get_info
; )
; if "%~1" equ "/f" if exist "%~2" (
; set _process_file="%~2"
; goto :get_info
; )
; echo incorect parameters & exit /b 1
; :get_info
; set "file_info="
; makecab /d InfFileName=%TEMP%\file.inf /d "DiskDirectory1=%TEMP%" /f "%~f0" /f %_process_file% /v0>nul
; for /f "usebackq skip=4 delims=" %%f in ("%TEMP%\file.inf") do (
; set "file_info=%%f"
; echo !file_info:,=%nl%!
; )
; endlocal
;endlocal
; del /q /f %TEMP%\file.inf 2>nul
; del /q /f %TEMP%\file.path 2>nul
; exit /b 0
.set DoNotCopyFiles=on
.set DestinationDir=;
.set RptFileName=nul
.set InfFooter=;
.set InfHeader=;
.Set ChecksumWidth=8
.Set InfDiskLineFormat=;
.Set Cabinet=off
.Set Compress=off
.Set GenerateInf=ON
.Set InfDiskHeader=;
.Set InfFileHeader=;
.set InfCabinetHeader=;
.Set InfFileLineFormat=",file:*file*,date:*date*,size:*size*,csum:*csum*,time:*time*,vern:*ver*,vers:*vers*,lang:*lang*"
Here's an example if the script is called fileinfo.bat
c:> fileinfo.bat /l C:\install.exe
file:install.exe
date:11/07/07
size:562688
csum:380ef239
time:07:03:18a
vern:9.0.21022.8
vers:9.0.21022.8 built by: RTM
lang:1033
You could adapt this script maybe. The pver variable is the version string and pname tells you the name. There's a lot more you can do with vbs because there's an entire scripting engine that starts with the Installer object. Sorry about the formatting, haven't masterd thet on SO.
Option Explicit
Public installer, fullmsg, comp, prod, a, fso, pname, ploc, pid, psorce, pcache, pver
Set fso = CreateObject("Scripting.FileSystemObject")
Set a = fso.CreateTextFile("prods.txt", True)
' Connect to Windows Installer object
Set installer = CreateObject("WindowsInstaller.Installer")
a.writeline ("Products")
on error resume next
For Each prod In installer.products
pid = installer.productinfo (prod, "ProductID")
pname = installer.productinfo (prod, "ProductName")
pver = installer.productinfo (prod, "VersionString")
psorce=installer.productinfo(prod, "InstallSource")
ploc = installer.productinfo (prod, "InstallLocation")
pcache = installer.productinfo(prod, "LocalPackage")
a.writeline (prod & " " & pname & " Version " & pver & " installed at " & ploc & " from " & psorce & " cached at " & pcache)
Next

set nor working inside a for loop for windows dos cmd

I have a script that eill search for certain directories and set a list of paths for the given directories, now i want to exclude from them some recurrent unwanted ones.
Here's the script
#ECHO off
setlocal enableextensions
:start
set scriptname=%0%
set PAUSE_ON_ERROR=yes
rem #
rem ###### SECTION TO CUSTOMIZE #####
rem #
rem #
rem # This is the list of directories where instances of TECSYS iTopia installed under
rem # JBoss are located.
rem #
set jboss_dir_list=C: C:\TecsysDev\iTopiaControlPanel\trunk
rem #
rem ###### END SECTION TO CUSTOMIZE #####
rem #
set argNb=0
for %%x in (%*) do Set /A argNb+=1
if %argNb% GTR 1 (
goto :showUsage
) else if %argNb% == 0 (
set ENV_NAME=*
) else (
set ENV_NAME=*%~1*
)
:MainBlock
set scriptname=%0%
cd /d %~dp0
for /f "usebackq delims=" %%D in (`cd`) do set scriptdir=%%D
for /f "usebackq delims=" %%D in (`cd`) do set CURRENT_DIR=%%D
cd "%scriptdir%"
for /f "usebackq delims=" %%D in (`cd`) do set JBOSS_DIR=%%D
set JBOSS_DIR=%JBOSS_DIR%\..\..\..\..\..
cd "%JBOSS_DIR%"
for /f "usebackq delims=" %%D in (`cd`) do set JBOSS_DIR=%%D
cd "%CURRENT_DIR%"
rem Make sure that we have the findstr utility installed.
set findstr_found=
for /f "usebackq" %%f in (`echo x ^| findstr x 2^>nul`) do set findstr_found=%%f
if "X%findstr_found%" == "X" (
echo The findstr utility is not found.
goto pauseforError
)
call :getJbossVersion
rem prepare the list of special JBoss environments to exclude
if /i "%JBOSS_VERSION%" lss "5" (
set env_to_exclude=all default minimal
) else if /i "%JBOSS_VERSION%" lss "6" (
set env_to_exclude=all default minimal standard web
) else (
set env_to_exclude=all default minimal jbossweb-standalone standard
)
rem find the environment directories
setlocal enabledelayedexpansion
Set Count=1
for %%f in (%jboss_dir_list%) do (
for /f "delims=" %%G in ('dir /b /ad "%%~f\jboss*"') do (
if exist "%%f\%%G\server\%ENV_NAME%" (
for /f "delims=" %%H in ('dir /b /ad "%%~f\%%~G\server\%ENV_NAME%"') do (
echo count est !count!
call :concat %%~f\%%~G\server\%%~H
Set /A Count+=1
)
)
)
)
rem echo %ENV_NAME%
rem %jboss_home_list%
:concat
echo the environment is %1
set is_env_to_exclude=no
for %%L in (%env_to_exclude%) do (
set is_env_to_exclude=no
for /f "usebackq delims=" %%U in (`echo %1 ^| findstr %%L`) do (
set is_env_to_exclude=yes
echo flag du Ellouze
)
)
echo %is_env_to_exclude%
rem echo %is_env_to_exclude%
rem set jboss_home_list=%1 %jboss_home_list%
goto :eof
:getJbossVersion
for /f "usebackq tokens=2" %%v in (`echo. ^| %JBOSS_DIR%\bin\run.bat -V ^| ^
findstr "JBoss" ^| findstr /i /v "BootStrap"`) do (
set JBOSS_VERSION=%%v
)
goto :EOF
:showUsage
echo Usage: tish [environment]
echo ^|
echo +--- installed environment
rem SET /P uname=Please enter your name:
rem IF "%uname%"=="" GOTO Error
rem ECHO Hello %uname%, Welcome to DOS inputs!
rem GOTO End
rem :Error
rem ECHO You did not enter your name! Bye bye!!
:pauseforError
if "%PAUSE_ON_ERROR%" == "yes" pause
:End
My idea is to to do the filetring through the :concat subroutine, problem is set is_env_to_exclude=yes insrtuction inside the for loop isn't working, when i execute the script the echo flag is displaying but the set is_env_to_exclude is always set to no.
I think what you need is to break the loop:
echo the environment is %1
set is_env_to_exclude=no
for %%L in (%env_to_exclude%) do (
set is_env_to_exclude=no
for /f "usebackq delims=" %%U in (`echo %1 ^| findstr %%L`) do (
set is_env_to_exclude=yes
echo flag du Ellouze
goto :break_loop
)
)
:break_loop
echo %is_env_to_exclude%
as on each iteration over %env_to_exclude% items the is_env_to_exclude is set to no.
Although the code is a little bit complicated for me :)
It really depends on the contents of env_to_exclude.
is_env_to_exclude will be set to no for each %%L, so even if it is set to yes once, if there are more elements processed after it's been set, it will be re-set to no.
The
set is_env_to_exclude=no
in the loop seems to be the culprit; removing it would seem to fix the problem.
AAMOI, set "flag=" and set flag=Y allows if [not] defined flag which has the added advantage that the CURRENT status of the flag is available within a FOR loop without needing enabledelayedexpansion.

Resources