HƯỚNG DẪN Working with OS tools using Runtime.getRuntime().exec()

Joe

Thành viên VIP
21/1/13
2,958
1,323
113
Hi

A real IT developer is the one who can work from a high-level like JAVA with the low-level OS-specific tools or OS commands. MacOS, Windows and LINUX-based OS shield its users from the OS tools with the fancy graphic user interfaces (i.e. icons). It's easy to use for the laypeople. But YOU as an IT developer who makes money from Software development? Using fancy high-level packages such as SPRING or whatever won't help so much when you have to access the OS specific data (or information) but it makes you looking like a very bad IT developer. For example, how can I run a Java App to access a value from a certain keyword stored in Windows Registry, or to verify the state of a submitted task whether it is still running or terminated? Impossible? NO. It's possible!

With the API Runtime you have the best tool to dive deeply into the OS low-level environment. I show you hereunder the possibility to access the OS tools or OS commands on Windows. And the similarity can be drawn on Linux OS, MacOS and Android. Let start with two Windows tools or commands: tasklist and reg.
Code:
C:\JFX\Browser>tasklist

Task Name                  PID     Session          Sess-No     Memory in use
========================= ======== ================ =========== ===============
System Idle Process              0 Services                   0             8 K
System                           4 Services                   0         2.988 K
Registry                       100 Services                   0        39.328 K
smss.exe                       460 Services                   0           552 K
csrss.exe                      688 Services                   0         2.656 K
wininit.exe                    648 Services                   0         3.552 K
services.exe                   756 Services                   0         8.684 K
...                             ..   ...                      .           ...
conhost.exe                  14764 Console                   85        15.712 K
tasklist.exe                 60716 Console                   85         9.268 K
WmiPrvSE.exe                139188 Services                   0        10.032 K

C:\JFX\Browser>reg /?

REG Command [Parameter list]

  command  [ QUERY   | ADD    | DELETE  | COPY    |
             SAVE    | LOAD   | UNLOAD  | RESTORE |
             COMPARE | EXPORT | IMPORT  | FLAGS ]

Return code: (with an exception of REG COMPARE)

  0 - successful
  1 - failed

    ...

C:\JFX\Browser>
From the command tasklist output you are able to extract relevant information about all running tasks on Windows: TaskName, TaskID, TaskSize, etc. and the command reg allows you to access directly the Windows Registry. Here is an application in JAVA using Runtime.getRuntime().exec().

The API WINDOWS.java
Java:
import java.io.*;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
// Joe Nartca (C)
public class WINDOWS {
  /** get a list of running tasks.
  @return List of running tasks
  */
  public static List<String> taskList( ) {
    try {
      List<String> list = new ArrayList<>();
      Process lstTasks = Runtime.getRuntime().getRuntime().exec("tasklist");
      BufferedReader reader = new BufferedReader(new InputStreamReader(lstTasks.getInputStream()));
      while (true) {
        String task = reader.readLine();
        if (task == null) return list;
        list.add(task);
      }
    } catch (Exception e) { }
    return null;
  }
  /** check for a specifed task whether it's running or not
  @param tName String, the task name to be checked (e.g. notepad.exe)
  @return boolean true: is running, otherwise: no or taskname is unknown
  */
  public static boolean isTaskRunning(String tName) {
    try {
      Process lstTasks = Runtime.getRuntime().getRuntime().exec("tasklist");
      BufferedReader reader = new BufferedReader(new InputStreamReader(lstTasks.getInputStream()));
      String task = reader.readLine(); // ignore 1st line
      task = reader.readLine(); // ignore 2nd line
      task = reader.readLine(); // ignore 3rd line
      while (true) { // loop till last line
        task = reader.readLine();
        if (task == null) return false;
        if (getName(task).equals(tName)) return true;
      }
    } catch (Exception e) { }
    return false;
  }
  /** get the Task ID of tName
  @param tName String, the task name to be checked (e.g. notepad.exe)
  @return int -1 if unknown, otherwise task ID
  */
  public static int taskID(String tName) {
    int i = 0;
    List<String> list = taskList( );
    for (int p = tName.indexOf(" "); p > 0; p = tName.indexOf(" ", p+1)) ++i;
    for (int p = 3, mx = list.size(); p < mx; ++p) if (tName.equals(getName(list.get(p)))) return toInt(list.get(p), i+1);
    return -1;
  }
  /** get the size of tName
  @param tName String, the task name to be checked (e.g. notepad.exe)
  @return int -1 if unknown, otherwise in KB
  */
  public static int taskSize(String tName) {
    int i = 0;
    List<String> list = taskList( );
    for (int p = tName.indexOf(" "); p > 0; p = tName.indexOf(" ", p+1)) ++i;
    for (int p = 3, mx = list.size(); p < mx; ++p) if (tName.equals(getName(list.get(p)))) return toInt(list.get(p), i+4);
    return -1;
  }
  /** kill the specifed running task
  @param tName String, the task name to be killed (e.g. notepad.exe)
  @return boolean true: successful
  */
  public static boolean killTask(String tName) {
    try {
      if (isTaskRunning(tName)) {
        Runtime.getRuntime().exec("taskkill /F /IM " + tName);
        return true;
      }
    } catch (Exception e) { }
    return false;
  }
  /**
  get Registry Value
  @param regPath String, Registry Path, e.g. HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings
  @param keyword String, Registry keyword, e.g. ProxyServer
  @return String, e.g. hostname:port for the above mentioned String.
  */
  public static String getRegValue(String regPath, String keyword) {
    try {
      if (System.getProperty("os.name").startsWith("Windows")) regPath = regPath.replace("/", "\\");
      Process process = Runtime.getRuntime().exec("reg query \""+regPath+ "\" /v \""+keyword+"\"");
      process.waitFor();
      byte[] out = new byte[2048]; // 2K
      InputStream inp = process.getInputStream();
      int n = inp.read(out);
      inp.close();
      if (n > 0) {
        String[] items = (new String(out, 0, n)).replace("\t","").replace("  "," ").split(" ");
        return items[items.length-1].replace("\r","").replace("\n","");
      }
    } catch (Exception e) { }
    return null;
  }
  //
  private static int toInt(String tsk, int i) {
    List<String> lst = Arrays.stream(tsk.split(" ")).filter(n -> !n.isEmpty()).collect(Collectors.toList());
    for (int mx = lst.size(); i < mx; ++i) {
      char c = lst.get(i).charAt(0);
      if (c >= '0' && c <= '9')  try {
         return Integer.parseInt(lst.get(i).replace(".","").replace(",",""));
      } catch (Exception ex) { return -1; }
    }
    return -1;
  }
  //
  private static String getName(String task) {
    int i = 1;
    List<String> lst = Arrays.stream(task.split(" ")).filter(n -> !n.isEmpty()).collect(Collectors.toList());
    StringBuilder name = new StringBuilder(lst.get(0));
    for (int mx = lst.size(); i < mx; ++i) {
      char c = lst.get(i).charAt(0);
      if (c >= '0' && c <= '9') break;
      name.append(" "+lst.get(i));
     }
     return name.toString();
  }
}
How to run WINDOWS?
Java:
import javax.swing.*;
import java.util.*;
import java.awt.Font;
// Joe Nartca (C)
public class Test {
  public static void main(String... a) throws Exception {
    UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
    new Test( );
  }
  private void combo(int idx, JTextArea jta) {
    String name, keyword;
    switch (idx) {
    case 0: List<String> lst = WINDOWS.taskList( );
      for (String s:lst) jta.append(s+"\n");
      return;
    case 1: name = JOptionPane.showInputDialog(jf,"Enter Task Name");
      if (name == null || name.length() == 0) return;
      jta.append("Task: "+name+", ID: "+WINDOWS.taskID(name)+"\n");
      return;
    case 2: name = JOptionPane.showInputDialog(jf,"Enter Task Name");
      if (name == null || name.length() == 0) return;
      jta.append("Task: "+name+", Size: "+WINDOWS.taskSize(name)+" KB\n");
      return;
    case 3: name = JOptionPane.showInputDialog(jf,"Enter Task Name");
      if (name == null || name.length() == 0) return;
      jta.append("Task: "+name+" is running? "+(WINDOWS.isTaskRunning(name)?"YES":"NO")+"\n");
      return;
    case 4: name = JOptionPane.showInputDialog(jf,"Enter Task Name");
      if (name == null || name.length() == 0) return;
      jta.append("Task: "+name+" is killed: "+(WINDOWS.killTask(name)?"YES":"NO")+"\n");
      return;
    case 5: name = JOptionPane.showInputDialog(jf,"Enter Registry Path");
      if (name == null || name.length() == 0) return;
      keyword = JOptionPane.showInputDialog(jf,"Enter Keyword");
      if (keyword == null || keyword.length() == 0) return;
      jta.append(keyword+" has the value: "+WINDOWS.getRegValue(name, keyword)+"\n");
      return;
    }
  }
  public Test( ) throws Exception {
    jf = new JFrame("Test WINDOWS tool");
    JTextArea jta = new JTextArea(60, 1);
    jta.setFont(new Font("Monospaced", Font.PLAIN, 12));
    jta.setEditable(false);
    JScrollPane jsp = new JScrollPane (jta,
                                       JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                                       JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    JComboBox<String> cb = new JComboBox<>("TASK LIST!TASK ID!TASK SIZE!IS RUNNING!KILL TASK!REG_VALUE".split("!"));
    cb.addActionListener(e -> {
      combo(cb.getSelectedIndex(), jta);
    });
    jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JPanel pan = new JPanel();
    pan.add(cb);
    //
    jf.add("Center", jsp);
    jf.add("South", pan);
    jf.setSize(600, 400);
    jf.setVisible(true);
  }
  private JFrame jf;
}
If you successfully compiled the codes the result would be
reg.png

reg_1.png

reg_2.png

Enjoy
Joe
 
Sửa lần cuối: