0

I want to automate a batch file. Which takes two arguments run-time one after another.

Following are the manual steps i do to execute this batch file--

1-Execute a ext.bat file from command line.

2- Asks for a path-

Please enter the path for code

3-Manual entry-- c:/

4- Press enter key.

5- Asks for folder name.

Please enter the directory name

6-Manual entry-- mydir

7-Press enter key.

Is there any way similar expect(works only with .sh script).

Adding following more details ---

This Batch file internally calls a standalone java class -- Following is the batch file

@echo off
setlocal
set classpath=C:\Users\abc\Documents\jar\instance.jar;%classpath%
"%JAVA_HOME%"\bin\java nstance.ABCUtil

That asks two questions one by one. following is the calling part in the class.

This ABCUtil class

final Console console = System.console();
// Read Instance absolute directory from the console
final String DirHome = console.readLine(abc.HOME_ABSOLUTE_path);
final String Dir = console.readLine(abc.HOME_ABSOLUTE_DIR_name);

so it will take value only from console ... I can not call like this. this wont work.

java ABCUtil path dir

Note - I can not install any additional tools to do this like TCL ,cygwin ETC. My M/C has os- windows 7 64 bit

Please help-- Dear Masters....

smriti
  • 1,124
  • 5
  • 14
  • 35
  • What is the real problem you are trying to solve? http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem. If the batch files runs java program, you could invoke it using process builder or directly from a java program. Also if this some thing related to remote execution/job orchestration tools like Jenkins may be much better. – Jayan Jun 12 '14 at 04:17
  • Added addition info..Please help – smriti Jun 12 '14 at 06:21
  • I first answere with a batch solution, than I saw you java code read from `Console` : I updated my answed. – Serge Ballesta Jun 12 '14 at 07:56

4 Answers4

1

If you really look for in simple Windows batch solution, here is one derived from the batch from PostgreSQL.

SET path=c:\
SET /P path="Path of code [%path%]: "

SET folder=\
SET /P folder="Folder name [%folder%]: "

REM and do what you want with those values ...
echo %path%
echo %folder%

This method allows even to propose default values.

EDIT

I've just seen you java code was reading from the console and not from stdin, so no redirection solution will help. Maybe you should look at the following post from SO How to simulate keyboard presses in java?

EDIT2

So the problem was not as I first thought to ask parameters in batch, but to automate a java program that asked two parameters on the console. Robot is a nice trick to automate such things. I wrote a piece of java that simulates its arguments being typed on keyboard followed by enter. My own trick is the use of Alt xyz to send the correct KeyEvent for any character.

You should only do java -jar ...\RoboSend.jar "ext.bat" "real_path" "real_folder" or java -jar ...\RoboSend.jar "ext.bat" %path% %folder%

package org.sba.robotsend;

import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;

/**
 * This program simulates the typing of its arguments on Console keyboard.
 * Each argument is send via Robot to the console, followed by an Enter key
 * Ex : java -j RobotSend.jar "echo foo" "echo bar"  gives :
 *  c:\> echo foo
 *  foo
 *  c:\> echo bar
 *  bar
 *
 * It is intented to automate programs reading their input on the Console
 * 
 * @author serge.ballesta
 */
public class RobotSend {
    private Robot robot;
    private Charset cp850;
    private static final int[] keys = { KeyEvent.VK_NUMPAD0, KeyEvent.VK_NUMPAD1,
         KeyEvent.VK_NUMPAD2, KeyEvent.VK_NUMPAD3, KeyEvent.VK_NUMPAD4,
         KeyEvent.VK_NUMPAD5, KeyEvent.VK_NUMPAD6, KeyEvent.VK_NUMPAD7,
         KeyEvent.VK_NUMPAD8, KeyEvent.VK_NUMPAD9
    };

    /**
     * This program simulates the typing of its arguments on Console keyboard.
     * Each argument is send via Robot to the console, followed by an Enter key
     * Ex : java -j RobotSend.jar "echo foo" "echo bar"  gives :
     *  c:\> echo foo
     *  foo
     *  c:\> echo bar
     *  bar
     *
     * It is intented to automate programs reading their input on the Console
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        RobotSend robot = new RobotSend();

        try {
            robot.run(args);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void run(String[] args) throws AWTException {
        robot = new Robot();
        cp850 = Charset.forName("IBM850");
        for (String str: args) {
            sendString(str);
        }
    }

    /**
     * Send a byte using the Alt xyz sequence.
     * the byte must be in CP850 code page, indipendently of the actual code
     * page of the console (at least for System natively in CP850 ...)
     * @param c the byte (char) to be inputted via keyboard
     */
    public void sendByte(byte c) {
            int i = (int) c;
            if (i < 0) { i = 256 + i; }
            if (i < 0  || i > 255) { i = 'X'; }
            int i1 = i / 100;
            int i2 = (i % 100) / 10;
            int i3 = i % 10;
            robot.keyPress(KeyEvent.VK_ALT);
            robot.keyPress(keys[i1]);
            robot.keyRelease(keys[i1]);
            robot.keyPress(keys[i2]);
            robot.keyRelease(keys[i2]);
            robot.keyPress(keys[i3]);
            robot.keyRelease(keys[i3]);
            robot.keyRelease(KeyEvent.VK_ALT);
    }

    /**
     * Simulate a Enter
     */
    public void sendEnter() {
        robot.keyPress(KeyEvent.VK_ENTER);
        robot.keyRelease(KeyEvent.VK_ENTER);
    }

    /**
     * Send a String via the Console keyboard.
     * The string is first encoded in CP850, sent one char at a time via sendByte
     * and followed by an Enter key
     * @param str 
     */
    public void sendString(String str) {
        ByteBuffer buf = cp850.encode(str);
        for (byte b: buf.array()) {
            sendByte(b);
        }
        sendEnter();
    }
}
Community
  • 1
  • 1
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • Dear Serge-- where in above script should i call the ext.bat as its sets path for both the args only. And it want manual intervention i think – smriti Jun 12 '14 at 07:56
  • If you can call ext.bat with args, just add `call ext.bat %path% %folder%` at end of batch ... but see also my edit. – Serge Ballesta Jun 12 '14 at 07:59
  • NO as i told in the problem i can not call batch with args :( – smriti Jun 12 '14 at 08:00
  • Thanks you so much Dear Serge. With your suggestion I done it. in answer i have put whole code. Its working fantastically. Thank you HUG~YOU. +50 for you.... :) – smriti Jun 12 '14 at 10:14
  • @smriti I have just finished my tests (and went eating in meanwhile :-) ). It seems to work, see code in my updated post. – Serge Ballesta Jun 12 '14 at 12:15
  • +50 awarded to you Serge. Thanks again. a lot – smriti Jun 12 '14 at 16:13
0

Java does have a method to execute command line commands. Use the following line of code to run a command line command: Runtime.getRuntime().exec("my command"); where "my command" is the line you with to execute, such as running the batch file.

What is happening is that the Java code is getting a "runtime", which is basically a console. Executing the string in the Java code has the same effect as it would if you typed the command into the command line.

For your problem, get the file & directory inputs into strings, and then use these strings as the arguments to your batch file. Build the command as a new string, with the arguments attached, and then run the command. Also make sure you include "cmd" in the front of your command, because that will actually execute the batch file.

For example, Runtime.getRuntime().exec("my command" + " " + arg1 + " " + arg2);

A similar question has been asked, so take a look how they solved the issue. How do I run a batch file from my Java Application?

Also take a look at the following link, as it may give a useful and relevant example. http://omtlab.com/java-how-to-run-exe-file-and-batch-file-using-java-program/

Community
  • 1
  • 1
jluckin
  • 662
  • 4
  • 6
  • Jonathan Thanks for looking into; I tried with this. But the batch file is -- not taking args like this.. don't know why :(. The batch file internally calling a java file. In java it takes two param from console. Please suggest what would be reason that its not taking the args from exec method... – smriti Jun 09 '14 at 16:47
  • just to highlight one more thing, Even I call the java class directly like -- java myclass args1 args2. its not working. because its takes one by one ... I mean if program satisfied with first arg then it will ask for second; I should not change the java class the way its taking... – smriti Jun 09 '14 at 16:51
  • Are you trying to automate the execution of a batch file from your java code, or are you trying to execute a java class from the batch file? The code that I posted was assuming that you are trying to execute batch files from the java program. – jluckin Jun 09 '14 at 17:00
  • Basically --I am running a java class for automation. which calls this batch file. This batch file(calls a executable java file) is with different owner I can not modify or change. batch file just have --%JAVA_HOME%/bin/java myclass – smriti Jun 09 '14 at 17:38
  • Make sure that your path variable is set up correctly, maybe try explicitly listing the path to java in your batch file. I'll be putting links/other relevant advice by editing my answer, so look there – jluckin Jun 09 '14 at 18:02
  • so good of you. Let me try again. I will update here my result. May be again need your help on this,,,, – smriti Jun 09 '14 at 18:07
  • its Unfortunate -- Did not help String filePath="C:/Users/ext.bat"; String args1="C:\\text"; String args2="text"; try { Process p = Runtime.getRuntime().exec(filePath + " " + args1 + " " + args2); – smriti Jun 10 '14 at 06:55
  • Make sure that you include "cmd" in your command, since that will execute the batch file. Take a look at the examples in the link above and try adapt them to your needs. – jluckin Jun 10 '14 at 13:03
  • i used --Process p = Runtime.getRuntime().exec("cmd /c start ext.bat"+" "+args1 +" "+args2); console is opening with first question Please enter the path for code.. and hangs there.. – smriti Jun 10 '14 at 14:49
  • as manually also the batch is not working on cmd prompt like this ---ext.bat path file. it ask first question then second. – smriti Jun 10 '14 at 15:40
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/55385/discussion-between-jonathan-luckin-and-smriti). – jluckin Jun 10 '14 at 15:54
0

Although you requested a Java solution, it is obvious that you may also run a Batch file, so I wrote a Batch file solution. Well, it is really a Batch-JScript hybrid script that make good use of WSH WScript.Shell.Exec method feature of have access to Stdin and Stdout channels of the executed process. Of course, you may also just take out the JScript code, if you wish.

@if (@CodeSegment == @Batch) @then

@echo off
cscript //nologo //E:JScript "%~F0"
goto :EOF

@end

// Execute the bat file
var batFile = new ActiveXObject("WScript.Shell").Exec("c:\\ext.bat");

// Expect the first prompt
while ( batFile.StdOut.ReadLine() != "Please enter the path for code" );

// Respond to first prompt
batFile.StdIn.WriteLine("c:\\");

// Expect the second prompt
while ( batFile.StdOut.ReadLine() != "Please enter the directory name" );

// Respond to second prompt
batFile.StdIn.WriteLine("test");

EDIT: In your question it seems that you need to identify (wait for) the specific prompts. However, if you want just to enter keys into the keyboard buffer, you may do that in a simpler way via JScript Sendkeys method:

@if (@CodeSegment == @Batch) @then

@echo off
cscript //nologo //E:JScript "%~F0"
goto :EOF

@end

var WshShell = WScript.CreateObject("WScript.Shell");
WshShell.Exec("c:\\ext.bat");
WshShell.SendKeys("c:\\{ENTER}");    
WshShell.SendKeys("test{ENTER}");
Aacini
  • 65,180
  • 12
  • 72
  • 108
  • Dear Aacini-- I copied the script form here and saved as sol.bat. i am getting follwoing error-- C:\ext.bat(16, 32) Microsoft JScript compilation error: Unterminated string constant. I double checked no unterminated string there, Please look into, Second point-- Do i need to install/set some paths, before i run this bat file?? i am running on win7 with no specific ms tools like vb etc... waiting for your reply.. – smriti Jun 12 '14 at 07:50
  • Oops, my mistake! 1. You need to double the backslash inside quotes in _two lines_ this way: `"c:\\..."`; I already did that in the code above. 2. You need nothing additional in order to run this program in any computer from Win XP on. For further details, see: http://msdn.microsoft.com/en-us/library/yek4tbz0(v=vs.84).aspx – Aacini Jun 12 '14 at 10:23
0

*Use Robot class.

First open batch file from java exec code and simulate the keyboard keys ...*

//@Author Smriti.

import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.lang.reflect.Field;



public class TestExpect {

    /**
     * @param args
     */
    public static void main(String[] args) {

        // TODO Auto-generated method stub

    String filePath="C:/ext.bat";

        try {
            Process p = Runtime.getRuntime().exec("cmd /c start"+filePath);

        } catch (IOException e1) {
            // TODO Auto-generated catch block
        System.out.println(e1.getMessage());    
        e1.printStackTrace();
        }


        try {


                Robot robot = new Robot();
                typeCharacter(robot, "c");
                robot.keyPress(KeyEvent.VK_SHIFT);
                robot.keyPress(KeyEvent.VK_SEMICOLON);
                robot.keyRelease(KeyEvent.VK_SEMICOLON);
                robot.keyRelease(KeyEvent.VK_SHIFT);
                robot.keyPress(KeyEvent.VK_ENTER);
                typeCharacter(robot, "c");
                robot.keyPress(KeyEvent.VK_SHIFT);
                robot.keyPress(KeyEvent.VK_SEMICOLON);
                robot.keyRelease(KeyEvent.VK_SEMICOLON);
                robot.keyRelease(KeyEvent.VK_SHIFT);
                robot.keyPress(KeyEvent.VK_SLASH);
                typeCharacter(robot, "i");
                typeCharacter(robot, "n");
                typeCharacter(robot, "s");
                typeCharacter(robot, "t");
                typeCharacter(robot, "1");
                robot.keyPress(KeyEvent.VK_ENTER);

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

     public static void typeCharacter(Robot robot, String letter)
        {
            try
            {
                boolean upperCase = Character.isUpperCase( letter.charAt(0) );
                String variableName = "VK_" + letter.toUpperCase();

                Class clazz = KeyEvent.class;
                Field field = clazz.getField( variableName );
                int keyCode = field.getInt(null);

                robot.delay(1000);

                if (upperCase) robot.keyPress( KeyEvent.VK_SHIFT );

                robot.keyPress( keyCode );
                robot.keyRelease( keyCode );

                if (upperCase) robot.keyRelease( KeyEvent.VK_SHIFT );
            }
            catch(Exception e)
            {
                System.out.println(e);
            }
        }

}
smriti
  • 1,124
  • 5
  • 14
  • 35
  • Excuse me, where are the `expect("Please enter the path for code")` request of your original question in this solution? See the edit in my answer... – Aacini Jun 12 '14 at 10:57
  • Thanks @Aacini for your help and time, I remove expect as i want to open the command prompt to the window, that can also be done from exec command, after it opens i call robot class to simulate keyboard to type, that is what i was looking for. BTW i tried with your edited code that again failing with --"'cscript' is not recognized as an internal or external command," – smriti Jun 12 '14 at 14:07
  • If you start a bounty you should be very careful if you change the specifications on the fly. You should be sure that the change does not result in the detrimental nor benefit of any answerer that participate in the topic attracted by the bounty points. After all, _this is_ the purpose of a bounty, isn't it? `:(` – Aacini Jun 13 '14 at 03:01