Support Wikipedia Follow My Heart: How to get Process Id in Windows?

2011年10月4日星期二

How to get Process Id in Windows?

For users, using WMIC.exe can easily solve the problem.

i.e. launch CMD.exe, then type in following sentence:

WMIC PROCESS get name,commandline,Processid


then press enter.
Now you can see three kinds of information for each running process:
  1. process caption (i.e. "notepad.exe"), 
  2. commandline (i.e. "C:\Windows\System32\notepad.exe"),
  3. process id (i.e. 1740)


You can also output the result into file by using the "/output" option.
You can type "WMIC /?" for help.

Also you can refer to this post or this post for more information.


For Java programmers, you can use JNA to do it. Otherwise you need to use native method to invoke local dll libraries.

The corresponding os-level method to get ProcessId in JNA is already wrapped in Kernel32.class.

What you need to do is just using the following code to do so. 

(import jna.jar
(import platform.jar)

private int getWindowsProcessId(Process proc) {
if (proc.getClass().getName().equals("java.lang.Win32Process")
|| proc.getClass().getName().equals("java.lang.ProcessImpl")) {
/* determine the pid on windows plattforms */
try {
Field f = proc.getClass().getDeclaredField("handle");
f.setAccessible(true);
long handl = f.getLong(proc);
Kernel32 kernel = Kernel32.INSTANCE;
                                        // be careful! If you use 3.3.0 version of JNA, you wil not found W32API.HANDLE. In stead, you should use WinNT.HANDLE 
W32API.HANDLE handle = new W32API.HANDLE(); 
                                // be careful for the security issue.
                                        // sometimes you need to open the rewrite lock and then invoke setPointer function.. For example, if you use 3.3.0 version of JNA, you need to reflect WinNT.HANDLE.immutable, which is a boolean variable. Set it to false before you setPointer
handle.setPointer(Pointer.createConstant(handl));
return kernel.GetProcessId(handle);
 
} catch (Throwable e) {
_log.error(e.getMessage());
}
}
return 0;
}


By the way, both jna.jar and platform.jar are released by JNA project. 
But jna.jar contains all mapping and specification, while platform.jar includes specific implementation. 
So if you do not want to import platform.jar, you need to write the following code by yourself.

Thanks to "Timothy Wall" who published the following code on internet as example.

/* Copyright (c) 2007 Timothy Wall, All Rights Reserved
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.

* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.  
*/
public interface W32Errors {
   int NO_ERROR               = 0;
   int ERROR_INVALID_FUNCTION = 1;
   int ERROR_FILE_NOT_FOUND   = 2;
   int ERROR_PATH_NOT_FOUND   = 3;
}


public interface Kernel32 extends W32API {
Kernel32 INSTANCE = (Kernel32) Native.loadLibrary("kernel32",
Kernel32.class, DEFAULT_OPTIONS);
/* http://msdn.microsoft.com/en-us/library/ms683179(VS.85).aspx */
HANDLE GetCurrentProcess();
/* http://msdn.microsoft.com/en-us/library/ms683215.aspx */
int GetProcessId(HANDLE Process);
int GetCurrentProcessId();
}

/** Base type for most W32 API libraries.  Provides standard options
 * for unicode/ASCII mappings.  Set the system property w32.ascii
 * to true to default to the ASCII mappings.
 */
public interface W32API extends StdCallLibrary, W32Errors {
 
    /** Standard options to use the unicode version of a w32 API. */
    Map UNICODE_OPTIONS = new HashMap() {
        /**
*
*/
private static final long serialVersionUID = 1L;
{
            put(OPTION_TYPE_MAPPER, W32APITypeMapper.UNICODE);
            put(OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.UNICODE);
        }
    };
 
    /** Standard options to use the ASCII/MBCS version of a w32 API. */
    Map ASCII_OPTIONS = new HashMap() {
        /**
*
*/
private static final long serialVersionUID = 1L;
{
            put(OPTION_TYPE_MAPPER, W32APITypeMapper.ASCII);
            put(OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.ASCII);
        }
    };
    Map DEFAULT_OPTIONS = Boolean.getBoolean("w32.ascii") ? ASCII_OPTIONS : UNICODE_OPTIONS;
 
    public class HANDLE extends PointerType {
        public Object fromNative(Object nativeValue, FromNativeContext context) {
            Object o = super.fromNative(nativeValue, context);
            if (INVALID_HANDLE_VALUE.equals(o))
                return INVALID_HANDLE_VALUE;
            return o;
        }
    }
    /** Constant value representing an invalid HANDLE. */
    HANDLE INVALID_HANDLE_VALUE = new HANDLE() {
        { super.setPointer(Pointer.createConstant(-1)); }
        public void setPointer(Pointer p) {
            throw new UnsupportedOperationException("Immutable reference");
        }
    };
}







没有评论:

发表评论