Java JNA: PROCESSENTRY32.szExeFile returns "???? ..." when converting to a Java string

I am new to JNA, and trying to port my first program to all processes on Windows, I ran into some problems. For some reason, I get the following output:

[pid = 0, name = ???????? ]
[pid = 4, name = ???????? ]
[pid = 364, name = ???????? ]
[pid = 516, name = ????e??? ]
[pid = 648, name = ?????e?? ]
[pid = 668, name = ????ee?? ]
[pid = 708, name = ???????? ]
[pid = 732, name = ????e??? ]
[pid = 740, name = ???ee??? ]
[pid = 796, name = ???????? ]
[pid = 880, name = ?????e?? ]
...

The process IDs were valid and are currently being executed on my system during the snapshot, but for some reason the lines were corrupted. Several other similar examples in StackOverflow gave me the same result. Do I need to specify something new in the latest version of JNA in order to make such a procedure work?

    public class Processes 
    {
        private static final Kernel32 kernel = ( Kernel32 )Native.loadLibrary( Kernel32.class );

        public static ArrayList<Process> getSnapshot( ) throws LastErrorException
        {
            ArrayList<Process> processes = new ArrayList<Process>( );
            HANDLE snapshot = null;

            try
            {
                snapshot = kernel.CreateToolhelp32Snapshot( Tlhelp32.TH32CS_SNAPPROCESS, new DWORD( 0 ) );
                PROCESSENTRY32 entry = new PROCESSENTRY32( );
                kernel.Process32First( snapshot, entry );

                do
                {
                    processes.add( new Process( Native.toString( entry.szExeFile ), entry.th32ProcessID.intValue() ) );
                }
                while( kernel.Process32Next( snapshot, entry ) );
            }
            finally
            {
                kernel.CloseHandle( snapshot );
            }

            return processes;
        }
    }

My code is very different from the MSDN example here .

+4
2

Native.loadLibrary, , JNA Process32FirstW (W32APIOptions.DEFAULT_OPTIONS ). , JNA kernel32.

Process32First, JNA platform.jar, unicode (-W) - PROCESSENTRY32, Java char . , , , "ANSI" Java char. Native.toString() , , .

+1

JNA Process32First\Next, ANSI, Unicode UTF-16LE Process32FirstW\NextW. , JNA, Unicode PROCESSENTRY32, TCHAR szExeFile UTF-16LE

Kernel32 :

Kernel32.java:

import com.sun.jna.Native;
import com.sun.jna.platform.win32.Tlhelp32;

public interface Kernel32 extends com.sun.jna.platform.win32.Kernel32 {
    Kernel32 INSTANCE = (Kernel32)Native.loadLibrary("kernel32", Kernel32.class, com.sun.jna.win32.W32APIOptions.DEFAULT_OPTIONS);

    boolean Process32FirstW(HANDLE hSnapshot, Tlhelp32.PROCESSENTRY32 lppe);
    boolean Process32NextW(HANDLE hSnapshot, Tlhelp32.PROCESSENTRY32 lppe);

}

Processes.java :

try
{
    snapshot = kernel.CreateToolhelp32Snapshot( Tlhelp32.TH32CS_SNAPPROCESS, new DWORD( 0 ) );
    PROCESSENTRY32 entry = new PROCESSENTRY32( );
    kernel.Process32FirstW( snapshot, entry );

    do
    {
        processes.add( new Process( Native.toString(entry.szExeFile ), entry.th32ProcessID.intValue() ) );
    }
    while( kernel.Process32NextW( snapshot, entry ) );
}
finally
{
    kernel.CloseHandle( snapshot );
}


ANSI:

import java.util.ArrayList;

import com.sun.jna.LastErrorException;
import com.sun.jna.Native;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.Tlhelp32;
import com.sun.jna.platform.win32.Tlhelp32.PROCESSENTRY32;
import com.sun.jna.platform.win32.WinDef.DWORD;
import com.sun.jna.platform.win32.WinNT.HANDLE;



public class Processes 
    {
        private static final Kernel32 kernel = ( Kernel32 )Native.loadLibrary( Kernel32.class );

        static class Process{
            public String pName;
            public int pID;
            Process(String pName,int pID){
                this.pName = pName;
                this.pID = pID;
            }
        }

        public static ArrayList<Process> getSnapshot( ) throws LastErrorException
        {
            ArrayList<Process> processes = new ArrayList<Process>( );
            HANDLE snapshot = null;

            try
            {
                snapshot = kernel.CreateToolhelp32Snapshot( Tlhelp32.TH32CS_SNAPPROCESS, new DWORD( 0 ) );
                PROCESSENTRY32 entry = new PROCESSENTRY32( );
                kernel.Process32First( snapshot, entry );

                do
                {
                    byte[] bytes = new byte[entry.szExeFile.length*2];
                    for(int i=0;i<entry.szExeFile.length;i++) {
                       bytes[i*2+1] = (byte) (entry.szExeFile[i] >> 8);
                       bytes[i*2] = (byte) entry.szExeFile[i];
                    }
                    processes.add( new Process( Native.toString( bytes, "ANSI" ), entry.th32ProcessID.intValue() ) );
                }
                while( kernel.Process32Next( snapshot, entry ) );
            }
            finally
            {
                kernel.CloseHandle( snapshot );
            }

            return processes;
        }
    }

, char [] [], "ANSI".

byte[] bytes = new byte[entry.szExeFile.length*2];
for(int i=0;i<entry.szExeFile.length;i++) {
   bytes[i*2+1] = (byte) (entry.szExeFile[i] >> 8);
   bytes[i*2] = (byte) entry.szExeFile[i];
}
processes.add( new Process( Native.toString( bytes, "ANSI" ), entry.th32ProcessID.intValue() ) );

Main:

public static void main(String[] args) {

    ArrayList<Processes.Process> curProcesses = Processes.getSnapshot();
    for(Processes.Process curP : curProcesses){
        System.out.println(curP.pName + ":" + curP.pID);
    }
}

:

[ ]: 0
: 4
smss.exe: 248
csrss.exe: 444
csrss.exe: 532
wininit.exe: 540
services.exe: 588
lsass.exe: 596
... ..

+1

Source: https://habr.com/ru/post/1622409/


All Articles