My question, is extremely similar to the following SO question: How to get Java Version from batch script?
In fact, it did almost solve my problem. The only difference is that I've to check the Java version based on %JAVA_HOME%, which the user is free to modify. The issue that I'm facing is with this code:
#ECHO OFF
SETLOCAL enableextensions enabledelayedexpansion
IF "%JAVA_HOME%"=="" (
#ECHO Please set JAVA_HOME environment variable
EXIT /B
)
#echo "%JAVA_HOME%"
REM Checking JAVA_VERSION
SET JAVA_VERSION=
FOR /f "tokens=3" %%g in ('"%JAVA_HOME%"\bin\java -version 2^>^&1 ^| findstr /i "version"') do (
SET "JAVA_VERSION=%%g"
)
%JAVA_HOME%% in my system points to "C:\Program Files\jdk1.7.0_25" (notice the space in the path)
Even with the quotes, I get the following error in command line:
'C:\Program' is not recognized as an internal or external command,
operable program or batch file.
Any idea as to how to solve this problem? (The comments to the aforementioned article also mentions this issue). I'm working on a Windows 7 machine
FOR /f "tokens=3" %%g in ('"%JAVA_HOME%\bin\java" -version 2^>^&1 ^| findstr /i "version"') do (
SET "JAVA_VERSION=%%g"
)
Edit the %JAVA_HOME% Variable into:
C:\"Program Files"\jdk1.7.0_25
if you want it automated, type
set %JAVA_HOME%=C:\"Program Files"\jdk1.7.0_25
REASON WHY:
The batch file does not accept the quotes; It is identifying them as a single file. So it attempts to find "C:\Program Files\jdk1.7.0_25" NOT as a folder path, but as a folder NAME in your root folder. If you type in
C:\"Program Files"\jdk1.7.0.25 it identifies that "Program Files" is a single file. If there are no redirection operators, It would think that the path would be like this;
C:\Program\Files\jdk1.7.0_25. It worked for me; It should probably work for you.
Hope that helped
-SonorousTwo
I had a similar problem, take a look at my QA: How to get Java version in a batch script subroutine?
From my answer:
It seems that piping the output to findstr was stripping the quotes for some reason.
I managed to fix the problem without Epic_Tonic's workaround (which would be very difficult to do with a path as a parameter).
This should work in your case:
set first=1
for /f "tokens=3" %%g in ('"%JAVA_HOME%\bin\java" -version 2^>^&1') do (
if !first!==1 echo %%~g
set first=0
)
Note: first is for only searching the first line of java -version's output (reference).
Related
Normally I can specify a folder for a batch file to work in.
Not so with the FOR command:
for %%a in (G_*.txt) do ren "%%a" "test-%%a"
This finds G_*.txt in all files and renames those by putting test- in front of the filename.
I tried specifying G_*.txt further with C:\test\G_*.txt but that is not accepted.
I also tried pouring this into a variable but that also failed.
Who knows what to do?
Again, I had to change the approach: using SET /R will put a long path into the %%a variable which makes the idea unsuited to put a bit of text in front of a filename.
I found the solution by selecting the work directory first and let the FOR construction do its work. Since it must be network proof, I had to use the PUSHD command.
This is what the final result looks like:
set source=\\nassie\home\test\source with nasty space
set target=D:\target
PUSHD %source%
:: If this fails then exit
If %errorlevel% NEQ 0 goto:eof
for %%a in (G_*.txt) do xcopy "%source%\%%a" "%target%\textblabla_%%a*" /D /Y
POPD
I am attempting to hash all or most of the files off of a machine using a batch script. What I thought would be straight forward was of course not as FCIV will not scan hidden files. I attempted to make a for loop that would scan the individual files themselves but what works in the command line does not work in the batch file.
I would go to the root of my drive and attempt this:
FCIV -r -both c:\
However I noticed that quite a few files were missing (even as admin) with most of them being hidden files.
Thanks,
Any help would be appreciated.
I use this snippet of the code for CertUtil, it might also work for FCIV
cd /d %targetDir%
for /r %%e in (*) do (
if exist "\\?\%%e" (
FOR /F "tokens=* USEBACKQ" %%F IN (`certutil -hashfile "\\?\%%e" %hashType% ^| findstr /v "certutil hash"`) DO (SET var=%%F)
echo !var! "%%e" >> %hashDatabaseOutput%
SET /A fileCount += 1
) else (
echo ERROR 1 - Failed to Hash file, File or Directory contains special characters >> %errorlog%
echo %%e >> %errorlog%
echo.>> %errorlog%
)
)
cd /d "%workingDir%"
I have a similar issue as you, I'm scanning some files in C:\ but those aren't hidden files.
EDIT: Seems that using this method makes no difference because even when the file path that is feed to FCIV, the hashing will fail because it cannot find the file. you can look at my question here https://stackoverflow.com/questions/62111957/fciv-fails-to-find-some-files-when-hashing-c-drive
EDIT2: Found the root cause, it's caused by redirection when you attempting to scan files in C:\Windows\System32. One guy explained it clearly here
The system cannot find the path specified
Since FCIV only have 32bit mode, the only solution is to use other hashing program like rHash with 64bit.
I have an exe file, say, C:\Programs\tools\4.0.97869\program.exe
This, obviously, version number may vary, but I'm totally sure that it will always be 4.0.something
I can execute some command from batch file, specifying path to that exe like this:
"C:\Programs\tools\4.0.97869\program.exe" /option:Key somevalue
Which works perfectly fine. However, I would like to place a wildcard here, for example like this:
C:\Programs\tools\4.0.*\program.exe
Since I can perfectly navigate like this using cd
I do not want to specify that exe in Path
I do not want to cd to that directory and call program.exe from there
It there a way to specify first matching directory which has a
necessary file to execute in one line?
Thanks.
Here is a solution that uses a PowerShell script:
$pathPattern = 'C:\Programs\tools\4.0.*\program.exe'
if(!(Test-Path $pathPattern)){
throw "Could not find a single executable"
}
$paths = Get-Item -Path $pathPattern
Invoke-Expression $paths[0]
A PowerShell solution would be a better idea. If only cmd.exe can be used, the following might work. It is not a one-liner. Store this in a .bat file and CALL it. It works by running the first "program.exe" it can find. It tries to get the most recent one by ordering the directory search as most recent first.
SETLOCAL ENABLEDELAYEDEXPANSION
SET EXITCODE=0
SET "EXEWILD=C:\Programs\tools\4.0.*"
FOR /F %%d IN ("%EXEWILD%") DO (SET "EXEBASE=%%~dpd")
IF NOT EXIST "%EXEWILD%" (
ECHO ERROR: Tool directory "%EXEWILD%" does not exist.
SET EXITCODE=4
GOTO TheEnd
)
FOR /F "usebackq tokens=*" %%d IN (`DIR /B /O-D "%EXEWILD%"`) DO (
IF EXIST "%EXEBASE%\%%~d\program.exe" (
"%EXEBASE%%%~d\program.exe" %*
SET EXITCODE=!ERRORLEVEL!
GOTO TheEnd
) ELSE (
ECHO WARNING: program.exe not found in "%EXEBASE%\%%~d"
)
)
:TheEnd
EXIT /B %EXITCODE%
My conundrum is related to the q/a thread at the following link: How to append date to directory path in xcopy
I'm new to this forum, and I had the same kind of question, and I'm using Windows 10, so I used the answer given in that thread by foxidrive about how to use WMIC for this, and it works fabulously, except for one issue that I've not yet figured out...
I modified the script that foxidrive provided, as follows:
#echo off
for /f "delims=" %%a in ('wmic OS Get localdatetime ^| find "."') do set dt=%%a
set datestamp=%dt:~0,8%
set timestamp=%dt:~8,6%
set YYYY=%dt:~0,2%
set YY=%dt:~2,2%
set MM=%dt:~4,2%
set DD=%dt:~6,2%
set HH=%dt:~8,2%
set Min=%dt:~10,2%
set Sec=%dt:~12,2%
for /f "tokens=%dow%" %%a in ("Su Mo Tu We Th Fr Sa") do set day=%%a
set stamp=%YY%%MM%%DD%%HH%%Min%%day%
REM echo Today is %day%.
md "%stamp%MoreDirName"
xcopy %source% /E /y .\"%stamp%MoreDirName"
When I run the batch file from cmd.exe, I get the desired result, namely, a directory is created with the date format the way I want it, and the date and time stamp that I want includes the name of the day of the week. However, when I double-click on the batch file in windows explorer, the folder is created and folders/files are copied, but the name of the day of the week does not appear in the new folder name. I am confused by this behavior and I would like to know how to override it, please.
I would have researched the issue more, but I am not sure what to search for other than ``different behaviors of WMIC in command line and windows'', and such a search yielded no helpful results. But since my efforts were based specifically upon the referenced stack exchange q/a thread, it seems to me that this is an appropriate place to document this strange behavior and get explanations if possible, which might help me, and others later, to compose better script.
I am confused by this behavior and I would like to know how to override it
There is no problem with wmic. The Issue is with your batch file, which contains two undefined variables).
for /f "tokens=%dow%" %%a in ("Su Mo Tu We Th Fr Sa") do set day=%%a
You don't set dow anywhere in your batch file.
xcopy %source% /E /y .\"%stamp%MoreDirName"
You also don't set source anywhere in your batch file.
What probably happened:
You have dow and source hanging about in your cmd environment from another batch file you have run that does not include the setlocal command (which prevents variables leaking into the parent cmd shell).
That means:
The batch file run from a cmd shell will work if dow and source are set in that instance of cmd.
The batch run from explorer won't work because it start a new instance of the cmd shell and dow and source are undefined.
Corrected batch file:
Here is a modified version of your batch file that will work when run from a cmd shell or from explorer, and correctly sets up Day of the Week.
rem #echo off
setlocal
set source=SomeSourceValue
rem use findstr to strip blank lines from wmic output
for /f "usebackq skip=1 tokens=1-6" %%g in (`wmic Path Win32_LocalTime Get Day^,Hour^,Minute^,Month^,Second^,Year ^| findstr /r /v "^$"`) do (
set _day=00%%g
set _hours=00%%h
set _minutes=00%%i
set _month=00%%j
set _seconds=00%%k
set _year=%%l
)
rem pad with leading zeros
set _month=%_month:~-2%
set _day=%_day:~-2%
set _hh=%_hours:~-2%
set _mm=%_minutes:~-2%
set _ss=%_seconds:~-2%
rem get day of the week
for /f %%k in ('powershell ^(get-date^).DayOfWeek') do (
set _dow=%%k
)
set _stamp=%_year%%_month%%_day%%_hh%%_mm%%_dow:~0,2%
md "%_stamp%MoreDirName"
xcopy %source% /E /y .\"%_stamp%MoreDirName"
endlocal
Notes:
The batch file uses a more elegant way to retrieve the timestamp components from wmic.
Modify the above as appropriate to set source correctly.
Credits:
Thanks to Danny Beckett for this answer which provided the PowerShell weekday trick.
Further Reading
An A-Z Index of the Windows CMD command line - An excellent reference for all things Windows cmd line related.
for /f - Loop command against the results of another command.
getdate - Display the date and time independent of OS Locale, Language or the users chosen date format (Control Panel/Regional).
setlocal - Set options to control the visibility of environment variables in a batch file.
variables - Extract part of a variable (substring).
wmic - Windows Management Instrumentation Command.
In my BAT file, i want to read these data from .txt file and need to set each data into one variable
SQLUserName=MFiles
WrapperSQLServerName=usa.com
WrapperDatabase=Wrapper
WrapperAssemblyLocation=D:\Assembly
MFilesNetworkAddress=USA-S1
MFilesVaultName=MF2
MFilesUsername=User
MFilesPassword=
MFilesVaultGUID={26F30-E120-408C-8035-04D85D6}
MFilesWebServerURL=www.WebServer.com
SQLMailProfileName=NoReply
WrapperSupportEmail=thejus#WebServer.com
I tried with this code
FOR /F "tokens=2 delims==" %%a IN ('find "WrapperSupportEmail" ^<config.txt') DO SET SupportEmail=%%a
But it throws error
find is not recognized as an internal or external command operable program or batch file
Please help me
Thejus T V
If the schema of your input file is fixed (keyword=value) and you want to assign all values to an environment variabel named keyword it is very, very easy. try this:
for /f "tokens=1,2 delims==" %i in (config.txt) do set %i=%j
remember to change %i and %j to %%i and %%j if you want to put this call into a cmd-file.
when two members with high reputation tell you it works, then it shouldn't be the worst of all ideas to at least try it.
rem #echo off
for /f "delims=" %%i in (config.txt) do set _%%i
pause
set _
I REMd the #echo off, so you can watch, how every single line get's processed.
(Your original error find is not recognized ... is probably because you messed up your %path%-variable, but you don't need find for this task.)
My code is correct one only. Only issue is windows cant locate find.exe. I included the .exe on same location and after that everything works fine.
Its working fine in Win 7 and Win 10 without adding Find.exe