1

我的问题是,我正在通过终端运行一些 adb 命令。我写了一个工具;这将有助于使事情变得更容易。所以回到问题,为了让命令运行,我必须在终端上输入一个“密码”。那么我该怎么做才能使“密码”部分出现在 JOptionPane.showInputDialog 框中?

这是我到目前为止所拥有的:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;

import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileNameExtensionFilter;


public class flash implements ActionListener {
    private File runfile;
    @Override
    public void actionPerformed(ActionEvent arg0) {
        {


            JFileChooser adbflashfile = new JFileChooser("/home/local/ANT/arthm/Desktop/os"); 
           FileNameExtensionFilter filter = new FileNameExtensionFilter(".py", "py");

                adbflashfile.setFileFilter(filter);

            int returnVal = adbflashfile.showOpenDialog(null);
            if (returnVal == JFileChooser.APPROVE_OPTION) {
                runfile = adbflashfile.getSelectedFile();

                try {
                    Runtime.getRuntime().exec("sudo python ./flashimage.py");
                } catch (IOException e1) {

                    e1.printStackTrace();
                }
                //This is where a real application would open the file.
                System.out.println("File: " + runfile.getName() + ".");    
            } else {
                JOptionPane.showMessageDialog(null, "Open command cancelled by user.");
            }
            System.out.println(returnVal);
        }
    };
    }
4

2 回答 2

1

您“可以”读取过程输入,当您“检测”密码提示时,显示 aJOptionPane并要求用户输入密码。

您“可以”在启动流程之前提示用户输入密码,因为您知道您需要将密码发送到流程。

您可能仍需要监视进程的输出以确定何时需要发送密码。

让我们从...

Runtime.getRuntime().exec("sudo python ./flashimage.py");

你完全忽略了Process。你也没有处理输出,但你没有办法为过程提供输入......

一般来说,Runtime#exec充其量是有问题的。你最好使用ProcessBuilder....

// Build the command to be executed.  Note that each parameter becomes
// it's own argument, this deals with parameters that contain spaces
// much better then Runtime#exec alone...
ProcessBuilder pb = new ProcessBuilder("sudo", "python", "./flashimage.py");
pb.redirectError();

InputStream is = null;
try {
    Process p = pb.start();
    is = p.getInputStream();
    StringBuilder output = new StringBuilder(80);
    int in = -1;
    while ((in = is.read()) != -1) {
        if (in != '\n') {
            output.append((char)in);
            // You will need to define PASSWORD_PROMPT
            if (PASSWORD_PROMPT.equals(output.toString())) {
                String text = JOptionPane.showInputDialog("Password");
                OutputStream os = p.getOutputStream();
                os.write(text.getBytes());
            }
        } else {
            System.out.println(output.toString());
            output.delete(0, output.length());
        }
    }
} catch (IOException exp) {
    exp.printStackTrace();
} finally {
    try {
        is.close();
    } catch (Exception e) {
    }
}

现在,毫无疑问,有人会指出(至少)这种方法的两个问题......

  1. JOptionPane.showInputDialog("Password");将呈现一个 normal JTextField,它不会隐藏密码字符和
  2. String不是存储密码的最安全方法...

相反,我们应该使用 aJPasswordField并将结果char数组转换为byte数组...

JPasswordField password = new JPasswordField(10);
JLabel label = new JLabel("Password: ");
JPanel panel = new JPanel();
panel.add(label);
panel.add(password);

int option = JOptionPane.showConfirmDialog(null, panel, "Password", JOptionPane.OK_CANCEL_OPTION);
if (option == JOptionPane.OK_OPTION) {
    char[] userPassword = password.getPassword();
    byte[] bytes = new byte[userPassword.length * 2];
    for (int i = 0; i < userPassword.length; i++) {
        bytes[i * 2] = (byte) (userPassword[i] >> 8);
        bytes[i * 2 + 1] = (byte) userPassword[i];
    }
    os.write(bytes);
}
于 2013-09-17T00:09:54.193 回答
0

可以使用Process类重定向子进程 I/O。您应该能够监视输出并将输入(密码)提供给子进程。

看:

于 2013-09-16T23:32:55.153 回答