[자바 JNA] 익스플로러 창개수 관리 데몬

[자바 JNA] 익스플로러 창 개수 관리 데몬

익스플로러를 띄우고, 창 개수를 관리해주는 데몬이다. 인터넷 옵션에서 원하는 URL을 홈페이지로 설정해두고 실행시키면 된다.

– 임포트 필요한 jar : (1) jna-4.5.0.jar / (2) jna-platform-4.5.0.jar

– 사용법

1. 아래 내용으로 프로젝트를 만든다.

2. 이클립스에서 프로젝트명 우클릭 – Build Path – Configure Build Path – 좌측메뉴의 Java Build Path – Libraries 탭 – Add JARs 버튼 – 클릭하고 라이브러리 (1) jna-4.5.0.jar / (2) jna-platform-4.5.0.jar 이렇게 2개 선택하고 – OK 버튼 클릭.

3. 이클립스에서 File – Export – Runnable JAR File 로 jar 파일 1개로 묶는다. (IEChecker.jar)

4. 동일한 위치에, IEChecker.bat 파일을 메모장으로 만든다. 내용은 아래와 같이 한다.

javaw -jar ./IEChecker.jar handleCount=2 sleep=200 closeHwpPwd=0

handleCount 는 목표하는 창 개수이다. 2로 지정되어 있다면 익스플로러 창을 2개로 유지한다.

sleep 은 루프돌 때의 대기시간이다. 밀리세컨드로 적으면 되며 100 에서 200 사이 값을 주면 적당하다.

closeHwpPwd 은 혹시나 해서 만든 옵션이다. 0 으로 놓고 돌리면 된다. 1 일 경우 한글(프로그램) 암호입력 창이 나올 경우 닫는다.

5. cmd 창을 열고 해당 bat 파일을 실행한다. 끝.

package com;

import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.util.ArrayList;

import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.RECT;
import com.sun.jna.platform.win32.WinUser.WNDENUMPROC;

public class MainClass {

    // 한글 암호입력창일 경우 닫기 옵션일 경우
    public static boolean optionCloseHwpPwd = false;
   
    // 로봇 객체
    public static Robot robot = null;

   
    /**
     * 메인 함수. IE Checker 를 실행한다.
     *
     * @param args
     */
    public static void main(String[] args) {

        double mx = 1000;
        double my = 1000;

        int targetHandleCount = 1;
        int sleepMilSecond = 200;
       
        try {
            System.out.println(“IE Checker Run.”);
           
            targetHandleCount = getArgumentInt(args, “handleCount”);
            if (targetHandleCount < 1) {
                targetHandleCount = 1;
            }
           
            sleepMilSecond = getArgumentInt(args, “sleep”);
            if (sleepMilSecond < 1) {
                sleepMilSecond = 200;
            }
           
            int closeHwpPwd = getArgumentInt(args, “closeHwpPwd”);
            if (closeHwpPwd == 1) {
                optionCloseHwpPwd = true;
            }

           
            System.out.println(“handleCount : ” + targetHandleCount);
            System.out.println(“sleep : ” + sleepMilSecond);
            System.out.println(“closeHwpPwd : ” + optionCloseHwpPwd);
           
            robot = new Robot();

            System.out.println(“Loop Begin.”);
           
            // 마우스가 화면 좌상단 10, 10 이내이면 프로그램 종료.
            while (mx > 10 || my > 10) {
                Point point = MouseInfo.getPointerInfo().getLocation();
                mx = point.getLocation().getX();
                my = point.getLocation().getY();

                // printAllHandles();
               
                if (targetHandleCount > checkHandleCount(“IEFrame”)) {
                    executeIEProcess();
                }
               
                Thread.sleep(sleepMilSecond);
            }
           
            System.out.println(“Loop End.”);

        } catch (Exception e) {
            e.printStackTrace();
        }
       
        System.out.println(“IE Checker End.”);
    }
   
   
    /**
     * 아규먼트 배열에서 특정한 키값으로 이퀄(=) 우측의 숫자 값을 얻는다.
     *
     * @param args
     * @param nameToFind
     * @return
     */
    public static int getArgumentInt(String[] args, String nameToFind) {
        String str = getArgumentString(args, nameToFind);
        if (str == null || str.length() == 0) {
            return 0;
        }
       
        int result = 0;
        try {
            result = Integer.parseInt(str);
       
        } catch (Exception e) {
            e.printStackTrace();
        }
       
        return result;
    }

   
    /**
     * 아규먼트 배열에서 특정한 키값으로 이퀄(=) 우측의 문자열 값을 얻는다.
     *
     * @param args
     * @param nameToFind
     * @return
     */
    public static String getArgumentString(String[] args, String nameToFind) {
        if (args == null || args.length == 0) {
            return “”;
        }
       
        if (nameToFind == null || nameToFind.length() == 0) {
            return “”;
        }
       
        String oneArg = “”;
        int cnt = args.length;
        for (int i=0; i<cnt; i++) {
            oneArg = args[i];
            if (oneArg == null || oneArg.length() == 0) {
                continue;
            }
           
            if (oneArg.toLowerCase().startsWith(nameToFind.toLowerCase() + “=”)) {
                int eqIdx = oneArg.indexOf(“=”);
                String result = oneArg.substring(eqIdx + 1);
                return result;
            }
        }
       
        return “”;
    }

   
    /**
     * 익스플로러를 실행한다.
     *
     * @throws Exception
     */
    public static void executeIEProcess() throws Exception {
       
        ArrayList list = new ArrayList();
        list.add(“C:\\Program Files\\Internet Explorer\\iexplore.exe”);
        // list.add(“http://en.wikipedia.org/“);

        ProcessBuilder pb = new ProcessBuilder(list);
        pb.start();
    }
   
   
    /**
     * 현재 실행중인 모든 핸들의 정보를 출력한다. (로그출력용)
     */
    /*
    public static void printAllHandles() {

        try {
            User32.INSTANCE.EnumWindows(new WNDENUMPROC() {

                public boolean callback(HWND hWnd, Pointer arg1) {
                    char[] windowText = new char[512];
                    User32.INSTANCE.GetWindowText(hWnd, windowText, 512);
                    String wText = Native.toString(windowText);
                    RECT rectangle = new RECT();
                    User32.INSTANCE.GetWindowRect(hWnd, rectangle);

                    if (wText.isEmpty() ||
                        !(User32.INSTANCE.IsWindowVisible(hWnd) &&
                            rectangle.left > -32000)) {
                        return true;
                    }

                    int count = 0;
                   
                    char[] c = new char[512];
                    User32.INSTANCE.GetClassName(hWnd, c, 512);
                    String clsName = String.valueOf(c).trim();

                    StringBuffer buff = new StringBuffer();

                    buff.append(“번호:” + (++count));
                    buff.append(“,텍스트:” + wText);
                    buff.append(“,” + “위치:(“);
                    buff.append(rectangle.left + “,” + rectangle.top + “)~(“);
                    buff.append(rectangle.right + “,” + rectangle.bottom);
                    buff.append(“),” + “클래스네임:” + clsName);

                    System.out.println(buff.toString());

                    return true;
                }
            }, null);
           
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    */
   
   
    /**
     * 현재 실행 중인 핸들의 개수를 얻는다.
     *
     * @param targetHandleName
     * @return
     */
    public static int checkHandleCount(String targetHandleName) {
       
        if (targetHandleName == null || targetHandleName.length() == 0) {
            return -1;
        }
       
        final String finHandleName = targetHandleName;
       
        final int[] handleCount = new int[1];
        handleCount[0] = 0;
       
        try {
            User32.INSTANCE.EnumWindows(new WNDENUMPROC() {
                public boolean callback(HWND hWnd, Pointer arg1) {
                    char[] windowText = new char[512];
                    User32.INSTANCE.GetWindowText(hWnd, windowText, 512);
                    String wText = Native.toString(windowText);
                    RECT rectangle = new RECT();
                    User32.INSTANCE.GetWindowRect(hWnd, rectangle);

                    if (wText.isEmpty() ||
                        !(User32.INSTANCE.IsWindowVisible(hWnd) &&
                            rectangle.left > -32000)) {
                        return true;
                    }

                    int count = 0;
                   
                    char[] c = new char[512];
                    User32.INSTANCE.GetClassName(hWnd, c, 512);
                    String clsName = String.valueOf(c).trim();

//                    StringBuffer buff = new StringBuffer();
//
//                    buff.append(“번호:” + (++count));
//                    buff.append(“,텍스트:” + wText);
//                    buff.append(“,” + “위치:(“);
//                    buff.append(rectangle.left + “,” + rectangle.top + “)~(“);
//                    buff.append(rectangle.right + “,” + rectangle.bottom);
//                    buff.append(“),” + “클래스네임:” + clsName);
//
//                    System.out.println(buff.toString());
                   
                    if (clsName != null) {
                        if (clsName.equals(finHandleName)) {
                            handleCount[0]++;
                        }
                       
                        // 한글 암호입력창일 경우 닫기 옵션일 경우
                        if (optionCloseHwpPwd) {
                            // 한글 암호입력창일 경우 닫기 시도한다.
                            if (clsName.equals(“HNC_DIALOG”)) {
                                // 셋포커스(잘 동작하지 않지만 그래도.)
                                User32.INSTANCE.SetForegroundWindow(hWnd);
                               
                                // 현재 포커스된 창 얻기
                                HWND curHwnd = User32.INSTANCE.GetForegroundWindow();
                                if (curHwnd != null) {
                                    String curWinName = getClassNameFromHandle(curHwnd);
                                   
                                    // 현재 포커스된 창이 한글 암호입력 창이라면 종료
                                    if (curWinName != null && curWinName.equals(“HNC_DIALOG”)) {
                                        // 종료
                                        AltF4(200);
                                        return true;
                                    }
                                }
                            }
                        }
                    }

                    return true;
                }
            }, null);
           
        } catch (Exception e) {
            e.printStackTrace();
        }
       
        return handleCount[0];
    }
   
   
    /**
     * 핸들의 이름을 얻는다.
     *
     * @param hWnd
     * @return
     * @throws Exception
     */
    public static String getClassNameFromHandle(HWND hWnd) {
        if (hWnd == null) {
            return “”;
        }
       
        String clsName = “”;
       
        try {
            // 핸들의 클래스 네임 얻기
            char[] c = new char[512];
            User32.INSTANCE.GetClassName(hWnd, c, 512);
            clsName = String.valueOf(c).trim();
           
        } catch (Exception e) {
            e.printStackTrace();
        }
       
        return clsName;
    }
   
   
    public static HWND castHwnd(Object obj) {
        try {
            return (HWND) obj;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
   
   
    public static void AltF4(int delay) {
        try {
            if (robot == null) {
                robot = new Robot();
            }
           
            robot.keyPress(KeyEvent.VK_ALT);
            robot.keyPress(KeyEvent.VK_F4);
            robot.keyRelease(KeyEvent.VK_F4);
            robot.keyRelease(KeyEvent.VK_ALT);
            robot.delay(delay);
       
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}