How to if "%var%" equ "/?" in cmd script - windows

I'm writing a script where I want to give some help (calling with /?)
Now I tried with
REM This is myscript.bat
FOR %%A IN (%*) DO (
rem controllo i parametri
rem ...
if /I "%%A" equ "/?" goto :help
if /I "%%A" equ "--help" goto :help
if /I "%%A" equ "-h" goto :help
)
echo stuff
goto :out
:help
echo this is your lifesaver
:out
it works fine with myscript.bat --help' and myscript.bat -h (it prints this is your lifesaver).
If I call it like myscript.bat /? it prints stuff then exits instead of printing this is your lifesaver

Related

Batch: How to scroll through files to read to a variable?

I'm trying to have it scroll through a directory and present a new variable when the user replies "N". I have it all figured out except how to go to the next variable.
cd "C:\Test"
for /r %%F in (*) do SET Show=%%~NF
echo %Show%
echo.
SET /P Continue=Continue?(Y/N)
if /I "%Continue%" EQU "y" goto :Run
if /I "%Continue%" EQU "n" goto :Start
If you're looking to scroll the directory and prompt the user the file name and have them choose to choose it or continue, then bellow should help you.
Firstly, we can use dir /b /a:d to display only directories (folders) in the the current directory. By using a code block ( & ) we can put batch script inside the for loop. For your sake, we can use the CHOICE command to prompt to continue the loop or to save current folder to string and do something with it.
ScrollTreeWithPrompt.bat:
#echo off
setlocal EnableDelayedExpansion
Rem | Configuration
Set "MainDir=C:\Test"
Rem | Get Each Project Folder
for /f "tokens=*" %%A in ('dir "!MainDir!\" /b /a:d') do (
Cls
Echo Current Folder: %%A
echo(
CHOICE /M "Continue?"
Rem | Check for "N" - If so Set String & goto
IF "!ERRORLEVEL!"=="2" (
Set "Choice=%%A"
GOTO Run
)
)
Rem | No Further Results
Cls
Echo Warning: No further folders found.
pause>NUL
goto :EOF
:Run
Cls
echo Currently selected: !MainDir!\!Choice!
pause>NUL
goto :EOF
I have left a few Rem comments in the script to help you along. For any more help on the commands, type the following into a command prompt:
choice /?
set /?
for /?
goto /?
Is this what you need:
For /R "C:\Test" %%A In (*) Do (Choice /M "%%~nA"
If Not ErrorLevel 2 (Set "Show=%%~nA" & GoTo Run))
Exit /B
:Run
Echo Running against %Show%
Pause
Alternatively, should you wish to return to the loop after running against the file name, then use Call instead of GoTo:
For /R "C:\Test" %%A In (*) Do (Choice /M "%%~nA"
If Not ErrorLevel 2 Call :Run "%%~nA")
Exit /B
:Run
Set "Show=%~1"
Echo Running against %Show%
Pause

using for loop and windows tasklist cmd i am trying to open several programs from a batch file which are not already running

My code below doesn't work
echo will now go ahead and load the essential programs needed for
project: %project%
set "programlistopen=sublime_text.exe xampp-control.exe"
for /f "delims=" %%j in (%programlistopen%) do (
if %%j=="sublime_text"(set pathtopen=%defaultpath%\Sublime_Text&&set
dirpath="%workdirectory%\%project%") else
if %%j=="xampp-control.exe"(set pathtopen=%xampp%\&&set dirpath=)
tasklist /FI "IMAGENAME eq %%j" 2>NUL | find /I /N "%%j">NUL
if "%ERRORLEVEL%"=="1" goto notstartedsublimetext
if "%ERRORLEVEL%"=="0" goto startedsublimetext
:notstartedsublimetext
Echo started %%j at %time%
pause
start /d "%pathtopen%" %%j %dirpath%
:startedsublimetext
echo %%j is already running......
)
I would suggest possibly changing the structure to this:
#Echo Off
For %%A In ("C:\Program Files\SomeName\madeup.exe"
"C:\Users\Vibrations\Portables\Some Name\dummy.exe"
"C:\Windows\built-in.exe"
) Do TaskList|FindStr/BRIC:"%%~nxA\>">Nul&&(Echo %%~nxA already running
)||(Start "" "%%~A"&Echo Started %%~nxA at %TIME%)
Pause
Just list the full paths to the executables you want to check/start similarly to the three I've used as an example
Edit
As a result of the latest comment, here is an example of what I assume you're trying to do by way of your modification, (replace from line 6):
)||(If "%%~nxA"=="sublime_text.exe" (Start "" "%%~A" "%workdirectory%\%project%"
) Else Start "" "%%~A"
Echo Started %%~nxA at %TIME%)
Pause
#echo off
setlocal
#rem Variables to be set.
#rem changedir is an optional pushd on each call of :notstarted.
#rem startdir is passed to the /d argument in the start command.
#rem programpath is the path to the program executable.
#rem args are any arguments to pass to the program executable.
#rem Variables are undefined at start of loop.
echo will now go ahead and load the essential programs needed for project: %project%
set "programlistopen=wordpad.exe notepad.exe"
for %%j in (%programlistopen%) do (
for %%B in (changedir startdir programpath args) do set "%%~B="
if "%%~j" == "wordpad.exe" (
set "changedir=%userprofile%"
set "startdir=%cd%"
set "programpath=C:\Program Files\Windows NT\Accessories"
) else if "%%~j" == "notepad.exe" (
rem Nothing to set. Just start notepad.exe.
)
tasklist /FI "IMAGENAME eq %%~j" 2>NUL | find /I /N "%%~j" >NUL
if errorlevel 1 (
call :notstarted "%%~j"
) else call :started "%%~j"
)
exit /b
:notstarted
setlocal
echo started "%~1" at %time%
set "cli=start """
if defined startdir set "cli=%cli% /d "%startdir%""
if defined programpath (
set "cli=%cli% "%programpath%\%~1""
) else set "cli=%cli% "%~1""
if defined args set "cli=%cli% %args%"
if defined changedir pushd "%changedir%"
echo %cli%
%cli%
if defined changedir popd
exit /b
:started
echo "%%~1" is already running......
exit /b
Your code has many unknowns so I have done an example which you
can adapt to your needs.
I chose some simple programs like notepad and wordpad to test with.
Variables for use are commented at the top of the script. These
variables are undefined at start of each loop so you do not need
to undefined them and just use the variables that you want to set
with each program.
The errorlevel of tasklist is checked and will call the name of
the label required. This allows the call to return back to the
position of the caller so the loop can continue.
The :notstarted label will bulid the command line (cli) with
each of the defined variables that are relevent to the cli. The
optional pushd and popd was added just for an unusual use.

Batch echo specific line

This is my first post and I am not very skilled with batch so sorry if I really mess up.
Basically I'm working on a little batch script where once run, the user inputs a file path and line number and the specified line of the specified file will be output to the command line. I have all my variables and commands working, and the command to specify the line of the text file works fine, its just when I put my variables in it doesn't work. Now I'm guessing what I'm doing is obviously wrong since I'm new to batch, but anyway here's my code:
#echo off
color b
:top
title specified line copy tool
echo input full path to txt file
set /P filepath=">"
cls
echo what line would you like to copy?
set /P lineoriginal=">"
set /A actualline=%lineoriginal%-1
for /F "skip=%actualline% delims=" %%i in (%filepath%) do if not defined output set "output=%%i"
echo %output%
pause
See if you can see what I did wrong, thanks.
From this link Windows Batch file to echo a specific line number
you can call this function like that : Call:ReadNthLine <File> <nLine>
:ReadNthLine File nLine
FOR /F %%A IN ('^<"%~1" FIND /C /V ""') DO IF %2 GTR %%A (ECHO Error: No such line %2. 1>&2 & EXIT /b 1)
FOR /F "tokens=1* delims=]" %%A IN ('^<"%~1" FIND /N /V "" ^| FINDSTR /B /C:"[%2]"') DO ECHO.%%B
EXIT /b
And your code can be re-written like that :
#echo off
color b
:top
cls
title specified line copy tool
echo input full path to txt file
set /P "filepath=>"
cls
echo what line would you like to copy ?
set /P "nLine=>"
cls
CALL :ReadNthLine "%filepath%" %nLine%
PAUSE >NUL & goto:top
GOTO :EOF
::***************************************************************************************
:ReadNthLine File nLine
FOR /F %%A IN ('^<"%~1" FIND /C /V ""') DO IF %2 GTR %%A (ECHO Error: No such line %2. 1>&2 & EXIT /b 1)
FOR /F "tokens=1* delims=]" %%A IN ('^<"%~1" FIND /N /V "" ^| FINDSTR /B /C:"[%2]"') DO ECHO.%%B
EXIT /b
::***************************************************************************************

Batch File Loop Issue

Ok, I have spent the better half of the last like 6 hours trying to get this to work and I'm nearly pulling my hair out. If someone could help be figure this out I would be eternally grateful.
#ECHO on
SETLOCAL ENABLEEXTENSIONS
SETLOCAL ENABLEDELAYEDEXPANSION
CALL:MicrsoftInstaller-IntegrityCheck "x86" "KB978601" "2010\MS10-019\WinSec-MS10-019-011-P57297-Windows6.1-KB978601-x86.msu" "/quiet /norestart"
pause
:MicrsoftInstaller-IntegrityCheck
SET MSCheck="%~1"
IF "%~1" NEQ "" (
IF /I %MSCheck:~1,1%=="/" SET MSI_Switch=%MSCheck%
IF /I %MSCheck:~1,2%=="20" SET MSI_Path=%MSCheck%
IF /I %MSCheck:~1,20%=="KB" SET MSI_KB=%MSCheck%
IF /I %MSCheck%=="x64" SET MSI_Architecture=x64
IF /I %MSCheck%=="x86" SET MSI_Architecture=x86
SHIFT
GOTO:MicrsoftInstaller-IntegrityCheck
)
ECHO KB: %MSI_KB%
ECHO Switches: %MSI_Switch%
ECHO Path: %MSI_Path%
ECHO Architecture: %MSI_Architecture%
GOTO:EOF
Some small changes were necessary to make it work:
#ECHO off
SETLOCAL ENABLEEXTENSIONS
SETLOCAL ENABLEDELAYEDEXPANSION
CALL:MicrsoftInstaller-IntegrityCheck "x86" "KB978601" "2010\MS10-019\WinSec-MS10-019-011-P57297-Windows6.1-KB978601-x86.msu" "/quiet /norestart"
pause
:MicrsoftInstaller-IntegrityCheck
SET MSCheck="%~1"
IF "%~1" EQU "" GOTO Part2
IF /I "%MSCHECK:~1,1%"=="/" SET MSI_Switch=%MSCheck%
IF /I "%MSCheck:~1,2%"=="20" SET MSI_Path=%MSCheck%
IF /I "%MSCheck:~1,2%"=="KB" SET MSI_KB=%MSCheck%
IF /I %MSCheck%=="x64" SET MSI_Architecture=x64
IF /I %MSCheck%=="x86" SET MSI_Architecture=x86
SHIFT
GOTO:MicrsoftInstaller-IntegrityCheck
:Part2
ECHO KB: %MSI_KB%
ECHO Switches: %MSI_Switch%
ECHO Path: %MSI_Path%
ECHO Architecture: %MSI_Architecture%
GOTO:EOF
First I added some double-quotes in your if statements.
The second problem is linked to how Batch interprets code: line after line. When it came to your line IF "%~1" NEQ "" ( it tried to interpret the following code block even when the condition was not satisfied (=no more argument to check). But with MSCHECK equal to "", the first if statement became IF /I """=="/" which resulted in an error.

Determining if batch script has been started/executed from the command line (cmd) -or- To pause or not to pause?

I like to have a typical "usage:" line in my cmd.exe scripts — if a parameter is missing, user is given simple reminder of how the script is to be used.
The problem is that I can't safely predict whether potential user would use GUI or CLI. If somebody using GUI double-clicks this script in Explorer window, they won't have chance to read anything, unless I pause the window. If they use CLI, pause will bother them.
So I'm looking for a way to detect it.
#echo off
if _%1_==__ (
echo usage: %nx0: filename
rem now pause or not to pause?
)
Is there a nice solution on this?
You can check the value of %CMDCMDLINE% variable. It contains the command that was used to launch cmd.exe.
I prepared a test .bat file:
#Echo Off
echo %CMDCMDLINE%
pause
When run from inside of open cmd.exe window, the script prints "C:\Windows\system32\cmd.exe".
When run by double-clicking, it prints cmd /c ""C:\Users\mbu\Desktop\test.bat" "
So to check if your script was launched by double-clicking you need to check if %cmdcmdline% contains the path to your script. The final solution would look like this:
#echo off
set interactive=1
echo %cmdcmdline% | find /i "%~0" >nul
if not errorlevel 1 set interactive=0
rem now I can use %interactive% anywhere
if _%1_==__ (
echo usage: %~nx0 filename
if _%interactive%_==_0_ pause
)
Edit: implemented fixes for issues changes discussed in comments; edited example to demonstrate them
:: exit if not interactive
echo %CMDCMDLINE% | find /i "/c"
if not ERRORLEVEL 1 goto:eof
Here, I wrote something...
Usage.bat
#echo off
if arg%1==arg goto help
goto action
:action
echo do something...
goto end
:help
set help1=This is Help line 1.
set help2=This is Help line 2.
cmd.exe /k "echo %help1% &echo %help2%"
goto end
:end
It's not perfect, but it works! :D
-joedf
This is only using the internal command. so effectively....
EnableDelayedExpansion
if "!cmdcmdline!" neq "!cmdcmdline:%~f0=!" pause >nul
or
if not "!cmdcmdline!" == "!cmdcmdline:%~f0=!" pause >nul
DisableDelayedExpansion
if "%cmdcmdline%" neq "%cmdcmdline:%~f0=%" pause >nul
or
if not "%cmdcmdline%" == "%cmdcmdline:%~f0=%" pause >nul
Start your batch checking for %WINDIR% in %cmdcmdline% like this:
echo "%cmdcmdline%" | findstr /ic:"%windir%" >nul && (
echo Interactive run of: %0 is not allowed
pause
exit /B 1
)
Please use findstr
echo %cmdcmdline% | findstr /ic:"%~f0" >nul && ( pause >nul )
or
setlocal EnableDelayedExpansion
.
.
echo !cmdcmdline! | findstr /ic:"%~f0" >nul && ( pause >nul )
.
.
endlocal
This is always worked...
for internal command
setlocal EnableDelayedExpansion
set "cmddiff=!cmdcmdline:~0,1!" & if !cmddiff! neq ^" ( pause >nul )
endlocal
or
setlocal EnableDelayedExpansion
set "cmddiff=!cmdcmdline:~28,1!" & if !cmddiff! neq ^" ( pause >nul )
endlocal
You can compare the different thing, but this is only worked within EnableDelayedExpansion. and I don't think that this will be always worked, cause windows version, etc...
Similar approach...
setlocal
set startedFromExplorer=
echo %cmdcmdline% | find /i "cmd.exe /c """"%~0""" >nul
if not errorlevel 1 set startedFromExplorer=1
...
if defined startedFromExplorer pause
goto :EOF
setlocal EnableDelayedExpansion
if "!cmdcmdline!" neq "!cmdcmdline:%comspec%=!" ( pause>nul )
Test is done in Windows 10. Using %windir%, it is a little dangerous or ambiguous. So %comspec% is super safe.

Resources