Java获取自身PID方法搜集

来源:互联网 发布:淘宝人本休闲鞋 编辑:程序博客网 时间:2024/05/21 06:42

http://blog.csdn.net/jsutluo/article/details/6860855



Java获取自身PID方法搜集: 其中如下方法在与SUN JDK兼容的虚拟机上是可以正常获取的。


第一种,来自:

http://rednaxelafx.iteye.com/blog/716918

Java标准库里常见的公有API确实是没有获取当前进程的ID的方法,有时候挺郁闷的,就是需要自己的PID。
于是有各种workaround,其中有很靠谱的通过JNI调用外部的C/C++扩展,然后调用操作系统提供的相应API去获取PID;也有些不怎么靠谱的hack。这里要介绍的就是后者之一,只在Sun JDK或兼容的JDK上有效的方法。

import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;

public class ShowOwnPID {
    public static void main(String[] args) throws Exception {
        int pid = getPid();
        System.out.println("pid: " + pid);
    //    System.in.read(); // block the program so that we can do some probing on it

     Thread.sleep(10000);

    }
    
    private static int getPid() {
        RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
        String name = runtime.getName(); // format: "pid@hostname"
        try {
            return Integer.parseInt(name.substring(0, name.indexOf('@')));
        } catch (Exception e) {
            return -1;
        }
    }
}


这PID是哪儿来的呢?先看RuntimeMXBean实例的来源,java.lang.management.ManagementFactory:  感兴趣的话,直接在http://rednaxelafx.iteye.com/blog/716918 查看吧。


第二种,未测试: http://tech.e800.com.cn/articles/2009/617/1245201766691_1.html

class JavaHowTo {
  public native long getCurrentProcessId();
  static {
    System.loadLibrary("jni2");
  }
}

public class JNIJavaHowTo {  public static void main(String[] args) {    JavaHowTo jht = new JavaHowTo();    System.out.println("Press Any key...");    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(jht.getCurrentProcessId());    }}
// jni2.cpp : Defines the entry point for the DLL application.//#include "stdafx.h"#include #include "JavaHowTo.h" BOOL APIENTRY DllMain( HANDLE hModule,                        DWORD  ul_reason_for_call,                        LPVOID lpReserved                     ){    return TRUE;}JNIEXPORT jlong JNICALL Java_JavaHowTo_getCurrentProcessId  (JNIEnv *, jobject) {     // return GetCurrentProcessId();    return getpid();}

第三种方法,http://momy.blogbus.com/logs/29634629.html


简单思路:先生成一个能够获取PID的脚本文件,然后执行。从执行的结果中找到进程名,根据进程名获得PID,然后根据PID杀掉进程。

import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class KillProcess {

    /**
     * @param args
     */
    public static void main(String[] args) {    
        try {
            killByAppName("notepad.exe");
        } catch (IOException e) {            
            e.printStackTrace();
        }
    }
  
    public static void killByAppName(String applicationName) throws IOException {
        String path = System.getProperty("user.dir");
        path = "C:\\";
        System.out.println(path);
        final File createFileName = new File(path + "\\scriptName.vbe");
        if (createFileName.exists()) {
            if (createFileName.delete()) {
            }
        } else {
            if (createFileName.createNewFile()) {
            }
        }
       
        final PrintWriter pw = new PrintWriter(new FileWriter(createFileName, true), true);
        pw.println("for each ps in getobject(\"winmgmts:\\\\.\\root\\cimv2:win32_process\").instances_");
        pw.println("wscript.echo ps.handle&vbtab&ps.name");
        pw.println("next");
        pw.close();
       
        final InputStream ii = Runtime.getRuntime().exec("cscript " + path + "\\scriptName.vbe").getInputStream();
       
        final InputStreamReader ir = new InputStreamReader(ii);
       
        final BufferedReader br = new BufferedReader(ir);
        String str = null;
        StringTokenizer st2 = null;
        String pid = null;

        while ((str = br.readLine()) != null) {
                    
            if (str.indexOf(applicationName) > 0) {
                st2 = new StringTokenizer(str);
                st2.hasMoreTokens();
                pid = st2.nextToken();
                System.out.println(pid);
               
                killByPID(pid);
            }
        }
        try {
            ir.close();
            ii.close();
            br.close();
            createFileName.delete();
        } catch (final IOException e) {
            e.printStackTrace();
        }
    }
   
    public static void killByPID(String pid) throws IOException {
        final String[] cmdArray = { "ntsd.exe", "-c", "q", "-p", pid };
        final String[] cmdArray1 = { "taskkill.exe", "/PID", pid, "/T", "/F" };
        int result = 0;
       
        try {
            Process process = Runtime.getRuntime().exec(cmdArray1);
            process.waitFor();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        if (result != 0) {
           
            try {
                Process process = Runtime.getRuntime().exec(cmdArray);
                process.waitFor();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }           

        }
    }
}


下面这个是英文blog上写的方法:http://blog.igorminar.com/2007/03/how-java-application-can-discover-its.html


How a Java Application Can Discover its Process ID (PID)

Occasionally it is important for an application to know its PID,specially if this application cooperates with other non-javaapplications. Currently there is no direct support for retrieving anapplication's process id by using standard Java api (this might changein the future if RFEs like 4250622, 4244896 or 4890847 are resolved).

I found five ways how to get the PID from my Java code:
  1. Using the java management and monitoring API (java.lang.management):
    ManagementFactory.getRuntimeMXBean().getName();
    returns something like:
    28906@localhost
    where 28906 is the PID of JVM's process, which is in fact the PID of my app.

    This hack is JVM dependent and I tested it only with Sun's JVM.

    From Javadocs for getName() method of RuntimeMXBean:
    Returns the name representing the running Java virtualmachine. The returned name string can be any arbitrary string and aJava virtual machine implementation can choose to embedplatform-specific useful information in the returned name string. Eachrunning virtual machine could have a different name.
    So even though this approach is the most comfortable one, your app can break if the implementation of this method changes.
  2. Using shell script in addition to Java propertiesStart your app with a shellscript like this:
    exec java -Dpid=$$ -jar /Applications/bsh-2.0b4.jar
    then in java code call:
    System.getProperty("pid");
  3. Using shell script's $! facility as described on this blog - this approach is fine if all you want is to create a pid file.
  4. Using Java Native Interface (JNI) - a very cumbersome and platform dependent solution.
  5. Using $PPID and Runtime.exec(String[]) method - described in detail inthis post
    import java.io.IOException;public class Pid {public static void main(String[] args) throws IOException {  byte[] bo = new byte[100];  String[] cmd = {"bash", "-c", "echo $PPID"};  Process p = Runtime.getRuntime().exec(cmd);  p.getInputStream().read(bo);  System.out.println(new String(bo));}}
It must be said that none of these approaches is perfect and each of them has some drawbacks.

I know that one of Sun's main priorities for Java is cross-platformcompatibility, but I have to agree with the comments on the RFEs abovewhich support the addition of a getPid() method to JDK. I especiallylike this one:
Come on Sun, this started 4.5 years ago. Give us the
PID. We need it. We want it. We demand it.
And another thing ... you will save a lot of developers a
lot of time currently spent searching through the
documentation trying to find a getPID method that isn't
there!
Posted by Rarb@GB on 05-MAR-2004

原创粉丝点击