Runtime.getRuntime().exec how to run goto commands - java

I'm trying to run small command-line code in java application to delete itself. So the command would keep running and keeps trying to delete the file, and once the application is closed it would be deleted.
I've tired passing the command into Runtime.getRuntime().exec but still unable to have it work.
eg:
SET file="program.jar"
goto :d
:r
timeout /t 1
:d
del %file%
if exist %file% goto :r
Tried doing this which obviously looks wrong. I've tired using ; instead of && but doesn't work either.
Runtime.getRuntime().exec("cmd /c \"SET file=\"program.jar\" && goto :d && :r && timeout /t 1 && :d && del %file% && if exist %file% goto :r\"");
Works perfectly well in a .bat file but how do i implement it into java .exec() method.
I could just run the .bat file but I would want all the code be contained inside java.

First, you can't use labels an gotos in a cmd one-liner. Use some kind of while TRUE loop instead. In cmd terms: for /L %a in (1 0 2) do ...
Second, you need to apply Delayed Expansion. Proof:
==> SET "_file=init.ext"
==> SET "_file=prog.jar" & for /L %a in (1 1 2) do #echo %_file% %time% & timeout /T 3 1>NUL
init.ext 8:05:55,33
init.ext 8:05:55,33
==> set _file
_file=prog.jar
In above example, %_file% and %time% variables are expanded in parse time.On the other side, with delayed expansion enabled: !_file! and !time! variables are expanded in execution time:
==> SET "_file=init.ext"
==> cmd /E /V /C SET "_file=prog.jar" ^& for /L %a in (1 1 2) do #echo !_file! !time! ^& timeout /T 3 1^>NUL
prog.jar 8:08:55,42
prog.jar 8:08:58,18
Hence, your one-liner could look as follows (verified from Windows cmd CLI for a locked file; loops until unlocked):
cmd /E /V /C SET "_file=program.jar" ^& for /L %a in (1 0 2) do if exist "!_file!" (del "!_file!" ^& timeout /T 2) else (exit /B)

Related

batch goto :eof not working when called from java

I have a batch file roughly with the following code:
#echo off
(
set /p x=
set /p y=
) < settings.cdb
IF DEFINED x (
IF DEFINED y (
ECHO true
GoTo :EOF
)
)
ECHO false
GoTo :EOF
In Java, I have the following code to call the batch file via command line:
ProcessBuilder probuilder = new ProcessBuilder(command);
Process pr = probuilder.start();
BufferedReader input = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line;
while ((line = input.readLine()) != null)
{
lines.add(line);
}
X and Y are some input parameters from a configuration file, which may, or may not, contain any data.
When x or y are not defined everything works as suppose, outputs false.
The problem comes when the variables are both defined.
When the batch file gets called via command line I get the resulting output: true. Which is the intend output.
When I call the same batch file via Java Process I get the following output:false. Which is not what I want.
Removing the #echo off I get the following output from running the batch file from command line:
IF DEFINED x (IF DEFINED y (
ECHO true
GoTo :EOF
) )
true
But when I run it from Java Process:
IF DEFINED x (IF DEFINED y (
ECHO true
GoTo :EOF
) )
ECHO false
false
GoTo :EOF
It is not even outputting the echo true.
I've tried with EXIT /b 0 instead of GoTo :EOF but with the same result.
So what am I missing here? Why the program, when called from Java, keeps going even though it has a GoTo :EOF?
Why the different outputs? Is it a Java thing? Is it a batch thing?
UPDATE:
After all the file from where variable were being loaded is relative to the command line location instead of the bat location.
Well, you said it: "It is not even outputting the echo true". When you add debug lines, it.. helps to think for a second about what it means. 'x' is not defined, or 'y' is not defined (or most likely both are not defined).
You can manage the environment of the spawned process, use ProcessBuilder, and before launching (with e.g. start()), first set up the environment; for example with pb.environment.put("x", "hello");.
Why are you running batch scripts from java, though? They were bad technology back in the 80s, and there are a ton of alternatives available at this point. If you explain what you're trying to accomplish by farming work out to a batch file, perhaps an enterprising SO reader can make some useful suggestions.

Not printing anything after for loop in a batch script

Below is my batch script which is not executing the line after for loop end. It's not print echo end or the line after that. The line asciidoctor-pdf C:\Users\abc\Conversion_to_PDF\OutputFiles\*.adoc is causing it. But I am not sure with what the problem is.
#echo off
echo # Starting job
java -jar C:\Users\abc\Conversion_to_PDF\swagger2markup-cli-1.3.1.jar convert -i C:\Users\abc\Conversion_to_PDF\HIP-ProviderManagement-1.0.0-swagger.json -d C:\Users\abc\Conversion_to_PDF\OutputFiles
chdir /d C:\Users\abc\Conversion_to_PDF\OutputFiles
for %%A in (*.adoc) do (
asciidoctor-pdf C:\Users\abc\Conversion_to_PDF\OutputFiles\*.adoc
echo %%A
)
echo # end
C:\Users\abc\Downloads\sejda-console-3.2.3\bin\sejda-console merge -f C:\Users\abc\Conversion_to_PDF\OutputFiles\*.pdf -o C:\Users\abc\Conversion_to_PDF\OutputFiles\merged.pdf
You need
call asciidoctor-pdf ....
since asciidoctor-pdf is a batch file. The call means "execute this, then return to the next statement". Without the call, it means "go to this batchfile" and it is not told to return to the original (the "caller")

Running multiple cmd.exe processes from a batch file in Java

I'm currently revising a small application that I wrote as a demonstration for a security course I'm taking. The prof loved it and has requested some modifications that I'm unable to figure out. I would like to add the ability to pass in as a parameter to the batch file a few variables from my code (i.e. the number of cmd.exe instances to run and in the code below, the message variable).
Using an answer found at Launching multiple shell prompts from a single batch file among other helpful SO threads, here's an example of the code I've put together:
The batch file:
#echo off
if not "%1" == "" goto :%1
SET message="The random number is: "
SET /a rand=%RANDOM%
start "Job 1" "%~dpfx0" job1
start "Job 2" "%~dpfx0" job2
start "Job 3" "%~dpfx0" job3
goto :eof
:job1
call :showMessage %message% %rand%
:job2
call :showMessage %message% %rand%
:job3
call :showMessage %message% %rand%
:showMessage
echo %~1 %~2
This works great to spawn 3 instances of cmd.exe. I'm stumped, though, as to how I can dynamically choose the number of jobs to run and how to pass in a variable to the batch file with the above configuration. I figure I need a FOR loop, but I'm uncertain how to do it either with the above setup or a new way entirely.
I'm 110% sure the line from the batch file "if not "%1" == "" goto :%1" is absolutely necessary as without it, the system will continuously open cmd.exe processes (experimentation resulted in several hard resets). It interferes with passing in parameters to the batch file, but I am not able to find a way around using it.
For reference:
The batch file is executed in Java via the following code:
public class CmdProcess{
Runtime rt;
public cmdProcess() {
rt = Runtime.getRuntime();
}
public void startSpawning() {
try {
rt.exec("cmd.exe /C example.bat");
} catch (Exception e) {
e.printStackTrace();
}
}
}
I call this class from the gui code with the following listener:
private void setupListeners() {
class spawnButtonListener implements ActionListener {
public void actionPerformed(ActionEvent ae) {
// Fire off 3 cmd.exe processes that show a message
CmdProcess proc = new CmdProcess ();
proc.startSpawning();
// Increment the local counter and display on the client
processCounter += 3;
processCounterTextField.setText(Integer.toString(processCounter));
}
}
tl;dr: I need to know if it's possible with DOS magic in a batch file executed with Java to pass in the parameters necessary to run any number of cmd.exe instances that will each perform the same command.
EDIT TO INCLUDE SOLUTION:
Based on input from #JosefZ, here is a solution that works the way I need it to:
#echo off
if not %1 == "" (
set /A noiter=%1
) Else (
set /A noiter=1
)
SET message="The random number is: "
SET /a rand=%RANDOM%
if %noiter% == 0 (
call :showMessage %message% %rand%
) Else (
For /L %%G IN (1, 1, %noiter%) do (
start "Job %%G" "%~dpfx0" job%%G
set /a rand=%RANDOM%
:job%%G
call :showMessage %message% %rand%
)
)
)
:showMessage
echo %~1 %~2
If I wanted to pass in additional parameters, I would handle them in the first if block...
#echo off
if not %1 == "" (
rem passed in parameters
set /A noiter=%1
set /A message=%2
set /A rand=%3
) Else (
rem default parameters
set /A noiter=1
set message="The random number is: "
set /a rand=%RANDOM%
)
You know we can call a script with a parameter. Let's check this parameter as follows: if it's a numeric value, consider this is instances count of cmd.exe to be launched and remember it to a numeric environment variable: set /A "noiter=%1"; otherwise it's simply a flag to end. Here's the code:
if not "%1" == "" (
set /A "noiter=%1"
) Else (
set /A "noiter=1"
)
Sample an effect of set /A "noiter=text" yoursef. Now we can test value of the noiter variable:
if "%noiter%" == "0" (
call :showMessage %message% %rand%
) Else (
rem loop here
)
Finally, substitute next code snippet in place of above's rem loop here:
rem loop from 1 stepping 1 to "noiter"
For /L %%G IN (1, 1, %noiter%) do (
rem for testing purposes only: echo our command line first
echo start "Job %%G" "%~dpnx0" job%%G
rem for testing purposes only: simulate real call
set /a "rand=%RANDOM%"
call :showMessage %message% %rand%
)
This is a raw blueprint only; there are still some issues: e.g. %random% tends to stay constant :-)
So, learn more on set command, setlocal, enabledelayedexpansion etc. etc.

Windows batch file to run jar file multiple times

Id like to make a batch file that runs a jar X amount of times from user input. I have looked for how to handle user input, but I am not totally sure.
In this loop I'd like to increase the parameters I am sending to the jar.
As of now, I do not know
manipulate the variables in the for loop, numParam, strParam
So, when i run this little bat file from the command line, I get am able to do user input, but once it gets to the for loop, it spits out "The syntax of the command is incorrect
So far I have the following
#echo off
echo Welcome, this will run Lab1.jar
echo Please enter how many times to run the program
:: Set the amount of times to run from user input
set /P numToRun = prompt
set numParam = 10000
set strParam = 10000
:: Start looping here while increasing the jar pars
:: Loop from 0 to numToRun
for /L %%i in (1 1 %numToRun%) do (
java -jar Lab1.jar %numParam% %strParam%
)
pause
#echo on
Any suggestion would be helpful
Edit:
With the recent change, it doesnt seem to run my jar file. or at least doesnt seem to run my test echo program. It seems that my user input variable is not being set to what I have inputted, it stays at 0
If you read the documentation (type help for or for /? from the command line) then you will see the correct syntax for executing a FOR loop a fixed number of times.
for /L %%i in (1 1 %numToRun%) do java -jar Lab1.jar %numParam% %strParam%
If you want to use multiple lines, then you must either use line continuation
for /L %%i in (1 1 %numToRun%) do ^
java -jar Lab1.jar %numParam% %strParam%
or parentheses
for /L %%i in (1 1 %numToRun%) do (
java -jar Lab1.jar %numParam% %strParam%
REM parentheses are more convenient for multiple commands within the loop
)
What happened was for my last issues was something with how the variables expanded. This was actually answer at dreamincode.net: Here
Final code:
#echo off
echo Welcome, this will run Lab1.jar
:: Set the amount of times to run from user input
set /P numToRun= Please enter how many times to run the program:
set /a numParam = 1000
set /a strParam = 1000
setlocal enabledelayedexpansion enableextensions
:: Start looping here while increasing the jar pars
:: Loop from 0 to numToRun
for /L %%i in (1 1 %numToRun%) do (
set /a numParam = !numParam! * 2
set /a strParam = !strParam! * 2
java -jar Lab1.jar !numParam! !strParam!
:: The two lines below are used for testing
echo %numParam% !numParam!
echo %strParam% !strParam!
)
#echo on

Filling in the blanks in a command with a file using user input in shell?

I've hit a road block while building this shell program which includes some javascript jar files. I've already got the menu set up and a pause to get the user entry, i.e.
echo "Enter a number between 0-9"
read answer
case $answer in
0) { echo Starting...; java -jar SYSTEM.EAD/apktool.jar ; } ;;
1) { echo Starting...; java -jar SYSTEM.EAD/apktool.jar ; java -jar SYSTEM.EAD/signapk.jar SYSTEM.EAD/testkey.x509.pem SYSTEM.EAD/testkey.pk8 [file] ; } ;;
esac
Obviously it goes though 9 but its the example I want. In 1), right after "testkey.pk8", there is the space to input a file. I want to make a functional pause in the script after the user inputs "1" from the initial echo so the user can enter the path to the file and then after pressing enter the script continues. I've seen it been done, I hope you guys have some suggestions. Thanks!
Use read -p "Enter file path: " fpath in your '1' case and use "$fpath" in place of <file>
1) { echo Starting...; read -p "Enter file path: " fpath; java -jar ... "$fpath" ; } ;;

Categories

Resources