Java

[펌] JNI 를 이용한 PID( Process ID )추출( 윈도우 기반 )

_침묵_ 2006. 1. 25. 22:25

- Project : How I get PID from inside java( on windows flatform )?

- 작성자 김건호(http://www.devoop.com ,devstory@naver.com)

- 자료출처(http://www.rgagnon.com/javadetails/java-0467.html )

 

이번 시간에는 JNI 를 이용한 Process ID 추출 방법에 대해서 알아보겠습니다.

단, 윈도우 계열에서만 작동됩니다.

(유닉스 계열의 운영체제에서는 이 전 자료 "Get Process ID from inside Java?"를 참조해주세요.)

 

사실 강좌라고 할 것은 없고 그냥 따라해봅시다 -_-;;

따라하시다보면 JNI 가 어떻게 작성되고 이용되어지는지 조금은 감을 잡으실겁니다.

( 솔직히 저도 아무것도 몰라요 ㅎㅎㅎ )

 

1. 자바 파일 작성

class LoadDLL
{
 public native long getCurrentProcessId();

 static
 {
  System.loadLibrary("pid");
 }
}

 

2. 위에서 작성된 파일을 컴파일 한 후( Class 파일 생성 ) 헤더파일 작성

Command Line : "javah -jni LoadDLL"

EX> D:\java\jni\getpid>javah -jni LoadDLL

위처럼 실행하면 LoadDLL.h 파일이 생성됩니다.

 

3. DLL 파일 작성

 

3.1 Visual C++ 실행( 6.0 기준 )

 

3.2 New -> Projects -> Win32 Dynamic-Link Library ->
    Project name 은 "pid" -> An empty DLL project

 

3.3 New -> Files -> C/C++ Header File -> File 명 "stdafx"
    아래 내용 입력

 

// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently,
// but are changed infrequently

#if !defined(AFX_STDAFX_H__0DB7A8E3_2DCD_44D6_A515_ACA9AD4E8399__INCLUDED_)
#define AFX_STDAFX_H__0DB7A8E3_2DCD_44D6_A515_ACA9AD4E8399__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000


// Insert your headers here
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers

#include <windows.h>

// TODO: reference additional headers your program requires here

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_STDAFX_H__0DB7A8E3_2DCD_44D6_A515_ACA9AD4E8399__INCLUDED_)

 

3.4 New -> Files -> C++ Source File -> File 명 "pid"
    아래 내용 입력

 

#include "stdafx.h"
#include <process.h>
#include "loaddll.h"

BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
      )
{
    return TRUE;
}

/**
 * Java_( )_getCurrentProcessId
 * 위 괄호 부분은 아까 작성한 클래스명
 */
JNIEXPORT jlong JNICALL Java_LoadDLL_getCurrentProcessId
  (JNIEnv *, jobject) {

 return getpid();
}

 

3.5 Project -> setting -> 우측 프레임의 C/C++ -> Category ->
    Preprocessor -> Additional include directories 에
    2번에서 생성된 LoadDLL.h 파일의 저장 위치 및
    jni.h 와 jni_md.h 파일

    (jdk에서 제공하는 파일들로써 jdk 가 설치된 디렉토리의
      include, include\win32 에 위치
)

EX> d:\java\jni\getpid\,c:\j2sdk1.4.2_05\include\,c:\j2sdk1.4.2_05\include\win32\

 

3.6 Build 시켜서 DLL 파일을 생성 한 후 DLL 파일을 클래스가 위치한 곳으로 복사.
    ( DLL 파일은 방금 작업한 프로젝트가 저장된 경로의 Debug 부분에 있을 확률 높음 )

 

4. LoadDLL 자바 파일을 이용한 PID 추출용 자바 파일 작성

 

class PrintPID
{
 public static void main(String[] args)
 {
  LoadDLL ldll = new LoadDLL();

  System.out.println("Please check the PID at the task manager");
  System.out.println("Press any key to show PID");

  java.io.BufferedReader input =
   new java.io.BufferedReader(
   new java.io.InputStreamReader( System.in ) );

  try
  {
   input.readLine();
  }
  catch( Exception e )
  {
   e.printStackTrace();
  }

  System.out.println("PID : " + ldll.getCurrentProcessId() );
 }
}

 

5. 컴파일 후 실행

 

- 개행에 따른 코드가 이상하게 입력될 것을 염려하는바 제가 작성한 소스 파일들을

  첨부하오니 실행하시기 바랍니다. 확인 방법은 자바로 프로그램을 실행한 후

  작업관리자에서 자바의 PID 와 콘솔에서 나오는 PID 가 같으면 정상 출력이 되는겁니다.

 

- JNI 에 대한 자세한 강좌 링크

http://www.javastudy.co.kr/docs/jhan/javaadvance/jni.html