0

Looking for a way by using JNA to get a list of all currently running windows programs and their command lines. There are a few tutorials on this site (Get list of processes on Windows in a charset-safe way) which show how to get a list of running program names but I'm looking for the full command line. I've seen posts mention the use of Module32First functions to do this but I can't seem to find any documentation on how to use that through JNA. Any ideas?

EDIT:

I've currently tried the below from the aforementioned post. The idea is that we want an in-process way of iterating over all currently running processes on windows and get their command lines. We don't want to use 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);
    }

EDIT2:

looking at the windows api (http://msdn.microsoft.com/en-us/library/windows/desktop/ms684839(v=vs.85).aspx) it says the below. I'm trying to get that full path to the executable through JNA. I guess it's the Module32First function that JNA does not have support for not the MODULE32ENTRY structure.

szExeFile The name of the executable file for the process. To retrieve the full path to the executable file, call the Module32First function and check the szExePath member of the MODULEENTRY32 structure that is returned. However, if the calling process is a 32-bit process, you must call the QueryFullProcessImageName function to retrieve the full path of the executable file for a 64-bit process.

Community
  • 1
  • 1
Christopher Dancy
  • 656
  • 2
  • 10
  • 21

1 Answers1

0

What have you tried so far? The type mapping is straightforward, and JNA is designed to allow you to easily extend existing definitions to augment them.

// 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);
}
technomage
  • 9,861
  • 2
  • 26
  • 40