- ครั้งก่อนตัวอย่างไม่ค่อยแจ่ม
- อันนี้แจ่มมากๆ
- ที่มา http://www.robvanderwoude.com/clevertricks.php
- แนะนำถ้าเขียน batch file บน windows ใช้ notepad++ แจ่มสุดแหละ
Many clever tricks are mentioned on my other pages, especially Solutions found on alt.msdos.batch
Every now and then a real "jewel" is sent to me by mail or otherwise.
A selection of these tricks will be displayed on this page.
- Remember Reinhard Irnberger's PUSHD trick to automatically map a drive if a UNC path is specified?
I usePUSHD "%~dp0"
ever since, as the first command in any batch file that could be run from a UNC path.
Without thisPUSHD
command, the start/working directory of the batch file will be changed to%windir%\System32
.
Today Denis St-Pierre informed me that this change of working directory also occurs when a batch file is running in elevated mode in Windows Vista, Windows Server 2008 or Windows 7.
I checked, and it occurs too when a script is started with RUNAS or PSEXEC.
I suppose that's because my current/working directory is saved in my "volatile environment" in my profile, and thus is not available in the elevated user's environment.
So there you have it, one more reason to specify (as opposed to assume) the working directory in your batch files.
I thinkPUSHD "%~dp0"
is by far the most reliable way to do this, and it will work with RUNAS, PSEXEC, UNC paths, UAC and Explorer's "Run as..." option.
Thanks Reinhard and Denis - A message by Steve Lessard:
Doing basic string substitution as described on www.robvanderwoude.com/ntset.php was pretty easy when using constant values.
But it took me a while to figure out how to do substitution when the string being substituted was determined programmatically.
Now that I have it figured out I'd like to share it with you so that you might be able to share it with all of your readers...Prerequisite:
Delayed expansion must be enabledScript:
SETLOCAL ENABLEDELAYEDEXPANSION
SET HOSTS_FILE=C:\Windows\System32\drivers\etc\hosts
SET VARIABLE_HOSTS_FILE=!HOSTS_FILE:%SystemRoot%=%%SystemRoot%%!
ECHO HOSTS_FILE=%HOSTS_FILE%
ECHO VARIABLE_HOSTS_FILE=%VARIABLE_HOSTS_FILE%
ENDLOCAL
GOTO:EOFOutput:
HOSTS_FILE=C:\Windows\System32\drivers\etc\hosts
VARIABLE_HOSTS_FILE=%SystemRoot%\System32\drivers\etc\hostsI used this kind of substitution to create machine independent instructions for fellow developers and testers to re-run my unit tests under their machine's source code location.
Here's a sample of my script's output:ECHO To repeat this test run use the following command: pushd "%_LCSROOT%\dev\server\eps\CollaborationApi\utest\OotyTests\" & runall /run=x& popd
Thanks Steve - Ever tried
SET /A
to work with really large numbers?
Then you may already know that numbers in batch math are severely limited in size.
Brian Williams submitted 2 batch files that work with large numbers: IsLarger.cmd and Multiply.cmd:
I want to submit these scripts/subroutines for the world to use, it allows one to multiply two numbers that are much larger than the limitations of
SET /A
.
I don't know if I have plans to create more math related subroutines, but it seemed to be a necessity to do math in batch and not have to use some third party tool or another script language.The point of Multiply.cmd and IsLarger.cmd is to work with number beyond the command lines ability.
You can Multiply an integer of hundreds of digits by another integer of many if not hundreds of digits.
Also IsLarger.cmd can compare integers of thousands of digits long.
The best part is this is all native NT Shell scripting tested on Windows XP, Windows 2003, and Windows Vista. (It might work on Windows 2000 - don't know haven't tried). No third party utilities are needed or reliance upon vbscript or some other language.I submitted these as batch files, but the subroutines starting with the labels
:Multiply
and:IsLarger
is all you need to paste in your batch file to start using these - one other requirement, you have to haveSETLOCAL ENABLEDELAYEDEXPANSION
in your script for this to work.Syntax in your script:
CALL :MULTIPLY CrazyLongNumber OtherCrazyLongNumber MyFavoriteVariable
Do not surround your variables with percents or bangs (you are passing a reference to the variable, not the actual variable)
CALL :MULTIPLY VariableContainingBigNumber OtherVariableConatiningBigNumber_GiveItToMeVariable
or if you use my script as is its just
MULTIPLY.CMD 121390487120394780398 123498712304981703948097
and you get the answer.
Multiply.cmd 2 2
4Same thing with IsLarger, prints TRUE, FALSE, or EQUAL (you are saying, is this first number larger than this second number?)
IsLarger.CMD 2948372948273234234 2342983472938472938472342342342342234234
FALSE
IsLarger.CMD 5 4
TRUE
IsLarger.cmd 1 2
FALSE
IsLarger.cmd 2 2
EQUALIf you use just the subroutine, no percents or bangs:
CALL :IsLarger _BIGNUMBER1 _BIGNUMBER2 _MYVARIABLE
I won't display the complete code here, the ZIPped sources for the batch files can be downloaded here.
I do want to show you the main trick that is used in both batch files:
FOR /L %%B IN (0,1,9) DO SET _NUMVAR=!_NUMVAR:%%B=%%B !
Note the space in the part of the code that was marked red: it means a space will be inserted after each digit.
Next each digit is multiplied or compared separately in a "regular"FOR
loop.
Brilliant!
Thanks Brian - Leonardo Gutierrez Ramirez found a way to use numbers as variables in a FOR loop:
Combined with Carlos Montiers' extension of the available variables in FOR loops, we can now, in theory at least, nest up to 75 FOR loops!Hi, I have discovered that we can use numbers in the variable FOR command, like this:
FOR /L %%ˆ6 IN (1 1 10) DO (
ECHO %%ˆ6
)
FOR /D /R %%ˆ2 IN (*) DO (
ECHO %%ˆ2
)
FOR /F "tokens=1,2,3" %%ˆ0 IN ('VER') DO (
ECHO.%%ˆ0 %%ˆ1 %%ˆ2
)
FOR %%ˆ1 IN ("%~nx0") DO (
ECHO %%~nxtˆ1
)
FOR /F "tokens=1" %%ˆ7 IN ('VER') DO (
ECHO.%%ˆ7
)
FOR %%ˆ1 IN ("%~nx0") DO (
ECHO %%~nxatdˆ1
)
Not that I would want to maintain such code...
Thanks Leo - Leonardo Gutierrez Ramirez found a way to add any (language) style comments to
SET /P
commands:
@echo off
set /p "suma=2+2 : " # La suma, my comment
if %suma% equ 4 (
echo.Bien
) else (
echo.Mal
)
set suma
@echo off
set /p "suma=2+2 : " // La suma
if %suma% equ 4 (
echo.Bien
) else (
echo.Mal
)
set suma
@echo off
set /p "suma=2+2 : " /* La suma */
if %suma% equ 4 (
echo.Bien
) else (
echo.Mal
)
set suma
@echo off
set /p "suma=2+2 : " ' Comment
if %suma% equ 4 (
echo.Bien
) else (
echo.Mal
)
set suma
@echo off
set /p "suma=2+2 : " Comment
if %suma% equ 4 (
echo.Bien
) else (
echo.Mal
)
set suma
@echo off
for %%. in (H e l l o _ W o r l d) do (
call :show %%.
)
goto:eof
:show
nul
goto:eof
As a matter of fact, any text after the closing doublequote is ignored.
Thanks Leo - Carlos Montiers found a way to increase the number of variables available in a
FOR /F
loop (I added some highlighting to discriminate between the individual lines):
Wow! I need a wider screen.I just discovered that you can use more than 26 characters in the command
for /f
, so we can reach a limit of 31 tokens.
In orderfor /f "tokens=1"
or simplyfor /f
can use the following characters:& : <
We can start from and arrive at characters within this range from low to high:> ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ˆ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | }
Note: The following characters must be escaped with a caret (ˆ):ˆ < > | &
as follows:ˆˆ ˆ< ˆ> ˆ| ˆ&
Finally a few examples:
@echo off
set palabras=p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 p17 p18 p19 p20 p21 p22 p23 p24 p25 p26 p27 p28 p29 p30 p31 p32 p33 p34 p35
for /f "tokens=1" %%ˆ& in ("%palabras%") do (echo %%ˆ&)
for /f "tokens=1" %%ˆ<>
for /f "tokens=1,2,3" %%ˆ> in ("%palabras%") do (echo %%ˆ>%%?%%@)
for /f "tokens=1-31" %%? in ("%palabras%") do (echo %%?%%@%%A%%B%%C%%D%%E%%F%%G%%H%%I%%J%%K%%L%%M%%N%%O%%P%%Q%%R%%S%%T%%U%%V%%W%%X%%Y%%Z%%[%%\%%])
for /f "tokens=1-31" %%ˆˆ in ("%palabras%") do (echo %%ˆˆ%%_%%`%%a%%b%%c%%d%%e%%f%%g%%h%%i%%j%%k%%l%%m%%n%%o%%p%%q%%r%%s%%t%%u%%v%%w%%x%%y%%z%%{%%ˆ|)
for /f "tokens=1-31" %%_ in ("%palabras%") do (echo %%_%%`%%a%%b%%c%%d%%e%%f%%g%%h%%i%%j%%k%%l%%m%%n%%o%%p%%q%%r%%s%%t%%u%%v%%w%%x%%y%%z%%{%%ˆ|%%})
pause
updated
The value of my discovery is that for example if, before declaring:
for /f "tokens=1-4" %%Y in ("p1 p2 p3 p4") do (echo %%Y%%Z...)
and wanted to show the token 1,2,3,4 we could only show the token 1 and 2, because then comes %%Y and %%Z then ... we did not know that letter came.
So now we can do:
for /f "tokens=1-4" %%Y in ("p1 p2 p3 p4") do (echo %%Y%%Z%%[%%\)
The other, the documents said 52 variables, ie 26 + 26 (az) and (AZ) for an inside another for, or for using a single letter of the alphabet any case, but now we have more than 65 variables, for example:
@echo off
for /f "tokens=1-10" %%ˆ> in ("El cmd.exe es el interprete de comandos en OS2 y") do (
for /f "tokens=1-10" %%H in ("sistemas basados en Windows NT incluyendo Windows 2000 Windows XP") do (
for /f "tokens=1-8" %%R in ("Windows Server 2003 y Windows Vista. Es el") do (
for /f "tokens=1-12" %%Z in ("equivalente de command.com en MS-DOS y sistemas de la familia Windows 9x.") do (
for /f "tokens=1-10" %%f in ("A diferencia de su antecesor command.com este programa es tan") do (
for /f "tokens=1-14" %%p in ("solo una aplicacion no es una parte del sistema operativo y no posee la") do (
echo %%ˆ>%%?%%@%%A%%B%%C%%D%%E%%F%%G%%H%%I%%J%%K%%L%%M%%N%%O%%P%%Q%%R%%S%%T%%U%%V%%W%%X%%Y%%Z%%[%%\%%]%%ˆˆ%%_%%`%%a%%b%%c%%d%%e%%f%%g%%h%%i%%j%%k%%l%%m%%n%%o%%p%%q%%r%%s%%t%%u%%v%%w%%x%%y%%z%%{%%ˆ|%%}
)
)
)
)
)
)
pause
So, in summary, my discovery increases the maximum of 26 to 31 tokens, and the maximum for the global variables, from 52 to over 65, more say in the example just because they are used within the range, but not individual characters.
Written by Carlos Montiers.
Thanks Carlos
Read more details: follow the discussion at the forum at Simon Sheppard's site. - Nushu sent me a message with a nice technique to combine multiple scripting languages in a single script:
Nice trick, and it can be used for KiXtart scripts too!The purpose is to be able to execute AutoIT code directly from inside a batch file (and so not having to worry about .au3 being associated with autoit).
.CMD file begins :
-------------------------------------------
; ::Batch code ,cmd.exe will run the lines beginning with comma and exit
; @echo off
; start C:\AutoIT\AutoIT3.exe %0 %*
; exit
; :: AutoIT code , autoit will ignore the lines beginning with semicolon
MsgBox (0 , "Box" , "Just A Box")
-------------------------------------------
.CMD file ends
Try the following code, saved as batch file; if KiXtart is available (andKIX32.EXE
is in the PATH) it will display the current date and time in YYYYMMDDHHmmss format:
; @ECHO OFF
; KIX32.EXE "%~f0"
; EXIT
$RC = SetOption( "ASCII", "ON" )
SubStr( @Date, 1, 4 )
SubStr( @Date, 6, 2 )
SubStr( @Date, 9, 2 )
SubStr( @Time, 1, 2 )
SubStr( @Time, 4, 2 )
SubStr( @Time, 7, 2 )
It can even be used in .REG files!
Thanks Nushu - One never stops learning, as this new trick by Justin proves:
Marvellous!Recently I came across a little trick using the REN command (tested on XP).
It is possible to use REN to delete every character after the last occurrence of a character by using the wildcard * followed by the desired character:
REM Rename filename.ext to filena
REN filename.ext *a
If you wanted to use a space or ampersand it would need to be contained in double quotes i.e.
REN "good&bad" "*&"
If you use a dot "*." the dot will also be trimmed off by windows because it doesn't allow file names to end with a dot.
Very simple but seemingly undocumented...............
Thanks Justin - I must confess, this tip by Leo Gutierrez Ramirez baffled me.
I didn't expect it to work, but it does.
See for yourself:
@ECHO OFF
REM Code:
ECHO Hello
REM Comments:
(COMMENT
HELLO!
HI!
The trick is not in the exclamation marks, it is the fact that the parenthesis opens a "code block" which is never closed, and thus seems to be ignored completely by the command interpreter.
As Leo said: a useful way to add comments at the end of a batch file.
Thanks Leo - Carlos Montiers sent me this "typewriter" batch file:
@ECHO OFF
CALL :Put Me canse de escribir tantas lineas ...
CALL :Put Este es el typewritter effect reloaded
CALL :Put o echo dinamico xD
>NUL PAUSE
GOTO:EOF
:Put
IF NOT DEFINED .m_ SET.m_=%*
IF NOT DEFINED .m_ GOTO:EOF
NUL PING -n 10
SET .m_=%.m_:˜1%
IF DEFINED .m_ (GOTO:Put) ELSE (ECHO.)
GOTO:EOF
Try it out, and see if you understand how it works.
Thanks Carlos - Justin wrote:
I was looking at you tips and tricks section and noticed you have a way to get the first and last line of a text file, but what it you want the /nth /line of text...
This trick takes advantage of two features of NT batch, calling batch labels and GOTO :EOF, which of course ends a call(or batch). The folowing will get the third line of a text file and set it to the variable TEXT_LINE.
SET NthLine=3
SET /A NthLine-=1
CALL :LINEGRAB
GOTO RESTOFFILE
:LINEGRAB
FOR /F "skip=%NthLine% tokens=*" %%G IN (TEXTFILE.TXT) DO SET TEXT_LINE=%%G&&GOTO :EOF
:RESTOFFILE
There is one limitation to this, because for /f skips blank lines any blank lines will cause the line grabbed to be off.
Thanks Justin.
While adding this tip to this web page, the following idea came up (combining this tip with John Taylor's):
SET /A NthLine -= 1
TYPE textfile ˆ| MORE /E +%NthLine% > "%Temp%.\~nthline.tmp"
SET /P TextLine= < "%Temp%.\~nthline.tmp"
This will also set the value of variable TextLine to the content of the nth line of textfile.
A big advantage is MORE doesn't ignore empty lines.
Unfortunately it involves the use of a temporary file.
But how about this:
SET NthLine=3
SET /A NthLine -= 1
CALL :LINEGRAB
GOTO RESTOFFILE
:LINEGRAB
FOR /F "tokens=*" %%A IN ('MORE /E +%NthLine% TEXTFILE.TXT') DO (
SET TextLine=%%A
GOTO:EOF
)
:RESTOFFILE
It doesn't use a temporary file.
Any disadvantages, anyone...? - Jeffrey Ehrhart wrote to me:
• For the DIR command, adding the /S flag to the /B will fully qualify file and directory names. Of course, using the /S flag will search all subdirectories which may not be what you want.
Examples:
DIR /B /S C:\Temp
C:\Temp\A.txt
C:\Temp\B.txt
DIR /B C:\Temp
A.txt
B.txt
• If you add the /S flag when deleting a specific file, you will get a resulting message with the file name fully qualified. Again, use the /S flag with caution on a delete. Without the /S flag, you do not get a message.
Example:
C:\Temp>
DEL /S A.txt
Deleted file - C:\Temp\A.txt
C:\Temp>
Thanks Jeffrey, I'll certainly keep that in mind.
But, as Jeffrey states, it is risky, unless of course there are no subdirectories involved. - A message from Matthew W. Helton:
Rob,
I feel your pain about finding a logged-on user... but there is hope from the most unlikely of places... using Netsh.
netsh diag show computer /v
Checkout near the bottom:UserName =
If there is no username, there is no logged-on user. Sweet!
Programmatically in Batch:
FOR /F "tokens=3" %%a IN ('netsh diag show computer /v ˆ| FIND /i "username"') DO ECHO %%a
Remotely using Batch via Psexec:
SET REMOTE_COMPUTER=%1
FOR /F "tokens=3" %%a IN ('PSEXEC.exe \\%REMOTE_COMPUTER% netsh diag show computer /v ˆ| FIND /i "username"') DO ECHO %%a
Note: this only gets you the locally logged-on user: Windows Server 2003 Terminal Services Users will not show up on this.
Great, thanks Matthew.
In theory, using NETSH's own-r \\%REMOTE_COMPUTER%
switch should do the trick without the need for PSEXEC, but my own tests using this switch failed.
PSEXEC will do the trick.
Experiment with the output of theNETSH Diag Show Computer /V
command, there is a lot of valuable information available. - A beautiful feature discovered by John Taylor: how to use
SET /P
to read the first line of a file and store it in an environment variable.
Try these commands, and notice the differences:
SET /P TestVar=
You see?SET /P
reads the first line, whereasFOR /F
reads the last line!
Thanks, John. - A great feature discovered by Reinhard Irnberger:
Wow! Great!Sometimes it is necessary to get a Driveletter from a mapping.
Normally you will define a fixed Driveletter which you will map to your Remote path.
After you have done all things you will delete the drive mapping.
I found an simple solution for Windows Server 2003. Maybe it's also working in Windows 2000.
WithPUSHD \\Server\Share\[path]
the system automatically creates a driveletter for you and jumps to it.
In the next step you can get the current Drive with %CD%.
When you usePOPD
you will jump back and the drivemapping is also deleted.
Attention: BecausePUSHD
can be nested you have to make sure that withPOPD
you don't delete your current directory!
In my scripts I will use the following lines to Map a remote path:
PUSHD \\Server\Share\path
SET rmt=%CD%
CALL %rmt%\script.cmd
This works in Windows NT 4 (SP6a), 2000 and XP (Professional) too.
Thanks, Reinhard.
Update:
Daniel Schmidt reported that this trick does not work in scheduled tasks in Windows 2000 Server. I tried it on my Windows XP machine, and it did work, so this may be a Windows 2000 issue (bug). Always test before implementing any script.
Daniel Schmidt also sent me this link to a Microsoft KnowledgeBase article documenting this trick (for Windows 2000 Server!).
Thanks, Daniel.
Here is a simple batch file to test if the PUSHD trick works in scheduled tasks on your computer:
PUSHD \\server\sharename
CD >> C:\pushdtest.log
POPD
CD >> C:\pushdtest.log
Run it twice, first from the command line, and then scheduled with your own credentials. C:\pushdtest.log should contain 4 (when run twice) lines like these:
X:\
C:\
X:\
C:\ - A nice tip by Chris Greenbank:
Thanks, Chris.Under XP (And I assume NT/2000 as well) it is possible to create a group of commands from the command line (not a batch file). This is useful for, among other things, copy&pasting scripts off of the internet for testing without saving. To do this, just type "(" and hit enter, enter each command one by one (or paste a previously copied list of commands), then type ")" and hit enter.
As well, it allows for groups of commands intended to be executed sequentially to be entered beforehand then allowed to run, useful if you are running external programs that you need to wait for and don't want to write a batch file for that specific job.
Output for every command may also be redirected at the end of the block, in the same manner as Tip 7 on the Clever Tricks page: ") > log.txt" instead of just ")"
C:\>(
More? cd
More? echo %windir%
More? echo This may be useful to someone wanting
More? echo to enter multiple commands in a row...
More? )
C:\
C:\WINDOWS
This may be useful to someone wanting
to enter multiple commands in a row...
C:\> - And another tip by Chris Greenbank, about escaping linefeeds:
Thanks, Chris.Well, now I just found something more useful: A way to increase readability.
After thinking about why this works under NT/etc, I realized its because under windows, a physical linebreak is represented by 2 characters, and the escape character only escapes one of them, leaving the other there. My guess is that under OS/2, a linebreak is only a single character.
After some testing, I found that using just the second half of the linebreak, its possible to make it all neat and non-spaced out (the hex value is shown in notepad as a square, it won't provide a physical linebreak):
ECHO testˆ
testˆ<0a>
testˆ<0a>
test
will result in:
test
test
test
test
To use in a SET command:
SET var=testˆˆˆ<0a><0a>ˆ<0a>
testˆˆˆ<0a><0a>ˆ<0a>
testˆˆˆ<0a><0a>ˆ<0a>
test
ECHO %var%
will result in:
test
test
test
test
The reason that the <0a> is repeated twice is that the first one is ignored, which would be interpreted asˆˆˆˆ
which is not what is wanted. Having a few control codes on the end instead of excessive linebreaks is much more readable, while providing the same behaviour. The only requirement is that you be able to enter the correct value. - Martin Richards wrote about IBM's E-Gatherer tool:
I have [...] discovered that you can run '
egather2 -local
' to output the native XML file rather than the .eg2 file.
You can also specify which information is output by egather2 by specify the probe name on the command line, eg:
egather2 -local -probe SYSTEM_SUMMARYYou can get a list of probe names to specify by running
egather2 -listprobesWell, this sure is a nice simple replacement for my (now obsolete) SNDisk2.bat.
Thanks, Martin
Continuing Martin's research I have discovered even more undocumented command line switches.
I used the command:
to find the following possible switches:
STRINGS -a EGATHER2.EXE | FINDSTR /R /B /I /C:"-[A-Z0-9][A-Z0-9]"
Try the
-Y2
-ht
-wB
-binaryfile
-xmlfile
-textfile
-asciifile
-dgmlfile
-vpd
-stdout
-local
-probe
-probes
-listprobes
-html
-filename
-level
-debug
-step
-nolimit
-silent
-batch
-help
-64OS
-zc-help
switch and you'll notice that most of these switches are indeed undocumented.
Experiment with these switches, you may find some are of great value.
My favorite so far:
which I used in my new SNDisk3.bat.
EGATHER2 -html -batch
Or add this one to your login script:
(no space between
EGATHER2 -html -batch -filename\\remoteserver\remoteshare\%ComputerName%-filename
and the actual file name; and no extension, the-html
switch will take care of that) - From Fred Langa and several other sources came this tip to add a Compatibility Mode tab to all shortcuts' properties in Windows 2000 (SP2 or later).
Run the following command only once:
From that moment on you can choose to run any program in Windows 95 or NT 4 compatibility mode.
REGSVR32 %systemroot%\apppatch\slayerui.dll - James Higgs sent me a nice PAUSE replacement using Windows 2000's SET /P:
Unlike PAUSE, which accepts any key, SET /P will only accept the Enter key.
ECHO Press Enter to continue . . .
SET /P =
Josh Murray sent me an improvement, a one-liner with the same functionality:
SET /P =Press Enter to continue . . . - Gabor Funk showed me this undocumented feature of the DIR command:
which is shorthand for:
DIR,
Works only in COMMAND.COM (tested in Windows 2000).
DIR /A - An ingenious way to use CHOICE is demonstrated by Laurence Soucy's version(s) of BootDriv.bat.
The same trick could be used to determine the current drive letter:
:: bootdrv1.bat
@ECHO off
:: By Laurence Soucy
:: http://www.bigfoot.com/~batfiles/
::
:: To place drive letter into variable
ECHO %comspec%|choice.com/n/c%comspec% set bootdrv=>%temp%.\bootdrv$.bat
FOR %%c in (CALL DEL) do %%c %temp%.\bootdrv$.bat
ECHO "%bootdrv%"
Tip (and the bootdrv* batch files themselves) provided by Laurence Soucy
@ECHO OFF
CD | CHOICE /N /C:ABCDEFGHIJKLMNOPQRSTUVWXYZ SET curdrive=>%temp%.\curdrv$.bat
FOR %%A IN (CALL DEL) DO %%A %temp%.\curdrv$.bat
ECHO "%curdrive%"
- Group commands for redirection:
To log the result of several commands, a commonly used method is
In Windows NT4/2000/XP command grouping can be used to simplify the code:
command1 > logfile.log
command2 >> logfile.log
command3 >> logfile.log
Tip provided by Dave Denholm
(
command1
command2
command3
) > logfile.log - Use VER to prevent NET USE asking for a password in NT:
Note: this will skip the drive mapping and display an error message if the user ID/password combination is invalid (in other words: if you don't have the rights you just won't get the drive mapping)
VER | NET USE * \\server\share [ /USER:domain\user ]
This trick works because VER's output starts with an empty line, which -- when redirected like this -- has the same result as pressing the Enter key
Tip provided by Justin F. Kuo - Check if a server is available:
A well known way to check if a server is stil "on the air" is
In Windows 95/98/NT this will result in 4 tries from PING to detect the presence of server.
PING server | FIND "TTL=" >NUL
IF ERRORLEVEL 1 ECHO Error pinging server
When checking large amounts of servers, some time could be saved by a fast check, followed by a more thorough check only when the first check fails.
Tip provided by Mark Johnson, and improved (using "TTL=" instead of "TTL") by Richard Parvass
PING server -n 1 | FIND "TTL=" >NUL
IF NOT ERRORLEVEL 1 GOTO Next
PING server -w 3000 | FIND "TTL=" >NUL
IF ERRORLEVEL 1 ECHO Error pinging server
:Next - Swap your mouse to left handed use:
- Windows 95:
RUNDLL USER.EXE,SwapMouseButton - Windows NT:
RUNDLL32 USER32.DLL,SwapMouseButton
I know of no command yet to undo this, but the following will get you close:
or:
CONTROL MAIN.CPL
RUNDLL32 SHELL32.DLL,Control_RunDLL MAIN.CPL,@0,1 - Windows 95:
- Start DialUp Network:
The RUNDLL command starts DUN, the TRACERT command is supposed to actually start the dialing process. Since I do not have access to any PC with DUN installed, I could not test the TRACERT command's effect.
START RUNDLL32 RNAUI.DLL,RnaDial exact name of dialer entry
TRACERT -h 1 -w 1
Tip provided by Michael J. Gregg and Tom Lavedas on alt.msdos.batch - Resolve host name for specified IP address (Windows NT):
The HostName.bat examples use this trick.
FOR /F "tokens=2 delims= " %%A IN ('PING -a %1 ˆ| FIND "[%1]"') DO ECHO.%%A
Adapt theFIND /V
part if you expect host names containing the (sub)string "TTL".
Tip provided by Marcel van der Wal - Enclose DEBUG scripts in batch file:
Technique first seen at McAfee's site
DEBUG < %0.BAT GOTO Around (do not skip this blank line)
(original DEBUG script goes here)
(do not skip this blank line)
:Around - Check if a scheduled event job is active or not:
Oskar Bäckström sent me this great tip:The win98 tasks scheduler creates .JOB files when you setup a program to run on a certain occasion.
These .JOB files contain information about some things like the path to the program that should be run and probably when it will run.
I've also seen that there's allways a character that indicates wether the .JOB file is active or not.
Checking if a certain task will be run or not could then be done in a batch file:
TYPE C:\Windows\Tasks\Thejobb.job | FIND "%character%" >NUL
IF NOT ERRORLEVEL 1 ECHO Job not active!
IF ERRORLEVEL 1 ECHO Job is active!Where %character% is the one character that will disappear from the .JOB file when it's activated.
I've found that the ASCII 196 is a pretty safe bet, but you should scan the file you want to test, both when you have it activated and when it is inactive.
Then check if it's really this character that differs (I suggest looking at it in notepad, thats how I did it).
If you're really unlucky the active-or-not charcter could be found twice in the file, on its active-or-not position and some other place, this test will then not work.
Check also that your program's name does not contain the control character.Tip provided by Oskar Bäckström
Uncommon use of NT's
SET /A
switch:
As you may or may not be aware, it isn't necessary to specify a variable when usingSET /A
.
Try this:
SET /A 0XFFand you should see the number 255 (the decimal value of the hexadecimal number FF) on screen.
Used without a variable, the result of the mathematical expression is displayed on screen.
As explained on my "Useless Tips" page in more detail, the result is displayed without a carriage return/line feed at the end!
Tip provided by Ken Gould
A final word of thanks to all who sent me their tips and tricks.
No comments:
Post a Comment