The Windows server my team uses recently got upgraded. A batch file, which used to work fine, is now not working due to spacing in a directory path. I believe the robocopy command is failing.
How can I get the command to work properly and recognize the space in the directory path correctly?
Batch file code:
#ECHO OFF
:start
rem GOTO end
if exist %1*_desc.xml (
del %1*_desc.xml
goto final
)
:final
rem Rename files with -en-us
setlocal enabledelayedexpansion
set "Pattern=-en-us"
set "Replace="
for %%# in (%1*.*) do (
set "File=%%~nx#"
ren "%%#" "!_File:%Pattern%=%Replace%!"
)
:end
copy %1*.* %2*.*
::robocopy "%1" "%2" *.*
Command being executed:
D:\scripts\Maintenance\COGCleanup.bat "\\nycb\corp$\group\IT\IT-NY\Application Development\CognosTest\"
Output error message:
\\nycb\corp$\group\IT\IT-NY\Application Development\CognosTest\*.*
Access is denied.
0 file(s) copied.
NOTE: In the above error message, the first part of the directory (before access is denied) is underlined and in blue. I can't replicate it here. The space after Application is what's causing the issue I believe.
If this is the command you used:
D:\scripts\Maintenance\COGCleanup.bat "\\nycb\corp$\group\IT\IT-NY\Application Development\CognosTest\"
%1 is "\\nycb\corp$\group\IT\IT-NY\Application Development\CognosTest\" (quotes included).
%1*.* is "\\nycb\corp$\group\IT\IT-NY\Application Development\CognosTest\"*.*
"%1" is ""\\nycb\corp$\group\IT\IT-NY\Application Development\CognosTest\"" and will be parsed as 2 parameters \\nycb\corp$\group\IT\IT-NY\Application and Development\CognosTest\.
You can fix is by using "%~1" (with quotes).
%~1 is %1 without quotes, if there are quotes. No matter if %1 is "foo" or foo, %~1 is always foo, and "%~1" is always "foo"
Related
While running something like .bat, the "X:\..\..path" often becomes ""X:\..\path and producing errors. For example, I was installing apktool, then it just appeared this:
'""C:\Program' is not recognized as an internal or external command,
operable program or batch file.
I then copy the command and put one of the double quote to the end, which is like this: "C:\Program"
And everything just went smoothly, installation was successful. Then I tried to decode an apk, and the exactly same problem occurred: '""C:\Program' is not recognized as an internal or external command, operable program or batch file. This time I have no idea how to fix it, it's not like the .bat now, I cannot get the #echo on and copy the last command and edit it. So I am here to ask: If I am the only one who met this? Any way to fix this? Thank you.
My command:
apktool d test.apk
Image of running a decode command : 1
apktool.bat content:
#echo off
setlocal
set BASENAME=apktool_
chcp 65001 2>nul >nul
set java_exe=java.exe
if defined JAVA_HOME (
set java_exe="%JAVA_HOME%\bin\java.exe"
)
rem Find the highest version .jar available in the same directory as the script
setlocal EnableDelayedExpansion
pushd "%~dp0"
if exist apktool.jar (
set BASENAME=apktool
goto skipversioned
)
set max=0
for /f "tokens=1* delims=-_.0" %%A in ('dir /b /a-d %BASENAME%*.jar') do if %%~B gtr !max! set max=%%~nB
:skipversioned
popd
setlocal DisableDelayedExpansion
rem Find out if the commandline is a parameterless .jar or directory, for fast unpack/repack
if "%~1"=="" goto load
if not "%~2"=="" goto load
set ATTR=%~a1
if "%ATTR:~0,1%"=="d" (
rem Directory, rebuild
set fastCommand=b
)
if "%ATTR:~0,1%"=="-" if "%~x1"==".apk" (
rem APK file, unpack
set fastCommand=d
)
:load
"%java_exe%" -jar -Duser.language=en -Dfile.encoding=UTF8 "%~dp0%BASENAME%%max%.jar" %fastCommand% %*
rem Pause when ran non interactively
for /f "tokens=2" %%# in ("%cmdcmdline%") do if /i "%%#" equ "/c" pause
Use set "var=value" for setting string values - this avoids problems caused by trailing spaces. Don't assign a terminal \, Space or " - build pathnames from the elements - counterintuitively, it is likely to make the process easier. If the syntax set var="value" is used, then the quotes become part of the value assigned.
set java_exe="%JAVA_HOME%\bin\java.exe"
Should be
set "java_exe=%JAVA_HOME%\bin\java.exe"
(apply this principle throughout your code)
Then, if you require " anywhere, insert it where it's needed - don't try to include it as part of a variable's value.
This should clean up at least some of your problems.
File: stack.bat
#echo off
#setlocal enabledelayedexpansion
for %%a in (%*) do (
call set "%%~1=%%~2"
shift
)
ECHO para1 %--para1%
ECHO para2 %--para2%
if "%--para2%"=="" (
echo missing para2
for /f "eol=: delims=" %F in ('dir /b/o:N %--folder%\*.001') do #set "newest=%F"
echo latest %newest%
)
This batch file is called with:
stack.bat --para1 c:\Sample\temp
The execution results in output of the error message:
N was unexpected at this time.
There is no error if the line for /f "eol=: ... is commented out with command REM.
Delayed expansion is already enabled.
What do I need to do to fix the error?
It is not described what the batch file code should do at all. It looks like it should find the newest file by its name containing most likely a date string in name in a directory passed as argument to the batch file and should define an environment variable with name passed also as argument left to the directory path with the file name of newest file.
I suggest following commented batch code for this purpose:
#echo off
rem Remove this line if the environment variables defined by this batch
rem file should still exist after processing of this batch file finished.
setlocal EnableExtensions DisableDelayedExpansion
rem Delete all environment variables of which name starts with --.
for /F "delims=" %%I in ('set -- 2^>nul') do set "%%I"
:ProcessArguments
rem Get current first argument (option) with surrounding " removed.
set "Option=%~1"
rem Is there no more option?
if not defined Option goto EndBatch
rem Remove all double quotes from the option.
set "Option=%Option:"=%"
rem This condition is just for 100% fail safe code. It should be never true.
if not defined Option goto EndBatch
rem Does the option not start with two hyphens?
if not "%Option:~0,2%" == "--" (
echo ERROR: Invalid option: "%Option%"
echo/
goto EndBatch
)
rem Get current second argument (folder path) with surrounding " removed.
set "Folder=%~2"
rem Is there no folder path?
if not defined Folder goto MissingFolder
rem Remove all double quotes from the folder path.
set "Folder=%Folder:"=%"
rem This condition is just for 100% fail safe code. It should be never true.
if not defined Folder goto MissingFolder
rem Replace all / in folder path by \ as many users type folder paths wrong
rem with slashes as on Linux/Mac instead of backslashes as required on Windows.
set "Folder=%Folder:/=\%"
rem Make sure the last character of folder path is a backslash.
if not "%Folder:~-1%" == "\" set "Folder=%Folder%\"
rem Search in specified folder for *.001 files output reverse by name and
rem define the option as environment variable with first output file name
rem assigned with full qualified absolute path even if environment variable
rem Folder referencing a relative path. Then shift the arguments list by
rem two arguments to the left and process the remaining arguments.
for /F "eol=| delims=" %%I in ('dir "%Folder%*.001" /A-D /B /O-N 2^>nul') do (
for %%J in ("%Folder%%%I") do set "%Option%=%%~fJ"
shift
shift
goto ProcessArguments
)
rem It is not possible to define an environment variable with no string.
rem So an error message is output if no file could be found like on
rem wrong folder path or no *.001 file found in the specified folder.
echo ERROR: Could not find a *.001 file for option "%Option%" in folder:
echo "%Folder%"
echo/
goto Endbatch
:MissingFolder
echo ERROR: Missing folder path for option: "%Option%"
echo/
:EndBatch
set "Option="
set "Folder="
echo Options parsed successfully:
echo/
set -- 2>nul
rem Remove this line if the environment variables defined by this batch
rem file should still exist after processing of this batch file finished.
endlocal
This batch file can be started for example with the command line:
stack.bat --para1 c:\Sample\temp "--para2" "C:/Temp/Development & Test!/" --para3 . --para4 "\Program Files\Internet Explorer\" -para5 .."
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /? ... explains how to reference batch file arguments
dir /?
echo /?
endlocal /?
for /?
goto /?
if /?
rem /?
set /?
setlocal /?
shift /?
Read the Microsoft documentation about Using command redirection operators for an explanation of 2>nul. The redirection operator > must be escaped with caret character ^ on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded dir command line with using a separate command process started in background with %ComSpec% /c and the command line within ' appended as additional arguments.
I suggest also reading:
How does the Windows Command Interpreter (CMD.EXE) parse scripts?
This question with its answers should be read first by every beginner in batch file coding.
Problems checking if string is quoted and adding quotes to string
This answer explains very detailed how to process arguments passed to a batch file.
Syntax error in one of two almost-identical batch scripts: ")" cannot be processed syntactically here
This answer describes common issues made by beginners in batch file coding and how to avoid them.
Why is no string output with 'echo %var%' after using 'set var = text' on command line?
Another extensive answer which describes how to work with environment variables in batch files.
Symbol equivalent to NEQ, LSS, GTR, etc. in Windows batch files
This also very long answer describes in detail how a string comparison is done by Windows command processor and what a batch file writer must take into account on using string comparisons.
I am trying to rename every image in a directory to add the date that each file was created, however, I keep either getting "invalid syntax" or "A duplicate file name exists, or the file cannot be found"
I am running Windows 10, and accessing the images off a flash drive (hence the short file path). I tried having all the code in one for-loop, when that didn't work I tried using batch functions, no dice. I did see someone mention on another thread to use delayed expansion, I would be up for using this if someone could give a better explanation than the /? command.
#echo off
REM batch file is placed in top of F drive, same as "images 2017+"
cd "F:\images 2017+"
FOR /R "F:\images 2017+" %%F in (*.jpg) do call :renER "%%~nF" "%%~tF"
goto :eof
:renER
cd "F:\images 2017+"
pause
echo %1
echo %2
rename %1.jpg %1_%2.jpg
pause
goto :eof
:end
For every .jpg file in "images 2017+", the date which that file was created would be stuck onto the end after a space.
thisIsMyFile.jpg made at 5-13-2017, would become thisIsMyFile 5-13-2017.jpg
Current output
EDIT:
I am CDing into the same directory as the images are, then using the passed variables to locate the correct image (The date is one of the passed variables, and shows up in the echo command).
I notice that you only want the date, not the time so you can do that as follows using your existing Call to a label, There is also no need to use FOR /R in this case so I'll use a normal for loop:
#echo off
FOR %%A IN ("F:\images 2017+\*.jpg") DO (
CALL :RenER "%%~fA" %%~tA
)
GOTO :eof
:RenER
PAUSE
ECHO %1
ECHO %2
SET "_tmp=%~2"
SET "_tmp=%tmp:/=-"
REN "%~1" "%~n1_%_tmp%%~x1"
PAUSE
GOTO :eof
Notice how above we are dropping the Time off immediately by not wrapping it in quotes since you don't want that to be part of the file name.
You can also forgo the call to a label entirely without needing delayed expansion by using a second loop, as a matter of preference I think this is quite a bit cleaner!
#echo off
FOR %%A IN ("F:\images 2017+\*.jpg") DO (
FOR /F "Tokens=1-3 Delims=/ " %%a IN ('echo.%%~tA') DO (
PAUSE
ECHO.%%~fA
ECHO.%%~tA
REN "%%~fA" "%%~nA_%%a-%%b-%%c%%~xA"
PAUSE
)
)
this is nice and clean and with a minor edit we can paste it directly into the CMD Prompt which is nicer still This is because we are not using DelayedExpansion, Calling a Label, or using Temp variables so by changing the %%s to %s, we can then Paste this directly into the CMD Line which is often more convenient when doing these sorts of operations:
This Multi-line will do just fine to be pasted into CMD directly:
FOR %%A IN ("F:\images 2017+\*.jpg") DO (
FOR /F "Tokens=1-3 Delims=/ " %a IN ('echo.%~tA') DO #(
PAUSE
ECHO.%~fA
ECHO.%~tA
REN "%~fA" "%~nA_%a-%b-%c%~xA"
PAUSE
)
)
or, as a single line to paste into CMD if you prefer:
FOR %A IN ("F:\images 2017+\*.jpg") DO #( FOR /F "Tokens=1-3 Delims=/ " %a IN ('echo.%~tA') DO #( PAUSE& ECHO.%~fA& ECHO.%~tA& REN "%~fA" "%~nA_%a-%b-%c%~xA"& PAUSE ) )
no need to cd anywhere. ren takes a full path/filename for source - just the destination must be a filename only. So ... do call :renER "%%~fF" "%%~tF" is fine (no need to snip the extension and add it again later). In the subroutine reformat the time to a valid string and reassemble the destination file name:
#echo off
FOR /R "F:\images 2017+" %%F in (*.jpg) do call :renER "%%~fF" "%%~tF"
goto :eof
:renER
pause
echo %1
echo %2
set "string=%~2"
set "string=%string::=-%"
set "string=%string:/=-"
ECHO rename "%~1" "%~n1_%string%%~x1"
pause
goto :eof
:end
NOTE: I disarmed the rename command. Remove the ECHO after troubleshooting, if it works as intended.
#Stephan's answer is probably the best approach. But if you want to change directories ...
The windows shell has a working drive/volume, and on each drive/volume a current working folder. cd changes the working folder on a disk; to change the working folder on a drive (which is not the working drive) and to make that drive the working drive, you need to use cd /d, in this case cd /d "F:\images 2017+".
(A plain cd in this instance changes the working folder on F:\, but if your working folder is on C: -- as I'm guessing is the case -- it will not be changed.)
Assuming command extensions are enabled, you should also be able to use pushd and popd. pushd behaves like cd /d but also saves your previous location; popd returns you to that previous location. (And IIRC pushd will accept UNC paths.)
So at the beginning of your script, pushd "F:\images 2017+", and at the end popd.
I tend to favor pushd/popd over cd because invocations can be nested. So you can do things like
(assume working directory is C:\Users\IoCalisto):
pushd "F:\images 2017+"
(working directory is now F:\images 2017+)
pushd "Z:\images 2015-2016"
(working directory is now Z:\images 2015-2016)
popd
(working directory is now F:\images 2017+)
popd
(working directory is now C:\Users\IoCalisto)
... with this approach, your scripts will have fewer "side effects" and be more modular, or at least modularizable.
I am a complete novice when it comes to scripting, but am attempting to write a batch script which runs a command to output a png file to a printer. The script I have works fine for one file, but when there are multiple files it does not.
Can anyone point me in the right direction please?
#echo off
REM ___Change Directory to where Label Is Stored___
pushd C:\AFP\to
REM ___Create Variable to capture filename of any png file___
for /F %%a in ('dir /b *.png') do set FileName=%%~na.png
REM ___Now we have the filename as a variable, send it to printer using Zebra SSDAL___
\\172.16.100.2\nDrive\Prime_DPD_Label_Print\ssdal.exe /p "TSC DA200" send %FileName% >> C:\AFP\Log\Label_Printing_Log.txt
REM ___Copy PNG File to Backup Folder___
XCOPY /y /q /c C:\AFP\to\*.png C:\AFP\backup\
REM ___Delete PNF File from To Folder___
DEL C:\AFP\to\*.png
When the script runs, the first file prints fine. The subsequent files then do not print, I get "File does not exist" back from the ssdal.exe command. Why would the first one work but not the subsequent prints? I would have expected the for to loop through.
#ECHO Off
SETLOCAL
REM ___Change Directory to where Label Is Stored___
pushd C:\AFP\to
REM ___Process all png files___
for /F "delims=" %%a in ('dir /b *.png') do (
REM ___Now we have the filename as "%%a", send it to printer using Zebra SSDAL___
\\172.16.100.2\nDrive\Prime_DPD_Label_Print\ssdal.exe /p "TSC DA200" send "%%a" >> C:\AFP\Log\Label_Printing_Log.txt
IF ERRORLEVEL 1 (
CALL ECHO SSDAL returned ERRORLEVEL %%errorlevel%% FOR "%%a"
) ELSE (
REM ___Move PNG File to Backup Folder___
IF EXIST "c:\afp\backup\%%a" (
ECHO MOVE "%%a" to backup skipped as file already exists IN backup
) ELSE (
MOVE "%%a" C:\AFP\backup\
)
)
REM Two-second delay
TIMEOUT /t 2 >nul 2>nul
)
POPD
GOTO :EOF
Ah! using Zebra printers. Sensible lad!
This replacement script should do what you want.
The setlocal command is used to ensure that any variation made by this batch to the cmd environment is discarded when the batch ends.
The delims= sets "no delimiters" so for/f will set %%a to the entire filename, even if it contains spaces or other delimiters. Quoting %%a ensures such filenames are kept together as a single unit, not interpreted as separate tokens.
I'm assuming that ssdal acts responsibly and returns errorlevel non-zero in the case of errors. The if errorlevel 1 means if the errorlevel is currently 1 or greater than 1 and in that case, the error message is generated. We need to call echo ... %%varname%% ... in order to display the current value of the variable, if we're not using delayed expansion (many SO articles explain this)
Otherwise, if ssdal was successful, check for the existence of the filename in the backup directory, and either move it there or report that it already exists.
Of course, there are many ways in which this could be manipulated if features I've added are not desired. I'm happy to adjust this script to comply.
timeout is a standard utility to wait for a keypress. The redirection takes care of its prompting (it will provide a countdown unless gagged).
I have set up a batch file to be default to open .txt files. In an earlier question I found out that %1 gives me the path of the file which was actually calling the batch file. The Problem is: if the file name contains white space, it gets interpreted as multiple parameters.
Example:
opening file "C:\Users\Desktop\space true.txt"
%1 gives:"C:\Users\Desktop\space" and then %2 gives: "true.txt"
How could I get just the full file path with the name and white space without trying to do a loop to attempt to get the full path by combining %1%2%3%4...
UPDATE-----------------------
Sorry there was a miss communication. The code below is working. The trick was to put "%*" instead of "%1"
here the code:
#echo on
set var= "%*"
c:
cd "C:\Users\MyText Editor"
start javaw -jar "MyTextEditor.jar"%var%
pause
I do the whole changing the path, because the file which I double click and the the the batch file are in different directories. I had to change it to this.
UPDATE 2 --------------------------
The solution which worked best for me was from this fine gentlemen dbenham.
#echo off
pushd "C:\Users\MyText Editor"
start javaw -jar "MyTextEditor.jar" %*
The only complain I have is, that there is a case, where %* does not return the path with quotes. So I am searching for a final solution. Something like this "%~*" But this doesn't work.
Thanks in advance
The following is not quite correct - I thought the file associations would put quotes around the file name like drag and drop does. But I was mistaken
This line is the source of your problem:
set var= "%*"
When files are dragged onto your batch script, or if a text file is double clicked, any file name(s) containing space will automatically be enclosed within quotes.
When you add your own additional quotes, it defeats the purpose of the quotes - the space is no longer quoted.
For example, a string like "name with space.txt" is treated as a single arg, but with added quotes, ""name with space.txt"" becomes three arguments.
There is no need for your var variable. You can use %* directly in your START command.
#echo on
pushd "C:\Users\MyText Editor"
start javaw -jar "MyTextEditor.jar" %*
pause
I'm not sure the above works properly if multiple files are passed. I suspect you may want the following:
#echo on
pushd "C:\Users\MyText Editor"
for %%F in (%*) do start javaw -jar "MyTextEditor.jar" %%F
pause
There is one potential problem. Windows has a bug in that file names containing & are not automatically quoted as they should. See "Droplet" batch script - filenames containing ampersands for more info.
EDIT - The following should work
OK, I did some tests and I believe your best bet is to modify the command associated with .txt files.
I tested association changes via the command line. This must be done via an elevated command prompt with admin rights. On my machine I go to the Start menu, click on "All Programs", click on "Accessories" folder, right click "Command Prompt", and select "Run as administrator", then click "Yes" to allow the program to make changes to the system.
The following command will show which file type needs to be modified
assoc .txt
On my machine it reports .txt=txtfile, so txtfile is what must be modified using FTYPE.
I believe the following should work for you:
ftype txtfile="C:\pathToYourScrpt\yourScript.bat" "%1"
Obviously you would need to fix the path to your batch script :-)
Once you have made the change, the filename will automatically be quoted every time your script is invoked via a file association.
Your batch script can then look like the following, and it should work no matter how it is invoked (excepting drag and drop with file name containing & but no space):
#echo off
pushd "C:\Users\MyText Editor"
for %%F in (%*) do start javaw -jar "MyTextEditor.jar" %%F
It seems to me you should be able to eliminate the batch script and configure FTYPE TXTFILE to open your java editor directly. I should think something like the following:
ftype txtfile="c:\pathToJava\javaw.exe" -jar "C:\Users\MyText Editor\MyTextEditor.jar" "%1"
When calling your batch file, you must enclose your parameter in quotes if there is spaces in it.
E.g.: Batch.cmd "C:\Users\Desktop\space true.txt"
Eric
%*
Here's a list of characters.
& seperates commands on a line.
&& executes this command only if previous command's errorlevel is 0.
|| (not used above) executes this command only if previous command's errorlevel is NOT 0
> output to a file
>> append output to a file
< input from a file
| output of one command into the input of another command
^ escapes any of the above, including itself, if needed to be passed to a program
" parameters with spaces must be enclosed in quotes
+ used with copy to concatinate files. E.G. copy file1+file2 newfile
, used with copy to indicate missing parameters. This updates the files modified date. E.G. copy /b file1,,
%variablename% a inbuilt or user set environmental variable
!variablename! a user set environmental variable expanded at execution time, turned with SelLocal EnableDelayedExpansion command
%<number> (%1) the nth command line parameter passed to a batch file. %0 is the batchfile's name.
%* (%*) the entire command line.
%<a letter> or %%<a letter> (%A or %%A) the variable in a for loop. Single % sign at command prompt and double % sign in a batch file.
Your problem is really that the syntax of your set command is wrong. In a batch
file, a set command looks like this:
set "var=%1"
That will give you your variable exactly as received. If the user quoted it,
then the variable's value will have quotes around it. To remove the quotes,
you'd put a ~ in front of the number:
set "var=%~1"
Notice how the quotes go around the entire assignment, and not just around the
value you are assigning. It is not set var="%1".
If you use set var= "%*", you haven't really fixed the fundamental problem
that your syntax is wrong. Plus, often you really do want %1 and not the
entire command line.
Here is an example script to test various quoting behaviors:
#echo off
set var="%*"
echo 1. var="%%*" --^> [%var%] (wrong)
set "var=%*"
echo 2. "var=%%*" --^> [%var%]
set "var=%1"
echo 3. "var=%%1" --^> [%var%]
set "var=%~1"
echo 4. "var=%%~1" --^> [%var%]
set "var=%~2"
echo 5. "var=%%~2" --^> [%var%]
set "var=%~3"
echo 6. "var=%%~3" --^> [%var%]
And here is the output of that script. Note how arg1, arg2, and arg3 are all
quoted:
C:\batch> all_args.cmd "arg 1" "this is arg 2" "arg 3"
1. var="%*" --> [""arg 1" "this is arg 2" "arg 3""] (wrong)
2. "var=%*" --> ["arg 1" "this is arg 2" "arg 3"]
3. "var=%1" --> ["arg 1"]
4. "var=%~1" --> [arg 1]
5. "var=%~2" --> [this is arg 2]
6. "var=%~3" --> [arg 3]
You can see that numbers 4, 5, and 6 correctly pulled out their quoted arguments
and saved the value into var. You typically want to save the argument without quotes, and then quote it when you use it in your script. In other words, your script should look like this:
#echo on
set "var=%~1"
c:
cd "C:\Users\MyText Editor"
start javaw -jar "MyTextEditor.jar" "%var%"
pause
#echo on
set var= "%*"
c:
cd "C:\Users\MyText Editor"
start javaw -jar "MyTextEditor.jar"%var%
pause
Becomes removing redundant commands
start "" javaw -jar "C:\Users\MyText Editor\MyTextEditor.jar" "%*"
pause
Echo is already on unless turned off by you.
We don't put things into variables for no reason, and it's already in %*. It just makes convoluted code and removes meaning from the name of the variable.
When programming (unlike typing) we don't change paths (and cd /d C:\Users\MyText Editor does drive and folder anyway).
We specify full path on the command line. This makes your meaning quite clear.
The main problem was there was no space between .jar and %var% and start command the first quotes on the line are assumed to the CMD's window title. I would code the path to javaw and not use start. Start is asking the Windows' graphical shell to start the file, not CMD.
Here's a batch file that starts vbs files. I don't specify path to cscript as it's a Windows' command.
It's complexity is to make use fairly idiot proof and easy for others.
#echo off
Rem Make sure filter.vbs exists
set filter=
set filterpath=
Call :FindFilter filter.vbs
Rem Add filter.bat to the path if not in there, setx fails if it's already there
setx path %~dp0;%path% 1>nul 2>nul
Rem Test for some command line parameters
If not "%1"=="" goto main
echo.
echo -------------------------------------------------------------------------------
echo.
echo Filter.bat
echo ==========
echo.
echo The Filter program is a vbs file for searching, replacing, extracting, and
echo trimming console output and text files.
echo.
echo Filter.bat makes Filter.vbs easily usable from the command line. It
echo controls unicode/ansi support and debugging.
echo.
echo Type Filter Help or Filter HTMLHelp for more information.
echo.
cscript //nologo "%filter%" menu
Goto :EOF
:Main
echo %date% %time% %~n0 %* >>"%~dp0\FilterHistory.txt"
rem echo Batch file ran
rem echo %*
Rem /ud Unicode and Debug
If %1==/ud FOR /F "tokens=1*" %%i IN ("%*") DO cscript "%filter%
" //nologo //u //x %%j&Goto :EOF
Rem /u Unicode
If %1==/u FOR /F "tokens=1*" %%i IN ("%*") DO cscript "%filter%
" //nologo //u %%j&Goto :EOF
Rem /d Ansi Debug
If %1==/d FOR /F "tokens=1*" %%i IN ("%*") DO cscript "%filter%
" //nologo //x %%j&Goto :EOF
Rem -ud Unicode and Debug
If %1==-ud FOR /F "tokens=1*" %%i IN ("%*") DO cscript "%filter%
" //nologo //u //x %%j&Goto :EOF
Rem /u Unicode
If %1==-u FOR /F "tokens=1*" %%i IN ("%*") DO cscript "%filter%
" //nologo //u %%j&Goto :EOF
Rem -d Ansi Debug
If %1==-d FOR /F "tokens=1*" %%i IN ("%*") DO cscript "%filter%
" //nologo //x %%j&Goto :EOF
Rem ANSI
cscript "%filter%
" //nologo %*&Goto :EOF
Goto :EOF
:FindFilter
If Exist "%~dpn0.vbs" set filter=%~dpn0.vbs&set filterpath=%~dp0&goto :EOF
echo find filter 1
If Not "%~dpnx$PATH:1" == "" set filter=%~dpnx1&set filterpath=%~dp1&goto :EOF
echo find filter 2
If Exist "%temp%\filter.vbs" set filter=%temp%\filter.vbs&set filterpath=%temp%&goto :EOF
copy "%~dpnx0" "%~dpn0.bak"
if not errorlevel 1 (
echo creating "%~dpn0.vbs"
goto :EOF
)
copy "%~dpnx0" "%temp%\filter.bak"
echo Error %errorlevel%
if not errorlevel 1 (
echo creating "%temp%\filter.bak"
Goto :EOF
)
Goto :EOF