I'm using a second batch file in my main one to save/load variables, like this:
if not exist "KeemyDataPersistence.bat" (
echo #ECHO OFF > KeemyDataPersistence.bat
echo SET GENDER=F >> KeemyDataPersistence.bat
echo SET BGCOLOR=0 >> KeemyDataPersistence.bat
echo SET FGCOLOR=2 >> KeemyDataPersistence.bat
)
call KeemyDataPersistence.bat
It's working fine, but I'd like to save that second file (KeemyDataPersistence.bat) with another extension (.keemy), so KeemyDataPersistence.keemy. It saves fine just by replacing .bat by .keemy in the whole code, but when using call KeemyDataPersistence.keemy, it runs the windows default window to choose the program the user wants to open it with.
How would I be able to make it call the file as a batch file?
Try first to run this script once with admin permissions (and .bat extension):
#echo off
rem :: A files with .keemy extension will be able to execute batch code but is not perfect as the %0 argument is lost
rem :: "installing" a caller.
if not exist "c:\caller.bat" (
echo #echo off
echo copy "%%~nx1" "%%temp%%\%%~nx1.bat" /Y ^>nul
echo "%%temp%%\%%~nx1.bat" %%*
) > c:\caller.bat
rem :: associating file extension
assoc .keemy=batps
ftype batps=c:\caller "%%1" %*
Related
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.
i'm looking for a .bat file that, on opening, ask the user what folder he want to select, then, the batch copy a file (python script) in this folder and execute it
for now i use :
xcopy c:/pythonfiletocopy d:/destinationpath
but i dont find a way to make the user choose the destination folder
any idea ?
thank you
You can request user input using the Set command together with its /P option.
Here's an example which should accept typed or pasted input and should also accept drag and drop for directories not containing spaces:
#Echo Off
Set "_in=" & Set /P "_in=Please provide a directory for the file: "
If Defined _in If Exist "%_in%\" Echo XCopy "C:\pythonfiletocopy" "%_in%"
Pause
I have added an Echo on line 3, if you're happy with the output you can remove that.
I know you said you didn't need one but you could JScript launch a GUI directory browser for input.
Here's an example which may do that:
0</* :
#Echo Off
For /F "Delims=" %%A In ('CScript //E:JScript //NoLogo "%~f0" 2^>Nul'
) Do Echo XCopy "C:\pythonfiletocopy" "%%A"
Pause
Exit /B */0;
var Folder=new ActiveXObject('Shell.Application').BrowseForFolder(0,'',1,'::{20D04FE0-3AEA-1069-A2D8-08002B30309D}');
try{new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1).Write(Folder.Self.Path)};catch(e){};close();
I have added an Echo on line 4, if you're happy with the output you can remove it and line 5.
When attempting to run the following commands via the cmd prompt on a windows 2008 server everything works successfully. However once those same commands are saved to a .bat or .cmd file the script no longer works.
#echo off
set FILE="\\servername\c$\users\users\desktop\test.txt"
FOR %I in (%FILE%) DO set SIZE=%~ZI
IF %SIZE% == 75 (
copy "\\servername\c$\users\users\desktop\test.txt" "\\servername\c$\users\users\desktop\test-1.txt"
del "\\servername\c$\users\users\desktop\test.txt"
) ELSE (
echo "Failure"
)
TIMEOUT /T -1
I'm not sure what the difference would be and would appreciate any help that can be provided. The text file I'm using has the following text in it.
"
hello goodmorning
I need this to have a file size.
this file size is 75
"
Inside batch scripts, variables for for loops need two % symbols.
FOR %%I in (%FILE%) DO set SIZE=%%~ZI
I have a code that calls specific files [.cmd files to be exact] using the call function, then echos a certain variable. This is highly inefficient due to the fact that the program needs to manually call each file. The current code, in case you need it is:
call afile.cmd
echo %Title%
call bfile.cmd
echo %Title%
pause > nul
[this is only the call part] Is there anyway to make it so it automatically calls all files with a .cmd extension, and displays all the %Title% variables without multiple
echo %Title%
functions?
I've tried using:
call *.cmd
call *.*
call *
just to see if those would work [since the * usually defines all files] but they didn't. Any suggestions for me?
setlocal enabledelayedexpansion
#echo off
For %%a in (*.cmd) do (
call "%%a"
echo !title!
)
pause
Windows .Bat file behave differently when executed from command window and by double clicking on the bat file. This is my file:
ECHO ON
del activity_ftp.log
cd D:\My_Test
IF EXIST united_ops*.csv (
for %%i in (united_ops*.csv) do (
set size=0
set /A size=%%~zi
echo %%i,%size%,397312,624640 > D:\My_Test\activity_ftp.log
)
)
When I run this by opening command window and calling it,
There are some issues in your code.
cd d:\My_test will only work if you are on D:, you could use cd /d or pushd here.
echo ...%size% doesn't work, as it's expands when the for block is parsed not when it's executed.
The if exist seems to be redundant, as the for %%i in ( united_ops*.csv) only expands if any file exists.
ECHO ON
setlocal EnableDelayedExpansion
del activity_ftp.log
pushd D:\My_Test
for %%i in (united_ops*.csv) do (
set size=0
set /A size=%%~zi
echo %%i,!size!,397312,624640 > D:\My_Test\activity_ftp.log
)
Building on jeb's answer.
1) Your FOR loop may iterate through many files that match your pattern. But you use the overwrite mode of file redirection. Each found file will over-write the output for the prior file. Your final output file will never have more than one line. You could change to the append mode using >>, but there is a better way. It is faster to enclose the entire loop in parentheses and redirect once in overwrite mode using >.
2) You are setting size to 0, then setting it to the file size, and then you don't use it after the line is echoed. I suspect you don't need the variable at all, so you don't need delayed expansion.
3) The file you delete at the top does not include the path information, so it may not be deleting from the correct folder. Even if it were, it is unnecessary since you are redirecting in overwrite mode anyway.
4) Instead of changing the current directory you could include the path in the FOR statement.
ECHO ON
>"D:\My_Test\activity_ftp.log" (
for %%i in ("d:\My_Test\united_ops*.csv") do (
echo %%~nxi,%%~zi,397312,624640
)
)