Store randomized folder in a batch script? - windows

I have a script that automatically backup NAPS2 (Scanner program) newest scan result to another drive, and also rename it according its timestamp...
Problem is, NAPS2 uses randomized folder name as the parentfolder of its scan result... e.g
"C:\Users\username\AppData\Roaming\NAPS2\recovery\4j4v.fbmv\scanresult001.jpg"
Here's the code, how do i point to that randomized folder?
SET ROOTDIR=C:\Users\Operator\AppData\Roaming\NAPS2\recovery\
for /f %%i in ('dir %ROOTDIR% /b /AD /od /t:w') do set LATEST_DIR=%%i >NUL
SET RANDOMDIR=%ROOTDIR%%LATEST_DIR%
for /F "delims=" %%a in ('dir /b /od "%RANDOMDIR%\*.jpg"') do set Youngest=%%a
echo Backing up %Youngest%
for /f "delims=" %%a in ('wmic OS Get localdatetime ^| find "."') do set dt=%%a
set YYYY=%dt:~0,4%
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%
set mydate=%YYYY%%MM%%DD%#%HH%%Min%%Sec%
copy "%Youngest%" "D:\Backup\%mydate%.jpg"
Output
C:\>for /F "delims=" %a in ('dir /b /od "C:\Users\Operator\AppData\Roaming\NAPS2
\recovery\jfwkui0s.pmd \*.jpg"') do set Youngest=%a
File Not Found
C:\>echo Backing up
Backing up
C:\>for /F "delims=" %a in ('wmic OS Get localdatetime | find "."') do set dt=%a
:\>set dt=20160818125756.950000+420
C:\>set YYYY=2016
C:\>set MM=08
C:\>set DD=18
C:\>set HH=12
C:\>set Min=57
C:\>set Sec=56
C:\>set mydate=20160818#125756
C:\>copy "" "D:\Backup\20160818#125756.jpg"
The system cannot find the path specified.
I think it's probably because the randomized folder has "." in it.. I tried "New Folder" which has space in it and it doesnt work as well

To do this use the approach shown in https://stackoverflow.com/a/30311479/6550457
You'll want to do it only for directories though so instead of a-d use ad
SET ROOTDIR=C:\Users\username\AppData\Roaming\NAPS2\recovery\
for /f %%i in ('dir %ROOTDIR% /b /AD /od /t:w') do set LATEST_DIR=%%i>NUL
echo Latest Dir = %LATEST_DIR%
so in your script you'd use it as:
SET ROOTDIR=C:\Users\username\AppData\Roaming\NAPS2\recovery\
for /f %%i in ('dir %ROOTDIR% /b /AD /od /t:w') do set LATEST_DIR=%%i>NUL
SET RANDOMDIR=%ROOTDIR%%LATEST_DIR%
echo Backing up %RANDOMDIR%
for /f "delims=" %%a in ('wmic OS Get localdatetime ^| find "."') do set dt=%%a
set YYYY=%dt:~0,4%
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%
set mydate=%YYYY%%MM%%DD%#%HH%%Min%%Sec%
copy "%RANDOMDIR%" "E:\Backup\%mydate%.png"

Related

windows batch file checking power plug with Battery.PowerOnline returns always FALSE

I did on a lot of windows 10 tablets a shutdown check when the power in the room switched off. Now I tried to update a view dell 8.1 tablets, but the Battery.PowerOnline returns always false. Any ideas?
FOR /F "tokens=* delims=" %%A IN ('WMIC /NameSpace:"\\root\WMI" Path BatteryStatus Get PowerOnline^,RemainingCapacity /Format:list ^| FIND "="') DO SET Battery.%%A
FOR /F "tokens=* delims=" %%A IN ('WMIC /NameSpace:"\\root\WMI" Path BatteryRuntime Get EstimatedRuntime /Format:list ^| FIND "="') DO SET Battery.%%A
FOR /F "tokens=* delims=" %%A IN ('WMIC /NameSpace:"\\root\WMI" Path BatteryFullChargedCapacity Get FullChargedCapacity /Format:list ^| FIND "="') DO SET Battery.%%A
IF /I "%Battery.PowerOnline%"=="TRUE" (
SET doShutDown=0
) ELSE (
SET doShutDown=1
)
You set Battery.%%A which will not set anything to be honest, also, you never defined %Battery.PowerOnline% variable, so it will never return true. Do we really need to check each status? Only the last set from your three commands will keep the variable value, so rather check the main poweronline value and do something from there. Notice how I set the variables:
#echo off
for /F "tokens=* delims=" %%A IN ('WMIC /NameSpace:"\\root\WMI" Path BatteryStatus Get PowerOnline /Format:list ^| FIND "PowerOnline"') DO SET "Battery=%%A" & goto :verify
:verify
if /I "%Battery%"=="PowerOnline=TRUE" (
set doShutDown=0
) else (
set doShutDown=1
)

Copy a txt file with today date as file name (YYMMDD)

Everyday I create a data log with today's date (eg. ERR150921.txt). I need to copy this file to the server like a backup.
This is my current code:
SET ServerPath=\\IYA-PC\Shared
SET ClientPath=%USERPROFILE%\Documents\Data Log
echo.
echo Copying Files to Server...
FOR /F "delims=|" %%I IN ('DIR "%ClientPath%\*.txt" /B /O:F') DO SET NewestFile=%%I
xcopy "%ClientPath%" "%ServerPath%\%NewestFile%" /s /c /d /e /h /i /r /y
I got it from a post here. It copies the recently updated files.
The problem is that I do not need all the updated files. I just need to copy the file created today.
This sample will copy every files that have today date as name before extension. ie it will copy any of this;
"ERR150921.txt"
"21184150921.txt"
"2526150921.txt"
"29056-150921.txt
"150921.txt"
"ABCDEF-150921.txt"
.
#echo off
for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"
set "YY=%dt:~2,2%" & set "YYYY=%dt:~0,4%" & 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%"
set "_timestamp=%YY%%MM%%DD%"
SET "ServerPath=\\IYA-PC\Shared"
SET "ClientPath=%USERPROFILE%\Documents\Data Log"
echo.
echo Copying Files to Server...
setlocal enabledelayedexpansion
FOR /F "delims=|" %%I IN ('DIR "%ClientPath%\*.txt" /B') DO (
set "filename=%%~nI"
if "!filename:~-6!"=="%_timestamp%" (
echo xcopy "%%~I" "%ServerPath%\%%~nxI" /s /c /d /e /h /i /r /y
)
)
Get today's date, and transform it to your file name
SET ServerPath=\\IYA-PC\Shared
SET ClientPath=%USERPROFILE%\Documents\Data Log
echo.
echo Copying Files to Server...
SET FILE_NAME=ERR%date:~2,2%%date:~5,2%%date:~8,2%.txt
FOR /F "delims=|" %%I IN ('DIR "%ClientPath%\%FILE_NAME%" /B /O:F') DO SET NewestFile=%%I
xcopy "%ClientPath%" "%ServerPath%\%NewestFile%" /s /c /d /e /h /i /r /y

Path over registry (windows)

I try to get a path over the regestry of windows. My Problem now is how do I get the Path out of MATLAB_ROOT_32?
for /F "tokens=* delims='C'" %%i IN ('reg query HKLM\SOFTWARE\WOW6432NODE\Mathworks\Matlab\7.9.1 /v MATLABROOT') do (set MATLAB_ROOT_32=%%i)
echo %MATLAB_ROOT_32%
set i=
rem GOTO Split1
rem :Split1
REM -- Split the result into MATLABROOT, REG_SZ and Folder using space as delimiter
for /f "tokens=1,2,3 delims='C'" %%a in ("%MATLAB_ROOT_32%") do set useless1=%%a&set useless2=%%b&set MATLAB_x32=%%c
echo %Matlab_x32%
The plan is to get the MATLAB Path in the Matlab_x32 variable.
This works for me:
#echo off
setlocal ENABLEEXTENSIONS
set MATLAB_VERSION=8.3
set KEY_NAME=HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432NODE\MathWorks\MATLAB\%MATLAB_VERSION%
set VALUE_NAME=MATLABROOT
for /F "usebackq tokens=2*" %%A IN (`reg query "%KEY_NAME%" /v "%VALUE_NAME%" 2^>nul ^| find "%VALUE_NAME%"`) do (
set MATLABROOT=%%B
)
echo %MATLABROOT%
Just change the Matlab version to whatever you're using and it should be fine. There are variations in the output from reg depending on the OS version, but this should cope (I think!)

look for file of a certain type one subfolder down, sort by date modified (newest first), and display subfolder name (NOT filename) in sorted order

This is a very specific question, so I've separated it into 3 parts.
Look in all subfolders for a certain file: world.sav, but only 1 level down, i.e.
C:\workingdir\foo\world.sav
C:\workingdir\bar\world.sav
C:\workingdir\baz\world.sav
C:\workingdir\qux\world.sav
is fine, but
C:\workingdir\foo\bar\world.sav
C:\workingdir\world.sav
isn't, etc.
Sort these world.sav files by date modified (newest first).
Display the name of the subfolder each world.sav file is in, in the previously sorted order. i.e. if the above list was date-sorted into
C:\workingdir\qux\world.sav (newest)
C:\workingdir\bar\world.sav
C:\workingdir\foo\world.sav
C:\workingdir\baz\world.sav (oldest)
then the output would be
qux
bar
foo
baz
I've tried numerous methods involving DIR, FORFILES and manipulation of variables, but the 2 main problems I've come across so far are
Both commands mentioned above will arrange by subfolder, then by date, and I can't find a way to avoid it.
Date formatting. It appears to be different for every localization of Windows, and I really want this to be locale-independent.
Also, it must support spaces in folder names.
EDITED version with a wait message:
#echo off
echo Please wait...
cd /d "c:\workingdir"
(for /d %%a in (*) do #robocopy "%%a" "%%a" world.sav /L /nocopy /is /njh /njs /ndl /nc /ns /ts)|(
#cls
for /f "tokens=2*" %%b in ('sort /r') do #for %%z in ("%%~dpc\.") do #echo %%~nz
)
cd /d "%~dp0"
echo.
pause
original version below
This works here:
robocopy is used on each folder in the directory to generate a list (UTCdate time drv:\path\world.sav format) and that is sorted to get most recent at the top of the list, which the second for parses to extract the drv:\path\folder\world.sav and the last for loop prints out just the folder name.
#echo off
cd /d "c:\workingdir"
(for /d %%a in (*) do #robocopy "%%a" "%%a" world.sav /L /nocopy /is /njh /njs /ndl /nc /ns /ts)|for /f "tokens=2*" %%b in ('sort /r') do #for %%z in ("%%~dpc\.") do #echo %%~nz
pause
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET /a count=0
:: remove variables starting $
FOR /F "delims==" %%a In ('set $ 2^>Nul') DO SET "%%a="
FOR /f "delims=" %%a IN (
'dir /b /ad "%sourcedir%\*" '
) DO IF exist "%sourcedir%\%%a\world.sav" CALL :set$ "%%a"
IF %count%==0 ECHO No files found&GOTO :EOF
IF %count%==1 ECHO %$1%&GOTO :EOF
:sortol
SET /a start=1
SET /a swap=0
:sortil
CALL :compdt
IF %start% neq %count% GOTO sortil
IF %swap% neq 0 GOTO sortol
FOR /l %%a IN (1,1,%count%) DO CALL ECHO %%$%%a%%
GOTO :EOF
:set$
SET /a count+=1
SET "$%count%=%~1"
GOTO :eof
:compdt
CALL SET f1=%%$%start%%%
SET /a START +=1
CALL SET f2=%%$%start%%%
FOR /f %%a IN (
'echo f^|xcopy /L /y /d "%sourcedir%\%f1%\world.sav" "%sourcedir%\%f2%\world.sav"'
) DO SET copies=%%a
IF %copies%==0 GOTO :EOF
SET /a swap +=1
SET /a START -=1
SET "$%start%=%f2%"
SET /a START +=1
SET "$%start%=%f1%"
GOTO :eof
This worked for me. You'd need to set sourcedir to suit your purpose.
Essentially, it builds a list of the next-level-down directory names which contain the target filename in variables $1...$whatever, then sorts the names using a simple bubble-sort which relies on the characteristics of xcopy. XCOPY's /L switch simply lists the files that would be copied; /y tells it to 'go ahead (and not copy)' and /d says 'only later files.ECHOingftellsxcopythat the desired "copy" is a file-copy, so it responds1 file(s) copiedor0...` as its last line, depending on whether the source file was later than the destination.
To reverse the order, simply change the if %copies%==0 to if %copies%==1
An idea :
#echo off
Setlocal EnableDelayedExpansion
set $WorkDir="C:\eh\guh\blugh\fneh\mork\workingdir"
for /f "tokens=*" %%a in ('dir /s/b/a-d %$WorkDir%') do (
for /f "tokens=9 delims=\" %%b in ('echo %%a') do (
if /i "%%b"=="world.sav" call:next "%%~pa" %%~ta
)
)
::Resultat
for /f "tokens=2 delims==" %%r in ('set #') do echo %%r
exit/b
:next
for /f "tokens=7 delims=\" %%c in ('echo %~1') do set $Path=%%c
for /f "tokens=1-3 delims=/" %%c in ('echo %~2') do set #%%e%%d%%c=!$path!

How to get the number of files in directory in variable in windows batch file

I have tried following command to do this but it's not working :
for /f "delims=" %%i in ('dir "d:/Database/BARC/" /b/a-d | find /v /c "::") do set count=%%i
It is showing some error like unexpected error. How to round this error?
#echo off
for /f "delims=" %%i in ('dir "d:/Database/BARC/" /b/a-d ^| find /v /c "::"') do set count=%%i
echo %count%

Resources