I am creating a batch file to open remote Computer Management console by taking User ID as input and computer name from 2nd column from file data.csv. it works fine on first attempt. When it goes back to :start label. and ask for other input. it gives error. System cannot find file ./data.csv
My code is
:start
set /p Input="Enter User-ID:"
for /f "usebackq tokens=1-4 delims=," %%a in (".\data.csv") do (
if %input% ==%%a ("cmd /c Start /B /wait compmgmt.msc –a /computer=%%b")
)
cls
GOTO start
Good practice to use %~dp0 for paths in batch files (instead of relative paths like .) that way if the current working folder changes the file will always be located.
So change to %~dp0data.csv
:start
set /p Input="Enter User-ID:"
PUSHD
for /f "usebackq tokens=1-4 delims=," %%a in (".\data.csv") do (
if %input% ==%%a ("cmd /c Start /B /wait compmgmt.msc –a /computer=%%b")
)
POPD
cls
GOTO start
should restore sanity, pushing the directory then restoring it before the next cycle.
Related
I am currently trying to create a batch script so I can sort multiple tiff images in a folder by moving it to other specific folder according to user input. What I achieved so far is:
1. Can loop through all the files in the folder
2. Can open the image viewer to view the tiff file
3. Close off the image viewer program
4. Move the tiff file to specific folder
However, I do not know why my set /p is not registering user's input value, when I tried to echo the input out.
cmd gave me "ECHO is off" message.
Appreciate if anyone could give me a hand to resolve this problem.
Many thanks
G
#ECHO OFF
cd "C:\img\"
FOR /R %%f IN (*.tif) DO (
echo Current file is: %%f
start "" "C:\Program Files (x86)\Common Files\Global 360\Imaging\kodakprv.EXE" %%f
set /p name= Action:
IF "%name%" == "1" GOTO ONE
IF "%name%" == "2" GOTO TWO
IF "%name%" == "3" GOTO THREE
ECHO %name%
echo None of the above, BYE!
GOTO END
:ONE
echo "I pressed 1"
taskkill /IM kodakprv.EXE
move %%f "C:\img\1"
cls
:TWO
echo "I pressed 2"
taskkill /IM kodakprv.EXE
move %%f "C:\img\2"
cls
:THREE
echo "I pressed 3"
taskkill /IM kodakprv.EXE
move %%f "C:\img\3"
cls
)
:END
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
cd "C:\img\"
FOR /R %%f IN (*.tif) DO (
echo Current file is: %%f
start "" "C:\Program Files (x86)\Common Files\Global 360\Imaging\kodakprv.EXE" %%f
SET "name="
set /p name= Action:
for %%v in (1 2 3) do IF "!name!" == "%%v" (
set "validaction=Y"
echo "I pressed %%v"
taskkill /IM kodakprv.EXE
move %%f "C:\img\%%v"
pause
cls
)
if not defined validaction (
ECHO !name!
echo None of the above, BYE!
GOTO END
)
)
:END
A few little problems.
First, you can't use labels within a code block (parenthesised series of commands) and second the old favourite, delayedexpansion - if a variable is changed within a code block then unless delayed expansion is in effect, the original value will be used. If delayed expansion is in effect, then %var% refers to the original value and !var! to the current (run-time) value.
Note also that set /p does not change the value of the variable if user response is simply Enter - -hence the set "name=" above to clear its value. Of course, you can omit that line and the last-entered value of name will be used again if you just press Enter.
There are many articles on SO about delayed expansion - just use the search feature.
I want to write a script to prompt user for file path and list all files found. The file path can contain wildcards. Something similar to this. But the batch script version of it. For example:
C:\Somewhere\user*\app\version-*.*\start.exe
The files might be located like this:
C:\Somewhere\user345\app\version-1.0\start.exe
C:\Somewhere\user898\app\version-1.2\start.exe
C:\Somewhere\user898\app\version-1.3\start.exe
I tried to use FOR and it turns out to be so much harder than expected because FOR does not support wildcards in the middle of a path.
Is there a way to list these files? (Maybe without using for?)
I think this recursive solution works pretty well; you may name it WCDIR.bat:
#echo off
setlocal
if "%~1" neq "" set "next=%~1" & goto next
echo Show files selected by several wild-cards
echo/
echo WCDIR wildcardPath
echo/
echo Each folder in the path may contain wild-cards
echo the last part must be a file wild-card
goto :EOF
:next
for /F "tokens=1* delims=\" %%a in ("%next%") do set "this=%%a" & set "next=%%b"
if defined next (
for /D %%a in ("%this::=:\%") do (
setlocal
cd /D "%%~a" 2>NUL
if not errorlevel 1 call :next
endlocal
)
) else (
for /F "delims=" %%a in ('dir /B /A:-D "%this%" 2^>NUL') do echo %%~Fa
)
exit /B
EDIT: I fixed a small bug in the last for /F command.
For example, the output of WCDIR.bat C:\Windows\Sys*\find*.exe command in my Windows 8.1 64-bits computer is:
C:\Windows\System32\find.exe
C:\Windows\System32\findstr.exe
C:\Windows\SysWOW64\find.exe
C:\Windows\SysWOW64\findstr.exe
You can try with the command Where /?
The WHERE command is roughly equivalent to the UNIX 'which' command. By default, the search is done in the current directory and in the PATH.
#echo off
Where /R "%programfiles%" *winrar.exe
pause
#echo off
:: Example d'input
set UserInput=*drive*
:: building the Pattern
set cmd=%Userinput%.exe
:: storage Where.exe command in a macro, the execution will be faster
set whereCmd=where.exe /r c:\windows\ %cmd%
:: execution of macro and output formatting
for /f %%a in ('%whereCmd%') do echo %%~nxa --^> %%a
pause
I've got a batch script to utilize a command for an application to create some backups. I've got a loop setup to run through and fetch folder names and then to run the backup operation utilizing those folder names as file names. My loop runs great but my batch script just closes when it is finished. I'd like to escape the loop so I can go back to a choices location I have specified. I've seemingly been unable to escape this loop properly. My code is below:
set /p work=Folder Location:
set /p staging=Location of staging-backup file:
set /p backup=Location to save backup:
#Echo off
md %backup%
setlocal enabledelayedexpansion
set /a $count=1
cd /d %staging%
for /f "delims=" %%a in ('dir "%work%" /b/o') do (
staging-backup "%%a" "%backup%\%%a"
set /a $Count+=1
)
Again, this all runs great (though I can't get it to log properly but thats another battle for later) except I'd love to GOTO CHOICE at the end. When I add it after the closing ) part of the loop, it still closes. When I bring it inside the loop, it closes. Do I need to wrap this loop in an if else to escape it properly?
I tried pulling the code out and pushing it to it's own bat then calling that bat with my original but no change.
:THREE
echo.
echo.
.\Loops.bat
echo.
echo.
GOTO CHOICE
This portion calls it, runs the new bat but still closes the cmd window when it is finished. Any ideas?
#Echo off
setlocal enabledelayedexpansion
:AGAIN
for %%a in (work staging backup) do set "%%a="
set /p "work=Folder Location: "
if not defined work goto :eof
set /p "staging=Location of staging-backup file: "
set /p "backup=Location to save backup: "
md %backup%
set /a $count=1
PUSHD %staging%
for /f "delims=" %%a in ('dir "%work%" /b/A-D') do (
staging-backup "%%a" "%backup%\%%a"
set /a $Count+=1
)
POPD
GOTO AGAIN
Here's a revision.
The first two lines are moved to the top to turn off command-echoing prevent the variables remaining set for each run.
Then insert a label, and clear the variables.
If you reply just Enter to the work prompt, the batch terminates as work will be undefined (set /p leaves the variable unchanged under these circumstances - it does not clear the variable)
PUSHD a directory to switch temporarily to a different directory.
execute staging-backup in that directory. Note that if staging-backup is a batch, then you should use CALL staging-backup... (actually, you could do that with any executable - if it's a batch, you must do it so that cmd knows where to come back to at the end of the destination batch (in this case, staging-backup.bat)
When the for loop is finished, POPD to return to the original directory and loop back to :AGAIN to well - do it all again.
I have a batch script which accepts >=1 files via drag & drop. The full paths are kept in an array and later fed to another program as input. The file name+extension is kept in another array which is then shown to the user.
I am trying to check the file extension and if it is not .bin, automatically rename the file I dragged & dropped to .bin and reload it to be added to the two arrays. How can I do that? I have tried some if commands or %%~xi but usually it doesn't properly detect if it's .bin or not and of course the path is not updated at the array.
#echo off
pushd %~dp0
setlocal enabledelayedexpansion
set /a Count = 0
:START
set file="%~1"
if %file%=="" goto RUN
for %%i in (%file%) do set name=%%~nxi
set /a Count += 1
set [FilePath.!Count!]=%file%
set [FileName.!Count!]=%name%
shift
goto START
:RUN
for /l %%i in (1, 1, %Count%) do (
program.exe -command "![FilePath.%%i]!"
echo.
echo File Name: ![FileName.%%i]!
echo.
pause
cls
if exist file.log del file.log
)
You could just rename it during your array population. There are a few other potential problems with your script (such as pushd to an unquoted directory, delayedexpansion where you don't need it where it will potentially clobber filenames containing exclamation marks, and if %file%=="" should have "%file%" quoted). And there's really no reason to maintain an array of filenames or loop twice. Your script is much more complicated than it needs to be.
#echo off
setlocal
pushd "%~dp0"
for %%I in (%*) do (
if /I not "%%~xI"==".bin" move "%%~fI" "%%~dpnI.bin" >NUL
program.exe -command "%%~dpnI.bin"
echo;
echo File Name: "%%~nxI"
echo;
rem If you want to rename the file back the way it was after running
rem program.exe on it, uncomment the following line:
rem if /I not "%%~xI"==".bin" move "%%~dpnI.bin" "%%~fI" >NUL
pause
cls
if exist file.log del file.log
)
Ok, I am trying to make a batch file to generate a series of files and folders, but can't find on how to do it.
My Idea:
FOR /f "Tokens=* delims=" %%I IN (export2.csv) DO call:create %%I GOTO:EOF
:create ECHO 1 >>%~pd0%1
But it didn't work at all.
Since I have no idea how your data file looks like it's hard to give good advice here, but your code could be cleaned up a bit:
set "filepath=%~dp0"
for /f "tokens=* delims=" %%I in (export2.csv) do call :create "%%I"
rem This is needed to avoid stepping into the subroutine again
goto :eof
:create
rem This will create an empty file instead of one that contains a single line with 1
copy nul "%filepath%%~1"
goto :eof
This won't create any directories, though. You can create those with md.
Figured it out a little bit ago and here is what I ended up with. It will generate both the path and create an empty file with the name of the file listed in the masterlist.csv.
Source Code
#ECHO OFF
CHDIR "%~dp0"
SET Count=0
ECHO/ Generating Necessary File, please Wait...
FOR /F %%A IN (Masterlist.csv) DO CALL:MKDIR %%A
EXIT /B
:MKDIR
SET /A Count+=1
SET "Path=%~dp1"
SET "File=%~nx1"
IF NOT EXIST "%Path%" MKDIR "%Path%
IF NOT EXIST "%Path%" CALL:ERROR "Path"
IF NOT EXIST "%Path%\%File%" ECHO/ >>"%Path%\%File%"
IF NOT EXIST "%Path%\%File%" CALL:ERROR
EXIT /B
:ERROR
IF NOT EXIST "Errorlog.csv" ECHO Error, Line Count>>Errorlog.csv
ECHO %~1, Line %Count%>>Errorlog.csv
A few example lines from Masterlist.csv
2006\MS06-003\Office2000\office2000-kb892842-fullfile-enu.exe
2006\MS06-003\Office2003\office2003-kb892843-fullfile-enu.exe
2006\MS06-003\Office2003\WinSec-MS06-003-009-P44333-outlook2003-kb892843-fullfile-enu.exe
2006\MS06-003\OfficeXP\officexp-kb892841-fullfile-enu.exe
2006\MS06-006\WindowsMedia-KB911564-x86-ENU.exe
2006\MS06-007\2003\WindowsServer2003-KB913446-x86-ENU.exe
2006\MS06-007\XP\WindowsXP-KB913446-x86-ENU.exe
2006\MS06-012\2003\office2003-KB905756-FullFile-ENU.exe
2006\MS06-015\2000\Windows2000-KB908531-x86-ENU.EXE
2006\MS06-015\2003\WindowsServer2003-KB908531-x86-ENU.exe