BATCH exist not working - windows

I've started making a small program in Batch, it worked fine until I've gotten into IF NOT EXIST, just then all my problems started as every time it got into that statement, the batch file has just crashed.
Here's the code:
REM BEGGINING OPTIONS
#ECHO OFF
TITLE Organizer
COLOR 07
MODE CON COLS=101 LINES=30
SETLOCAL enableDelayedExpansion
CLS
REM WELCOME
CLS
COLOR E
ECHO WELCOME TO ORGANIZER.BAT! THIS PROGRAM IS MADE BY ELDAR BAKERMAN TO ORGANIZE YOUR FILES AND COMPUTER!
ECHO THIS IS VERSION 1.0!
ECHO THIS PROJECT STARTED IN 11.08.2017 (DD/MM/YYYY)
ECHO PRESS ANY KEY TO CONTINUE
PAUSE>NUL
REM ORGANIZATION
:ORGANIZATION
COLOR 0B
CLS
REM CREATE FOLDERNAME VARIABLE
SET /P FOLDERNAME=WHAT IS THE NAME OF THE FOLDER WHERE THE UNORGANIZED FILES ARE LOCATED IN?
REM FIND FOLDER
IF NOT EXIST "D:\Users\Eldar\Desktop\%FOLDERNAME%\NUL"
(
COLOR 0C
ECHO ERROR! FOLDER "%FOLDERNAME%" WAS NOT FOUND!
PAUSE>NUL
) ELSE (
PAUSE
)
PAUSE

Here's your script without the bloat:
#ECHO OFF
SET/P "FOLDERNAME=WHAT IS THE NAME OF THE UNORGANIZED FILES FOLDER? "
IF NOT EXIST "D:\Users\Eldar\Desktop\%FOLDERNAME%\" (
ECHO ERROR! FOLDER "%FOLDERNAME%" WAS NOT FOUND!
) ELSE ECHO "%FOLDERNAME%" WAS FOUND
PAUSE
Hopefully you can see how the parenthesis placement works.

Related

Recursively change file extensions to lower case

I have a game that I play and mod a lot, and a lot of the files in the game have file extensions that are in all caps, which bothers me quite a bit. I'm trying to change them all to be lowercase, but there are numerous folders in the game files, so I'm having to be very repetitive. Right now, I'm working with this:
cd\program files (x86)\Activision\X-Men Legends 2\Actors
start ren *.IGB *.igb
cd\program files (x86)\Activision\X-Men Legends 2\Conversations\
start ren *.XMLB *.xmlb
cd\program files (x86)\Activision\X-Men Legends 2\Conversations\act0\tutorial\tutorial1
start ren *.XMLB *.xmlb
and so on for each and every folder in the game files. I have a very long .bat file where I just have line after line of this but with a different destination folder. Is there a way to streamline this process so I don't have to manually type out each folder name? Also, is there a line that I could add at the beginning to automatically run as an administrator, so I don't have to make sure to run the .bat file as an administrator each time?
I'm not looking for anything complicated, and I'm very inexperienced with coding other than the small amount of stuff I've been able to search up.
Instead of doing it for each folder, use a for /R loop which loops through all subfolders. I would suggest the following code:
#echo off
:prompt
set /p "extensions=What are the up-case extensions you want to convert to lower-case?: "
if not defined extensions (cls & goto:prompt) else (goto:loop)
:loop
for %%A IN (%extensions%) do (
for /R "custom_folder" %%B IN (*.%%A) do (
ren "%%~fB" "%%~nB.%%A"
)
)
Take a look on this on how to run this batch file as admin. Create another batch file and add the code specified in the accepted answer.
Note: As Stephan pointed out in the comments, you can use %ProgramFiles(x86)% environment variable which is the same thing.
#echo off
setlocal
rem Check if admin.
2>nul >nul net session || goto :runasadmin
rem Start in script directory.
pushd "%~dp0" || (
>&2 echo Failed to change directory to "%~dp0".
pause
exit /b 1
)
rem Ask for directory to change to, else use the script directory if undefined.
set "dirpath=%~dp0"
set /p "dirpath=Dir path: "
rem Expand any environmental variables used in input.
call set "dirpath=%dirpath%"
rem Start in the input directory.
pushd "%dirpath%" || (
>&2 echo Failed to change directory to "%dirpath%".
pause
exit /b 1
)
rem Ask for file extensions.
echo File extensions to convert to lowercase, input lowercase.
echo i.e. doc txt
set "fileext="
set /p "fileext=File extension(s): "
if not defined fileext (
>&2 echo Failed to input file extension.
pause
exit /b 1
)
rem Display current settings.
echo dirpath: %dirpath%
echo fileext: %fileext%
pause
rem Do recursive renaming.
for %%A in (%fileext%) do for /r %%B in (*.%%A) do ren "%%~B" "%%~nB.%%A"
rem Restore to previous working directory.
popd
echo Task done.
pause
exit /b 0
:runasadmin
rem Make temporary random directory.
set "tmpdir=%temp%\%random%"
mkdir "%tmpdir%" || (
>&2 echo Failed to create temporary directory.
exit /b 1
)
rem Make VBS file to run cmd.exe as admin.
(
echo Set UAC = CreateObject^("Shell.Application"^)
echo UAC.ShellExecute "cmd.exe", "/c ""%~f0""", "", "runas", 1
) > "%tmpdir%\getadmin.vbs"
"%tmpdir%\getadmin.vbs"
rem Remove temporary random directory.
rd /s /q "%tmpdir%"
exit /b
This script is expected to start from double-click.
It will restart the script as admin if not already admin.
It will prompt to get information such as directory to change to and get file extensions i.e. doc txt (not *.doc *.txt). If you enter i.e. %cd% as the directory input, it will be expanded.

Running Portable Exe file through batch file

I have created a batch file which runs multiple commands in the Windows command prompt, which is working just fine, however, I want to run a portable exe file through the same batch file as well. E.g. if I transfer the zip file to another computer, all I would like to do is run the batch file and that portable exe would run along with the other commands as well
:start
cls
color 1A
cls
#echo off
echo.
echo.
echo.
echo ********************************************
echo ************* Test Program **************
echo ********************************************
echo.
echo.
echo.
echo 01) System information
echo 02) Ping
echo 03) IP configuration
echo 04) Verify Drivers
echo 05) Driver List
echo 06) Get Serial Number
echo 07) Disk Defragmentation
echo 08) DiskPart
echo 09) Repair Load Preferences
echo 10) Run CCleaner
echo.
REM This is a test program
REM echo This is a Test Program
set /pnum= Type the corresponding number to perform an operation:
if %num%==01 (
cls
systeminfo
)
if %num%==02 (
cls
ping www.google.com
)
if %num%==03 (
cls
ipconfig /all
)
if %num%==04 (
cls
verifier
)
if %num%==05 (
cls
driverquery
)
if %num%==06 (
cls
wmic bios get serialnumber
)
if %num%==07 (
defrag c: /a
pause
cls
)
if %num%==08 (
diskpart
pause
cls
)
if %num%==09 (
cls
lodctr /r /f
echo.
pause
)
if %num%==10 (
cls
C:\Users\kumar\Desktop\CCleaner.exe
echo.
pause)
set /p choice="Do you want to restart? Press 'Y' to continue, or any other key to exit: "
if '%choice%'=='y' goto start
So for example in the last condition I am running CCleaner which is on the Desktop at the moment, but if i copy a zip file which consists of the BAT File and the CCleaner.exe how would i enable it to run on another PC after copying?
Any help would be appreciated.
If the "portable" directory will contain all executable files, another way is to make the location of the .bat script the current working directory.
#ECHO OFF
PUSHD "%~dp0"
: do things, the directory of the .bat script is the current directory
POPD
EXIT /B 0
place your tools into the same folder as the batchfile and instead of
C:\Users\kumar\Desktop\CCleaner.exe
do
%~dp0\CCleaner.exe
%~dp0 is Drive and Path of your batchfile.
You may also put your tools into a subdir (tools) and:
%~dp0\tools\CCleaner.exe
This could be useful in the case your app uses some system variables (e.g. PATH)
and you might want to reassign them locally before starting the application. The provided .exe will pass control to a .bat where you can do this and much more.
At the end of this .bat run the App.exe

Batch Hex to Asciic makes the string useless?

I belive i found a nice way to send out a command line to multiple batch windows at once, here is how i see it going:
Using Set with /p allows me to user input a string that i save as message
Exporting it to its own bat file with "Echo set command=%message% >command.bat
Using echo to type out ftp information and then run it with "Ftp -s:upload.txt ftp.example.com
This uploads it to my webhotel where im gonna use a bitadmin.exe to download the file
Then running command.bat and ensuring that if the string %command% isnt the same before it runs the command
It's all working fine and what not, but i feel like my ftp name/password is too exposed to anyone that has the IQ to "Right-Click, Edit" and inspect the code. I've come to the point where i'm trying to make it harder to really get it just by looking at the batch file.
So far i converted my password into HEX and using a fancy batch file convert it back into a string from a batch file i call, and then export it with the ftp connection file. It works all up untill the batch reads the ftp connection file and gets stuck on "requiring password" even though when i check my ftp connection file then the password is correctly typed in the right place, no additional spaces or odd stuff. But it wont work untill i deleted the line and typed it in my self. (The other way that i was considering using a Batch to exe program but that just runs the batch file in the temp folder, everyone knows that) The hex password i use here is just "password"
Code so far:
#Echo Off
:Start
Rem (1)Set/(2)Export Message
Rem (1)
Set /p message=
Rem (2)
Echo set run=%message% >command.bat
Rem (1)Decode Hex/(2)Running hex output/(3)Acces FTP service
Rem (1)
Start HEX.bat 70617373776f7264
Rem (2)
Call CODE.bat
Del /Q CODE.bat
Rem (3)
Echo darkrock> upload.txt
Echo %code%>> upload.txt
Echo asc>>upload.txt
Echo put command.bat>> upload.txt
Echo quit >> upload.txt
Ftp -s:upload.txt ftp.example.com
Goto :Start
The hex converter comes here:
#echo off
setlocal DisableDelayedExpansion
set Caret=^^
set ControlChar={SOH} {STX} {ETX} {EOT} {ENQ} {ACK} {BEL} {BS} {HT} {LF} {VT} {FF} {CR} {SO} {SI} {DLE} {XON}
set ControlChar=%ControlChar% {DC2} {XOFF} {DC4} {NAK} {SYN} {ETB} {CAN} {EM} {SUB} {ESC} {FS} {GS} {RS} {US}
set AsciiChar= !"#$%%&'()*+,-./0123456789:;<=>?
setlocal EnableDelayedExpansion
set AsciiChar=!AsciiChar!#ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]!Caret!_`abcdefghijklmnopqrstuvwxyz{^|}~
set AsciiChar=!AsciiChar!€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿
set AsciiChar=!AsciiChar!ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ
set HexCode=%1
call :Conversion
echo Hex: %1
echo Dec: %DecimalCode%
echo Ascii: !AsciiCode!
echo Bin: %BinaryCode%
cls
goto :EOF
:Conversion
set DecimalCode=
set AsciiCode=
set BinaryCode=
:ConvertHex
set /A Decimal=0x%HexCode:~0,2%, DecChar=Decimal-32
set DecimalCode=%DecimalCode%%Decimal%,
if %Decimal% lss 32 (
if %Decimal% equ 0 (
set AsciiCode=!AsciiCode!{NUL}
) else (
for /F "tokens=%Decimal%" %%c in ("%ControlChar%") do set AsciiCode=!AsciiCode!%%c
)
) else (
set AsciiCode=!AsciiCode!!AsciiChar:~%DecChar%,1!
)
call :DecToBin
set BinaryCode=%BinaryCode%%Binary%,
set HexCode=%HexCode:~2%
if defined HexCode goto ConvertHex
exit /B
:DecToBin
set Binary=
for /L %%i in (1,1,8) do (
set /A "Bit=Decimal&1, Decimal>>=1"
set Binary=!Bit!!Binary!
)
echo set code=%AsciiCode% >Code.bat
exit /B
Thx in advance! :) It might be me that missed something in the code but i belive i tried by best the last two days compared to being busy with collage.

Batch script prompt needs multiple entries

So I have this subroutine that I want to call from another location in a batch file. The functions work as desired, but for some reason I cant pin down, the prompt wants to have the user enter something TWICE, before it will accept anything.
Say, if I enter "0", to go back to a previous menu, it takes me right back to the prompt, and I have to enter "0" again before it will actually go back to the previous menu (elsewhere in my main script).
I can, say, enter "w" (or any other value), then the second time, enter the one I actually WANT to use, and it will finally do it.
This is driving me nuts.
:subfullbackup
cls
if exist "%current%\Backup\Full_Backup" (
Echo Backup folder already exists
Echo.
Echo [o] Overwrite local device files with existing local files
Echo [w] Wipe current local backup and start fresh
Echo.
set /p choice=Select:
if %choice% == o (
Echo.
Echo Depending on how much data you have,
Echo this could take a couple hours.
Echo.
Echo Backing up...
adb pull /sdcard/ "%current%\Backup\Full_Backup" >nul 2>&1
Echo.
Echo -= BACKUP COMPLETE =-
Pause
Goto :backup
)
if %choice% == w (
Echo.
Echo Removing all current local backup files in 'Full_Backup'
rmdir /S /Q "%current%\Backup\Full_Backup" >nul 2>&1
Echo.
Echo Depending on how much data you have,
Echo this could take a couple hours.
Echo.
Echo Backing up...
adb pull /sdcard/ "%current%\Backup\Full_Backup" >nul 2>&1
Echo.
Echo -= BACKUP COMPLETE =-
Pause
Goto :backup
)
if not %choice% == o goto subfullbackup
if not %choice% == w goto subfullbackup
) else (
Echo.
Echo Depending on how much data you have,
Echo this could take a couple hours.
Echo.
Echo Backing up...
adb pull /sdcard/ "%current%\Backup\Full_Backup" >nul 2>&1
Echo.
Echo -= BACKUP COMPLETE =-
Pause
Goto :backup
)
Goto :eof
Your batch code with using delayed expansion, enabled at top of the batch script with command setlocal which additionally creates a copy of all environment variables and remembering also current directory for restoring the variables list, current directory and current states of command extensions and delayed expansion on endlocal or leaving batch processing:
#echo off
setlocal EnableDelayedExpansion
set "current=%CD%"
:FullBackup
cls
if exist "%current%\Backup\Full_Backup" (
Echo Backup folder already exists
Echo.
Echo [o] Overwrite local device files with existing local files
Echo [w] Wipe current local backup and start fresh
Echo.
set "UserChoice="
set /p "UserChoice=Select: "
if /I "!UserChoice!" == "o" (
Echo.
Echo Depending on how much data you have,
Echo this could take a couple hours.
Echo.
Echo Backing up...
adb.exe pull /sdcard/ "%current%\Backup\Full_Backup" >nul 2>&1
Echo.
Echo -= BACKUP COMPLETE =-
Pause
Goto DoBackup
)
if /I "!UserChoice!" == "w" (
Echo.
Echo Removing all current local backup files in 'Full_Backup'
rmdir /S /Q "%current%\Backup\Full_Backup" >nul 2>&1
Echo.
Echo Depending on how much data you have,
Echo this could take a couple hours.
Echo.
Echo Backing up...
adb.exe pull /sdcard/ "%current%\Backup\Full_Backup" >nul 2>&1
Echo.
Echo -= BACKUP COMPLETE =-
Pause
Goto DoBackup
)
goto FullBackup
) else (
Echo.
Echo Depending on how much data you have,
Echo this could take a couple hours.
Echo.
Echo Backing up...
adb.exe pull /sdcard/ "%current%\Backup\Full_Backup" >nul 2>&1
Echo.
Echo -= BACKUP COMPLETE =-
Pause
Goto DoBackup
)
Goto :EOF
:DoBackup
But your batch code could be also written without delayed expansion and much more compact avoiding duplicate code lines:
#echo off
set "current=%CD%"
:FullBackup
cls
if exist "%current%\Backup\Full_Backup" goto PromptBackup
:OverwriteBackup
Echo.
Echo Depending on how much data you have,
Echo this could take a couple hours.
Echo.
Echo Backing up...
adb.exe pull /sdcard/ "%current%\Backup\Full_Backup" >nul 2>&1
Echo.
Echo -= BACKUP COMPLETE =-
Pause
Goto DoBackup
:PromptBackup
Echo Backup folder already exists
Echo.
Echo [o] Overwrite local device files with existing local files
Echo [w] Wipe current local backup and start fresh
Echo.
set "UserChoice="
set /p "UserChoice=Select: "
if /I "%UserChoice%" == "o" goto OverwriteBackup
if /I not "%UserChoice%" == "w" goto FullBackup
Echo.
Echo Removing all current local backup files in 'Full_Backup'
rmdir /S /Q "%current%\Backup\Full_Backup" >nul 2>&1
goto OverwriteBackup
:DoBackup
Some notes about small changes in code:
choice (SS64 article) is a standard Windows command. Therefore it is advisable to avoid choice (Microsoft article) as name for an environment variable or label. UserChoice (CamelCase spelling for easier reading) is used instead of choice.
backup (SS64 article) is not a standard Windows command, but a standard SQL command. Therefore it is also advisable to avoid backup as name for an environment variable or label. DoBackup is used instead in batch code above.
It is advisable to define a default for an environment variable before prompting a user. The user can hit just RETURN or ENTER in which case the environment variable keeps its value.
The environment variable is cleared with set "UserPoint=" before prompting the user and therefore the variable does not exist when user enters nothing.
Possible would be also set "UserPoint=o" or set "UserPoint=w" to define a valid default value.
Comparing strings with user input should be done always with using double quotes to avoid an exit of batch processing caused by a syntax error when user inputs nothing.
if %choice% == w ( becomes if == w ( when the user enters nothing which is a syntax error and results in breaking batch processing by command processor.
if /I "%UserChoice%" == "w" ( becomes if /I "" == "w" when the user enters nothing in code above which is still valid batch code and can be therefore processed.
Note: User could now break batch processing by entering "w".
But it can be expected here that the user does not input 1 or more double quotes on being asked for o or w.
On comparing strings entered by user with predefined strings it is advisable to do case-insensitive string comparisons if letters are included in the compared strings.
The option /I changes a string comparison from case-sensitive to case-insensitive.
So now the user can enter also O or W and this is interpreted like o or w.

How to get attributes of a file using batch file

I am trying to make a batch file to delete malicious files from pendrive. I know that these malicious files uses hidden,read only and system attributes mainly to hide itself from users. Currently i am deleting these files using cmd by removing malicious files attributes then deleting it. Now I am thinking to make a small batch file which can be used to remove these files just by entering the drive letter.
I have found this code in a website to find attributes of a file. But after entering the name of the file the batch file just exits without showing any results.
#echo off
setlocal enabledelayedexpansion
color 0a
title Find Attributes in Files
:start
set /p atname=Name of the file:
if not exist %atname% (
cls
echo No file of that name exists!
echo.
echo Press any key to go back
pause>nul
goto start
)
for /f %%i in (%atname%) do set attribs=%%~ai
set attrib1=!attribs:~0,1!
set attrib2=!attribs:~1,1!
set attrib3=!attribs:~2,1!
set attrib4=!attribs:~3,1!
set attrib5=!attribs:~4,1!
set attrib6=!attribs:~5,1!
set attrib7=!attribs:~6,1!
set attrib8=!attribs:~7,1!
set attrib9=!attribs:~8,1!
cls
if %attrib1% equ d echo Directory
if %attrib2% equ r echo Read Only
if %attrib3% equ a echo Archived
if %attrib4% equ h echo Hidden
if %attrib5% equ s echo System File
if %attrib6% equ c echo Compressed File
if %attrib7% equ o echo Offline File
if %attrib8% equ t echo Temporary File
if %attrib9% equ l echo Reparse point
echo.
echo.
echo Press any key to go back
pause>nul
goto start
can you tell me why this batch file is exiting without showing any results. Or can you give any better batch script for getting attributes of a file.
EDIT
I was able to work the above code only for a single file. As my purpose of my batch file is to remove malicious files by entering the drive letter. How can i use it to find what kind of attributes files are using in a particular drive.
For example:
In cmd we can use this command to find the file attributes of a given drive
attrib *.*
Advance thanks for your help
I tried the bat file (without inspecting the details) and it seems to work fine for me. What I noticed is that it closes instantly if you don't enclose file path with quotation marks - e.g. "file". Example:
Name of the file: path\file.txt // this will close immediately
Name of the file: "path\file.txt" // now it will stay open and display the result
This hopefully solves your problem.
As far as your question in EDIT is concerned, a simple option is to iterate a list of files and execute the batch on each one.
batch1.bat: (%1 refers to the first command-line parameter)
#echo off
setlocal enabledelayedexpansion
echo %1
set atname=%1
for %%i in ("%atname%") do set attribs=%%~ai
set attrib1=!attribs:~0,1!
set attrib2=!attribs:~1,1!
set attrib3=!attribs:~2,1!
set attrib4=!attribs:~3,1!
set attrib5=!attribs:~4,1!
set attrib6=!attribs:~5,1!
set attrib7=!attribs:~6,1!
set attrib8=!attribs:~7,1!
set attrib9=!attribs:~8,1!
cls
if %attrib1% equ d echo Directory
if %attrib2% equ r echo Read Only
if %attrib3% equ a echo Archived
if %attrib4% equ h echo Hidden
if %attrib5% equ s echo System File
if %attrib6% equ c echo Compressed File
if %attrib7% equ o echo Offline File
if %attrib8% equ t echo Temporary File
if %attrib9% equ l echo Reparse point
echo.
echo.
Next, generate a list of all files within a given path (say 'folder' including all subfolders):
dir /s /b folder > ListOfFiles.txt
main.bat (read ListOfFiles.txt line-by-line and pass each line to batch1.bat as a command line parameter):
#echo off
for /f "tokens=*" %%l in (ListOfFiles.txt) do (batch1.bat %%l)
Then, from cmd:
main.bat >> output.txt
The last step generates an output file with complete results. Granted, this can be done in a more polished (and probably shorter) way, but that's one obvious direction you could take.
You're using a for /f loop here, which isn't necessary (and may yield undesired results if the filename contains spaces). Change this:
for /f %%i in (%atname%) do set attribs=%%~ai
into this:
for %%i in ("%atname%") do set attribs=%%~ai
This is dangerous code - but it'll delete read only, hidden and system files.
It should fail to run on c: drive but I haven't tested it. Note that some Windows installs are on drives other than c:
#echo off
echo "%cd%"|find /i "c:\" >nul || (
del *.??? /ar /s /f
del *.??? /ah /s
del *.??? /as /s
)

Resources