Get PID of Runtime process using JNI

2019-08-13 18:51发布

I need to get the PID of a process which is launched via Java's Runtime.getRuntime().exec() command.

I know how to do it in JNA. But I really would like to do it with JNI and create my own libraries. Does anyone know how to do it?

import java.lang.reflect.Field;

class GetPid
{
    public native int getPid( long procHandle);

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

    public static void main(String args[])
    {
        try {

          Process process = Runtime.getRuntime().exec( "calc");
          Field f = process.getClass().getDeclaredField( "handle");
          f.setAccessible( true);
          long procHandle = f.getLong( process);

          System.out.println( "prochandle: " + procHandle + ", pid: " + new GetPid().getPid( procHandle));

        } catch( Exception e) {
          e.printStackTrace();
        }

    }
}

But what's the C part supposed to look like?

JNIEXPORT jint JNICALL
Java_GetPid_getPid(JNIEnv *env, jobject obj, jlong handle)
{
    ...

    return ???;
}

It would be great if someone could help me. I mainly seek the Windows solution, since you can get the PID for Linux from the Process field, but I wouldn't mind if someone could show me how to do this in Linux / Solaris as well.

Thank you very much in advance!

标签: java runtime pid
2条回答
神经病院院长
2楼-- · 2019-08-13 19:36

I found this page that might be useful - http://golesny.de/p/code/javagetpid. It gives code for extracting an external processes PID on various platforms ... in a couple of ways.

In summary:

  • You can use RuntimeMXBean to list all running processes, and then use pattern matching to pick out one that matches the name of the process whose PID you are trying to find. (But the gotcha is that process names are not unique ...)

  • On Linux / UNIX you can fish the PID out of the XxxProcess object using reflection.

  • On Windows you have to use JNA to get the PID. Some code to do this is on the linked page.


If I was doing this, I think I'd take a different approach. I'd see if it was possible to get the external command (or a wrapper / launcher) to figured out what the PID is, and then write it somewhere that the parent JVM can read it.

查看更多
beautiful°
3楼-- · 2019-08-13 19:52

Got it. It was as simple as using:

#define WINVER 0x0501
#define _WIN32_WINNT 0x0501

and

JNIEXPORT jint JNICALL
Java_GetPid_getPid(JNIEnv *env, jobject obj, jlong handle)
{
  return GetProcessId((HANDLE) handle);
}

Thanks to all who tried to help :-)

查看更多
登录 后发表回答