[자바 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();
}
}
}