헤르메스 LIFE

외부프로그램 실행시키기 본문

Core Java

외부프로그램 실행시키기

헤르메스의날개 2020. 12. 17. 00:40
728x90

프로그램의 Runtime 시에 외부프로그램을 수행시킬 필요가 있습니다.

아래의 프로그램을 사용해서 "Notepad.exe"를 실행시켜 보겠습니다.

 

package example.ext;

import java.io.IOException;

public class NotepadExec {
 public static void main(String[] args) throws Exception {
  runNotepad();
 }
 
 static Runtime rt = Runtime.getRuntime();
 
 public static void runNotepad() throws IOException {
  Process notepad = rt.exec("notepad.exe");

  notepad.waitFor();  // Notepad 프로그램이 종료될때까지 기다립니다.
 }
}

 

------------------------------------------------------------------------------

전 일반적인 내용만을 테스트했는데 아래분은 조금 더 테스트해보셨네요.

그래서 첨부했습니다.

 

[아래 영문출처]
http://blogs.sun.com/vaibhav/entry/not_as_easy_as_we


This week, one of my office colleagues,Vijay asked me " Can we runcommand of PowerShell from Java Application ?" Microsoft is coming upwith a new shell called PowerShell, commands are very similar to thatof our Unix Shell. Yes, this problem looks quite simple, I guess JavaRuntime class will do that as it do for cmd commands. And for that wewrote one simple code like this :

import java.io.*;
class OneMore {
public static void main(String[] args)throws IOException
{
          Runtime runtime = Runtime.getRuntime();
           String cmds[] = {"ls"};
           Process proc = runtime.exec(cmds);
           InputStream inputstream = proc.getInputStream();
           InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
           BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
           String line;
           while ((line = bufferedreader.readLine()) != null) {
               System.out.println(line);
           }
}
}

So,this code will print the output of ls on console. But no we need toexecute powershell command. So it is required to pass PowerShell in theString cmds[]. Ok, I don't have PowerShell on my machine but let me tryto run the same with command.exe(cmd.exe) in place of powershell.exe.So, I have changed one line in the code:

String cmds[] = {"cmd", "ls"};

But then this is not right as there should be right option with cmd like /c or /k. So further it changed into :

String cmds[] = {"cmd", "\c", "ls"};

Codeis running fine and we are done with job. But he want a file in placeof command "ls", not a problem pass a file "file.bat" in place of ls.file.bat contains ls :). So, finally code goes something like:

Runtime runtime = Runtime.getRuntime();
           String cmds[] = {"cmd", "\c", "file.bat"};
           Process proc = runtime.exec(cmds);
           InputStream inputstream = proc.getInputStream();
           InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
           BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
           String line;
           while ((line = bufferedreader.readLine()) != null) {
               System.out.println(line);
           }


Evenif we want to check the process is exiting correctly or not, we can addsome more lines checking for proc.waitFor() or proc.ExitValue().

But,this piece of code is not running fine for PowerShell. WHY ? Noclue(till today, trying to find out why). Unfortunately the program gofor a hang. And till now the conclusion is: its either a problem thatwe are not able to find the right substitute of \c in PowerShell,though the document is saying "&" will do the same Or maybePowerShell is stopping us in writing streams(some security issue).

A bad workaround is working fine.

Process proc = runtime.exec("powershell & filename" > out.txt)

Weare able to pass the output of PowerShell process into a file out.txt,now reading the file out.txt and print the output on console. But itcan create problem if out.txt will go large enough. Can you give me theanswer of my WHY ? Why this code is not running for PowerShell. Isthere any bug in PowerShell(according to me, yes) ?



-- 결론
댓글에 정답이..아래처럼 하면 된다.

        String cmd = "cmd /C powershell Get-Process";
        Runtime r = Runtime.getRuntime();
        Process pro = r.exec(cmd);
        pro.getOutputStream().close();

        InputStreamReader isr = new InputStreamReader(pro.getInputStream());
        BufferedReader br = new BufferedReader(isr);

        for (String line = null; (line = br.readLine()) != null;)
              System.out.println(line);


기념으로 아래꺼 그냥 만들어봤다..


///////////////// Java Swing 에서 PowerShell 명령 실행하기 //////////////

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;



/**
 * @author tobby48
 *
 */
public class RuntimeTest extends JFrame implements ActionListener{
   
    /**
     *
     */
    private static final long serialVersionUID = 1L;

   
    /**
     *     JFrame
     */
    private JFrame         jFrame;
    /**
     *     JTextArea Command
     */
    private JTextField    jTextField_Command;
    /**
     *     JTextArea Window
     */
    private JTextArea    jTextArea_Window;
    /**
     *     JButton Run
     */
    private JButton        jButton_Run;
    /**
     *     JButton Clear
     */
    private JButton        jButton_Clear;
   
   
    /**
     *    생성자
     */
    public RuntimeTest(){
   
        jFrame = new JFrame("POWERSHELL VIEWER");
        jTextField_Command = new JTextField("");
        jTextArea_Window = new JTextArea("");
        jButton_Run = new JButton("RUN");
        jButton_Clear = new JButton("CLR");
    }
   
    /**
     *     창 초기화
     */
    public void configWindow(){
       
        /*    스크롤바 지정    */
        jTextArea_Window.setAutoscrolls(true);
        JScrollPane scrollPane = new JScrollPane();
        scrollPane.setViewportView(jTextArea_Window);

       
        /*    Component 크기    */
        jTextArea_Window.setSize(880, 500);
        jTextField_Command.setSize(700, 80);
        jButton_Run.setSize(80, 80);
        jButton_Clear.setSize(80, 80);
               
       
        /*    화면하단 레이아웃    */
        JPanel jPanel = new JPanel();
        jPanel.setLayout(new BorderLayout());
        jPanel.add(jTextField_Command, BorderLayout.CENTER);
        jPanel.add(jButton_Run, BorderLayout.WEST);
        jPanel.add(jButton_Clear, BorderLayout.EAST);
       
       
        /*    Action등록    */
        jButton_Run.addActionListener(this);
        jButton_Clear.addActionListener(this);
       
       
        /*    전체화면 레이아웃    */
        jFrame.setLayout(new BorderLayout());
        jFrame.add(scrollPane, BorderLayout.CENTER);
        jFrame.add(jPanel, BorderLayout.SOUTH);
       
       
        /*    화면 보이기    */
        Dimension windowSize = new Dimension(900, 600);
        jFrame.setSize(windowSize);
        Dimension screenSize= Toolkit.getDefaultToolkit().getScreenSize();

        jFrame.setLocation((screenSize.width - windowSize.width)/2,
                                              (screenSize.height - windowSize.height)/2);

        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jFrame.setResizable(true);
        jFrame.setVisible(true);
    }
   
    public void runProcess(String cmd) throws IOException, InterruptedException{
   
        String initCommand = "cmd /c powershell ";
        Runtime r = Runtime.getRuntime();

        Process pro = r.exec(initCommand + cmd);
        pro.getOutputStream().close();

        InputStreamReader isr = new InputStreamReader(pro.getInputStream());
        BufferedReader br = new BufferedReader(isr);
       
        for (String line = null; (line = br.readLine()) != null;)
            jTextArea_Window.append(line + "\n");

        isr.close();
        pro.destroy();
    }
   
    /**
     * @param str
     */
    public static void main(String str[]){
       
        RuntimeTest rt = new RuntimeTest();
        rt.configWindow();
    }

    /* (non-Javadoc)
     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
     */
    public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub
       
        if(e.getActionCommand().endsWith("RUN")){
            try {
                runProcess(jTextField_Command.getText());
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            } catch (InterruptedException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }else if(e.getActionCommand().endsWith("CLR")){
            jTextArea_Window.setText("");
            jTextArea_Window.validate();
            jTextField_Command.setText("");
            jTextField_Command.validate();
        }
    }
}

출처:[JAVA] Java Runtime 클래스를 이용한 PowerShell 구동

728x90

'Core Java' 카테고리의 다른 글

[Source] XPatharserDemo  (0) 2020.12.20
[HttpURLConnection] jsp 파일의 실행  (0) 2020.12.17
Thread 를 이용한 데몬 프로그램  (0) 2020.12.17
BigDecimal타입의 사칙연산  (0) 2020.12.17
Java에서 Stored Procedure 실행  (0) 2020.12.17