Search code examples
javacmdjna

How find a certain process using JNA?


i´m working on a Java program. It has to run an app as administrator and, when that execution ends, do another things. In the beginning, i used

String cmd[] = new String [3];
cmd [0] = "cmd";
cmd [1] = "/C";
cmd [2] = "runas /user:..."
Process p = Runtime.getRuntime().exec(cmd);

but the problem was i cannot enter the password (i tried it, but i didn´t find solution). After, i used JNA to make it, like this:

boolean CreateProcessWithLogonW
    (WString lpUsername,
     WString lpDomain,
     WString lpPassword,
     int dwLogonFlags,
     WString lpApplicationName,
     WString lpCommandLine,
     int dwCreationFlags,
     Pointer lpEnvironment,
     WString lpCurrentDirectory,
     STARTUPINFO  lpStartupInfo,
     PROCESS_INFORMATION lpProcessInfo);

Here, the problem is how make to wait the execution of the program until this process ends (maybe, in JNA, there are forms to do this, but is too big and i don´t know how do it...)

I thought another way to do it, but i don´t know if it´s possible... Like this:

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));
    }
}

Whit this, i have the id and the name of the process. It would be possible find the name of the user that run this process?? If i succeed, i could be do it (the only process run as administrator would be this one)

Regards.


Solution

  • I solved it.

    public boolean jambo_loco (int pid)
    {
    
        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  
        {
            int i = 0;
    
            int size = processEntry.dwSize.intValue();
    
            while (kernel32.Process32Next(snapshot, processEntry) && i < size) 
            {             
                if (processEntry.th32ProcessID.intValue() == pid)
                    return true;
                i++;
            }
    
        }
        finally 
        {
            kernel32.CloseHandle(snapshot);
        }
        return false;
    }
    

    A loop, in other side, invoques many times this method when it returns true.

    Regards.