0

寻找一种方法,通过使用 JNA 来获取所有当前正在运行的 Windows 程序及其命令行的列表。这个站点上有一些教程(Get list of processes on Windows in a charset-safe way)展示了如何获取正在运行的程序名称列表,但我正在寻找完整的命令行。我已经看到帖子提到使用 Module32First 函数来执行此操作,但我似乎找不到任何有关如何通过 JNA 使用它的文档。有任何想法吗?

编辑:

我目前已经从上述帖子中尝试了以下内容。这个想法是我们想要一种进程内的方式来迭代所有当前在 Windows 上运行的进程并获取它们的命令行。我们不想使用 wmic。

   Kernel32 kernel32 = (Kernel32) Native.loadLibrary(Kernel32.class, W32APIOptions.UNICODE_OPTIONS);
    Tlhelp32.PROCESSENTRY32.ByReference processEntry = new Tlhelp32.PROCESSENTRY32.ByReference();          

    WinNT.HANDLE snapshot = kernel32.CreateToolhelp32Snapshot(Tlhelp32.TH32CS_SNAPPROCESS, new WinDef.DWORD(0));
    try  {
        while (kernel32.Process32Next(snapshot, processEntry)) {             
            System.out.println(processEntry.th32ProcessID + "\t" + Native.toString(processEntry.szExeFile));
        }
    }
    finally {
        kernel32.CloseHandle(snapshot);
    }

编辑2:

查看 windows api ( http://msdn.microsoft.com/en-us/library/windows/desktop/ms684839(v=vs.85).aspx ) 它说如下。我正在尝试通过 JNA 获取可执行文件的完整路径。我猜这是 JNA 不支持的 Module32First 函数,而不是 MODULE32ENTRY 结构。

szExeFile 进程的可执行文件的名称。要检索可执行文件的完整路径,请调用 Module32First 函数并检查返回的 MODULEENTRY32 结构的 szExePath 成员。但是,如果调用进程是 32 位进程,则必须调用 QueryFullProcessImageName 函数来检索 64 位进程的可执行文件的完整路径。

4

1 回答 1

0

你试过什么了?类型映射很简单,JNA 旨在让您轻松扩展现有定义以扩充它们。

// Original C
typedef struct tagMODULEENTRY32 {
  DWORD   dwSize;
  DWORD   th32ModuleID;
  DWORD   th32ProcessID;
  DWORD   GlblcntUsage;
  DWORD   ProccntUsage;
  BYTE    *modBaseAddr;
  DWORD   modBaseSize;
  HMODULE hModule;
  TCHAR   szModule[MAX_MODULE_NAME32 + 1];
  TCHAR   szExePath[MAX_PATH];
} MODULEENTRY32, *PMODULEENTRY32;

// JNA equivalent (unicode version)
public interface MyKernel32 extends Kernel32 {
    class MODULEENTRY32 extends Structure {
        DWORD dwSize;
        DWORD th32ModuleID;
        DWORD th32ProcessID;
        DWORD GlblcntUsage;
        DWORD ProccntUsage;
        Pointer modBaseAddr;
        DWORD modBaseSize;
        HMODULE hModule;
        char[] szModule = new char[MAX_MODUE_NAME32+1];
        char[] szExePath = new char[MAX_PATH];
        public String szModule() { return Native.toString(this.szModule); }
        public String szExePath() { return Native.toString(this.szExePath); }
        protected List getFieldOrder() {
            return Arrays.asList(new String[] {
                "dwSize", "th32ModuleID", "th32ProcessID", "GlblcntUsage", "ProccntUsage", "modBaseAddr", "modBaseSize", "hModule", "szModule", "szExePath",
            });
        }
    }

    MyKernel32 INSTANCE = (MyKernel32)Native.loadLibrary("kernel32", W32DEFAULT_OPTIONS);
    boolean Module32First(HANDLE hSnapshot, MODULEENTRY32 lpme);
}
于 2013-05-05T13:01:23.240 回答