반응형
'자바 프로그래머'라면 한번쯤 고민하게 되는 부분이 있다. 그 중 하나가 자바 API가 지원하지 못하는 부분에 대한 것이다. 예를 들어 자바 API로는 네트워크 인터페이스 카드(NIC, 흔히 랜 카드라고 부른다)의 맥 어드레스(MAC Address)를 알아 낼 방법이 없다. 결국 JNI(Java Native Interface)를 사용하거나 다른 꽁수(?)를 찾아내곤 한다. 본인이 생각하기에는 두 방법 모두 시원스런 방법은 아니라서 상당히 거시기한 느낌이다. JNI를 사용하자니 C/C++ 코드를 사용하여 플랫폼에 제한적이 되어버리고… 꽁수를 사용하자니 안 먹히는 경우가 너무 많고…

어쨌거나 다른 해결 방법이 없다면 둘 중 하나를 사용해야 한다. 두 가지 중에서 본인이 많이 사용하는 방법은 꽁수를 사용하는 방법이다. 여기서 말하는 꽁수란 원하는 결과를 얻을 수 있는 외부 프로세스를 실행시키고 그 결과를 받아내어 필요한 부분만 얻어내는 방법을 사용하는 것이다. 이번 기사에서는 윈도우 XP 운영체제의 시스템 비밀스런(?) 정보를 얻어내는 자바 프로그램을 만들어 보도록 하자.

※ 주의: 본 소스의 모든 내용은 윈도우 XP 프로페셔널에서만 동작한다. 윈도우 XP 홈에디션에는 시스템 정보를 얻어내는 프로그램(systeminfo.exe)이 지원되지 않는다.

일단 화면에 도스창을 하나 띄워보자. 그런 후, "systeminfo"라고 입력하면 자신이 사용하는 윈도우 시스템에 대한 여러 정보가 나타난다. 윈도우 XP 프로페셔널에 이런 프로그램이 있다는 사실은 본인도 이 프로그램을 작성하면서 처음 알게 된 것이다. 자세한 세부 사항은 "systeminfo /?"라고 입력하여 도움말을 참고하도록 하자.

화면에 보이는 결과를 살펴보면 의외로 많은 사실들을 알 수 있다. 운영체제의 자세한 버전이나 사용자 정보, 실제 메모리 정보, 운영체제에 적용된 패치 등등… 이제부터는 이 정보들을 이용하여 자신이 원하는 몇 가지만을 보여주는 간단한 프로그램을 만들어보자.

이 프로그램의 핵심은 자바 프로그램 내에서 외부 프로그램을 실행시키고 그 결과를 받아내는 것이다. 이미 알고 있는 사람들에게는 아주 쉬운 일이지만 한번도 사용해보지 않았다면 이번 기회에 익혀두도록 하자. 나중에 두고 두고 써먹을 수 있는 프로그램 기법이 될 것이다(실제로 필자도 위기가 닥칠 때마다 이용해서 아주 유용하게 사용하고 있다). 아래 자바 메소드는 실행할 외부 프로그램의 이름을 스트링으로 지정하고 그 프로그램을 실행 후에 표준 출력과 표준 에러를 받아 내는 것이 전부이다.

public void run() {
Runtime runtime = Runtime.getRuntime();
Process process = null;

try {
// this.command = "systeminfo.exe";
process = runtime.exec(this.command); // 외부 프로그램 실행
} catch (IOException ioe) {
ioe.printStackTrace();
}

// 표준 출력
InputStream standardOutput = process.getInputStream();
// 표준 에러
InputStream standardError = process.getErrorStream();

InputStreamReader ir = new InputStreamReader(standardOutput);
InputStreamReader ow = new InputStreamReader(standardError);

BufferedReader outReader = new BufferedReader(ir);
BufferedReader errorReader = new BufferedReader(ow);

StringBuffer stdout = new StringBuffer();
StringBuffer stderr = new StringBuffer();
String line = null;
try {
// 루프를 돌면서 퓨준 출력과 표준 에러를 계속 받아낸다
while ( (line = outReader.readLine()) != null) {
stdout.append(line).append("\n");
}
while ( (line = errorReader.readLine()) != null) {
stderr.append(line).append("\n");
}
standardOutput.close();
standardError.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
result.setStdout(stdout.toString()); // 이 결과를 나중에 사용한다
result.setStderr(stderr.toString());
}

위의 코드 마지막 부분에 나중에 사용할 결과를 지정하는 부분이 있다. 그 결과를 이용해서 원하는 정보만 가려내는 코드는 다음과 같다.

String result = pRunner.result.getStdout();
StringTokenizer st = new StringTokenizer(result, "\n");
while (st.hasMoreElements()) {
String line = (String)st.nextElement();
if (line.startsWith("호스트 이름")) {
addSysInfo(line);
}
if (line.startsWith("OS 이름")) {
addSysInfo(line);
}
if (line.startsWith("등록된 소유자")) {
addSysInfo(line);
}
if (line.startsWith("Product ID")) {
addSysInfo(line);
}
if (line.startsWith("System Up Time")) {
addSysInfo(line);
}
}

원하는 정보를 모두 얻었다면 이제 GUI로 아름답게 보여주는 일만 남았다. 이 부분에서는 여러 분들이 직접 원하는 형태대로 만들어보기 바란다.
<출처:ibm.com/developerworks/kr>

+ Recent posts