我想念的重点是必须是可变对象的lpFilename参数.它可以是任何可变对象,例如字符数组或字节数组作为参数.我认为我们不能将String类用作参数,因为它是不可变类.我认为与从msdn 网站.您可以在他们说的文章中间找到 要在当前进程中检索模块的名称,请使用 GetModuleFileName函数.这样更有效,更可靠 而不是调用带有当前进程句柄的GetModuleFileNameEx这里有两个条件.首先,我的操作系统是Windows 7 Ultimate 64位其次,您和我拥有不同的开发人员环境.我从原始的网站.我测试了四种不同的方法.其中一种方法失败了.我的切入点如下public static void main(String[] args) { testCopyFile(); printProcesses(); testAllocFree(PROCESSID); testAllocFree2(PROCESSID); testModuleFileName(PROCESSID); testModuleFileName2(PROCESSID); } testCopyFile方法只是使用与您不同的方法来复制一些文本文件.private static void testCopyFile() { Function copyFunc = Function.getFunction("kernel32", "CopyFileA"); Object[] params = new Object[3]; params[0] = "C:\\DEV\\temp\\_info.txt"; params[1] = "C:\\DEV\\temp\\_info2.txt"; params[2] = false; copyFunc.invoke(params); }通过实现相同的功能,需要功能类,作为参数的对象和功能类的调用方法.下一个是找到测试的进程ID. private static void printProcesses() { Tlhelp32.PROCESSENTRY32.ByReference processEntry = new Tlhelp32.PROCESSENTRY32.ByReference(); HANDLE snapshot = Kernel32Me.INSTANCE.CreateToolhelp32Snapshot(Tlhelp32.TH32CS_SNAPPROCESS, new DWORD(0)); try { while (Kernel32Me.INSTANCE.Process32Next(snapshot, processEntry)) { System.out.println(processEntry.th32ProcessID + "\t" + Native.toString(processEntry.szExeFile)); } } finally { Kernel32Me.INSTANCE.CloseHandle(snapshot); } }只需选择屏幕上显示的其中之一即可.为了方便起见,我首先测试了两种具有通用功能的方法,即VirtualAllocEx和VirtualFreeEx.我测试成功了.以下两种不同的方法testAllocFree和testAllocFree2函数产生相同的输出.private static void testAllocFree(final int processId) { SIZE_T dwSize = new SIZE_T(1024); DWORD flAllocationType = new DWORD(Kernel32Me.MEM_RESERVE | Kernel32Me.MEM_COMMIT); DWORD flProtect = new DWORD(Kernel32Me.PAGE_READWRITE); Pointer allocPoint = null; boolean ret = false; DWORD options = new DWORD( Kernel32Me.PROCESS_VM_OPERATION | Kernel32Me.PROCESS_VM_WRITE | Kernel32Me.PROCESS_VM_READ | Kernel32Me.PROCESS_CREATE_THREAD | Kernel32Me.PROCESS_QUERY_INFORMATION); DWORD procs = new DWORD(processId); HANDLE hProcess = Kernel32Me.INSTANCE.OpenProcess(options, false, procs); if(null == hProcess) { System.err.println("Can't have a handle for you..sorry"); return; } try { allocPoint = Kernel32Me.INSTANCE.VirtualAllocEx(hProcess, null, dwSize, flAllocationType, flProtect); if(allocPoint==null) { System.err.println("Can't get a memory resource for you..sorry"); int c = Kernel32Me.INSTANCE.GetLastError(); System.out.println("\t>>" + c); //c = Native.getLastError(); //System.out.println("\t" + c); } if (allocPoint != null) { dwSize = new SIZE_T(0); DWORD freeType = new DWORD(Kernel32Me.MEM_RELEASE); System.err.println("allocPoint >>==> " + allocPoint.toString()); ret = Kernel32Me.INSTANCE.VirtualFreeEx(hProcess, allocPoint, dwSize, freeType); if(!ret) { int c = Kernel32Me.INSTANCE.GetLastError(); System.out.println("\t" + c); c = Native.getLastError(); System.out.println("\t" + c); } else { System.out.println("\t Free success"); } } } finally { Kernel32Me.INSTANCE.CloseHandle(hProcess); } }然后private static void testAllocFree2(final int processId) { Function allocFunc = Function.getFunction("kernel32", "VirtualAllocEx"); Function freeFunc = Function.getFunction("kernel32", "VirtualFreeEx"); DWORD flAllocationType = new DWORD(Kernel32Me.MEM_RESERVE | Kernel32Me.MEM_COMMIT); DWORD flProtect = new DWORD(Kernel32Me.PAGE_READWRITE); SIZE_T dwSize = new SIZE_T(1024); DWORD freeType = new DWORD(Kernel32Me.MEM_RELEASE); DWORD options = new DWORD( Kernel32Me.PROCESS_VM_OPERATION | Kernel32Me.PROCESS_VM_WRITE | Kernel32Me.PROCESS_VM_READ | Kernel32Me.PROCESS_CREATE_THREAD | Kernel32Me.PROCESS_QUERY_INFORMATION); DWORD procs = new DWORD(processId); Pointer allocPoint = null; HANDLE hProcess = Kernel32Me.INSTANCE.OpenProcess(options, false, procs); if(null == hProcess) { System.err.println("Can't have a handle for you..sorry"); return; } Object[] inArgs = new Object[5]; inArgs[0] = hProcess; inArgs[1] = null; inArgs[2] = dwSize; inArgs[3] = flAllocationType; inArgs[4] = flProtect; allocPoint = (Pointer) allocFunc.invoke(Pointer.class, inArgs); try { if(allocPoint==null) { System.err.println("Can't get a memory resource for you..sorry"); int c = Kernel32Me.INSTANCE.GetLastError(); System.out.println("\t>>" + c); //c = Native.getLastError(); //System.out.println("\t" + c); } if (allocPoint != null) { Object[] inArgs2 = new Object[4]; inArgs2[0] = hProcess; inArgs2[1] = allocPoint; inArgs2[2] = new SIZE_T(0); inArgs2[3] = freeType; System.err.println("allocPoint ==> " + allocPoint.toString()); freeFunc.invoke(inArgs2); } } finally { Kernel32Me.INSTANCE.CloseHandle(hProcess); } }最后,在下面测试了GetModuleFileName和GetModuleFileNameA函数private static void testModuleFileName(final int processId) { DWORD nSize = new DWORD(256); char lpFilename[] = new char[256]; byte bFilename[] = new byte[256]; String strFileName = new String(); DWORD options = new DWORD(Kernel32Me.PROCESS_VM_READ | Kernel32Me.PROCESS_QUERY_INFORMATION); DWORD procs = new DWORD(processId); HANDLE hProcess = Kernel32Me.INSTANCE.OpenProcess(options,false, procs); if(null == hProcess) { System.err.println("Can't have a handle for you..sorry"); return; } try { Kernel32Me.INSTANCE.GetModuleFileName(null, lpFilename, nSize); System.err.println("module path is " + new String(lpFilename)); Kernel32Me.INSTANCE.GetModuleFileName(null, bFilename, nSize); System.err.println("module path is " + new String(bFilename)); Kernel32Me.INSTANCE.GetModuleFileNameEx(hProcess, null, strFileName, nSize); System.err.println("module path is " + strFileName); } finally { Kernel32Me.INSTANCE.CloseHandle(hProcess); } }我有两个原型,一个是数组字节,另一个是代码中使用的字符数组.DWORD GetModuleFileName(HMODULE hModule, char[] lpFilename, DWORD nSize);DWORD GetModuleFileName(HMODULE hModule, byte[] lpFilename, DWORD nSize);第三个不起作用,就像我在开始时提到的那样,它告诉我UnsatisfiedLinkError.我不知道为什么.DWORD GetModuleFileNameEx(HANDLE hProcess, HMODULE hModule, String lpFilename, DWORD nSize);另一种实现方式也一样..看代码private static void testModuleFileName2(final int processId) { Function allocFunc = Function.getFunction("kernel32", "GetModuleFileName"); DWORD nSize = new DWORD(256); char[] lpFilename = new char[256]; DWORD procs = new DWORD(processId); DWORD options = new DWORD( Kernel32Me.PROCESS_VM_READ | Kernel32Me.PROCESS_QUERY_INFORMATION); HANDLE hProcess = Kernel32Me.INSTANCE.OpenProcess(options, false, procs); if(null == hProcess) { System.err.println("Can't have a handle for you..sorry"); return; } try { Object[] inArgs = new Object[3]; inArgs[0] = null; inArgs[1] = lpFilename; inArgs[2] = nSize; allocFunc.invoke(inArgs); System.err.println("module path is " + new String(lpFilename)); } finally { Kernel32Me.INSTANCE.CloseHandle(hProcess); } }我发现这两种方法最终都无法正常工作.Function allocFunc = Function.getFunction("kernel32", "GetModuleFileName");Function allocFunc = Function.getFunction("kernel32", "GetModuleFileNameEx");显示未找到的过程消息... java.lang.UnsatisfiedLinkError:查找功能出错 'GetModuleFileName'java.lang.UnsatisfiedLinkError:查找错误 函数'GetModuleFileNameEx'在不久的将来,我必须对这些错误进行更多的挖掘.最后一个...这里是主要的原型课public interface Kernel32Me extends StdCallLibrary { final Kernel32Me INSTANCE = (Kernel32Me) Native.loadLibrary("kernel32.dll", Kernel32Me.class, W32APIOptions.DEFAULT_OPTIONS); //https://msdn.microsoft.com/en-us/library/windows/desktop/aa366890(v=vs.85).aspx int PROCESS_CREATE_THREAD = 0x0002; int PAGE_EXECUTE_READWRITE = 0x40; int PROCESS_QUERY_INFORMATION = 0x0400; int PROCESS_VM_OPERATION = 0x0008; int PROCESS_VM_WRITE = 0x0020; int PROCESS_VM_READ = 0x0010; int PAGE_READWRITE = 0x04; int MEM_RESERVE = 0x00002000; int MEM_COMMIT = 0x00001000; int MEM_RESET = 0x00080000; int MEM_DECOMMIT = 0x4000; int MEM_RELEASE = 0x8000; Pointer VirtualAllocEx(HANDLE hProcess, Pointer lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect); boolean VirtualFreeEx(HANDLE hProcess, Pointer lpAddress, SIZE_T dwSize, DWORD dwFreeType); DWORD GetModuleFileName(HMODULE hModule, char[] lpFilename, DWORD nSize); DWORD GetModuleFileName(HMODULE hModule, byte[] lpFilename, DWORD nSize); DWORD GetModuleFileNameEx(HANDLE hProcess, HMODULE hModule, String lpFilename, DWORD nSize); HANDLE CreateToolhelp32Snapshot(DWORD dwFlags, DWORD th32ProcessID); boolean Process32First(HANDLE hSnapshot, PROCESSENTRY32 lppe); boolean Process32Next(HANDLE hSnapshot, PROCESSENTRY32 lppe); HANDLE OpenProcess(DWORD dwDesiredAccess, boolean bInheritHandle, DWORD dwProcessId); boolean CloseHandle(HANDLE hObject); int GetLastError(); }输出可能如下所示0 [System Process]4 System280 smss.exe444 csrss.exe536 wininit.exe544 csrss.exe7860 chrome.exe8132 chrome.exe7808 chrome.exe7516 chrome.exe6176 chrome.exe8156 chrome.exe7120 chrome.exe7476 chrome.exe8016 chrome.exe5616 devmonsrv.exe1644 chrome.exe6548 chrome.exe5960 chrome.exe5636 chrome.exe8260 chrome.exe3440 notepad.exe8844 chrome.exe9416 chrome.exe6744 chrome.exe6032 chrome.exe9724 javaw.exe Free successallocPoint >>==> native@0x34d0000allocPoint ==> native@0x34d0000module path is C:\DEV\COMP\Java\jdk1.7\bin\javaw.exemodule path is C.... <== The output is strange...Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function 'GetModuleFileNameEx':您需要使用char数组而不是字节数组,以避免字符编码问题.我的导入语句是import com.sun.jna.Function;import com.sun.jna.Native;import com.sun.jna.Pointer;import com.sun.jna.platform.win32.BaseTSD.SIZE_T;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.WinDef.HMODULE;import com.sun.jna.platform.win32.WinNT.HANDLE;import com.sun.jna.win32.StdCallLibrary;import com.sun.jna.win32.W32APIOptions;您可以依次使用以下方法. printProcesses(); testModuleFileName(PROCESSID);private static final int PROCESSID = 3440; // the process id from printProcesses(); public static void main(String[] args) { printProcesses(); testModuleFileName(PROCESSID); }希望这对您有帮助 PS最后,对于这个问题,我有自己的答案...可以使用Psapi界面完成...这是我的最终测试方法... private static void testModuleFileName2(final int processId) { DWORD nSize = new DWORD(260); char lpFilename[] = new char[260]; byte bFilename[] = new byte[260]; DWORD options = new DWORD(Kernel32Me.PROCESS_VM_READ | Kernel32Me.PROCESS_QUERY_INFORMATION); DWORD procs = new DWORD(processId); HANDLE hProcess = Kernel32Me.INSTANCE.OpenProcess(options, false, procs); if (null == hProcess) { System.err.println("Can't have a handle for you..sorry"); return; } HMODULE handle = Kernel32.INSTANCE.GetModuleHandle("kernel32.dll"); if (null == handle) { System.err.println("Can't have a handle for you..sorry"); return; } try { Kernel32Me.INSTANCE.GetModuleFileName(handle, lpFilename, nSize); System.err.println("2> module path is " + new String(lpFilename)); Psapi.INSTANCE.GetModuleFileNameExA(hProcess, handle, bFilename, 260); System.err.println("2> module path is " + new String(bFilename)); Psapi.INSTANCE.GetModuleFileNameExW(hProcess, null, lpFilename, 260); System.err.println("2> module path is " + new String(lpFilename)); } finally { Kernel32Me.INSTANCE.CloseHandle(hProcess); }}我打开了notepad.exe并获得了其进程ID然后,我调用了此方法.I am adding User32Ext methods to JNI. In particular, I extended the original UserExt class: package sirius.core; import com.sun.jna.Native; import com.sun.jna.Pointer; import com.sun.jna.platform.win32.Kernel32; import com.sun.jna.platform.win32.WinDef; import com.sun.jna.platform.win32.WinNT; import com.sun.jna.win32.W32APIOptions; public abstract interface Kernel32Ext extends Kernel32 { public static final Kernel32Ext INSTANCE = (Kernel32Ext)Native.loadLibrary("kernel32.dll", Kernel32Ext.class, W32APIOptions.DEFAULT_OPTIONS); public abstract Pointer VirtualAllocEx(WinNT.HANDLE paramHANDLE, Pointer paramPointer, int paramInt, WinDef.DWORD paramDWORD1, WinDef.DWORD paramDWORD2); public abstract boolean VirtualFreeEx(WinNT.HANDLE paramHANDLE, Pointer paramPointer, int paramInt, WinDef.DWORD paramDWORD); }I want to add the GetModuleFileNameEx function.I'd write it like this:public abstract DWORD getModuleFileName(WinNT.HANDLE hProcess, WinNT.HMODULE hModule, WinNT.LPTSTR pathString, WinNT.DWORD pathStringLength);But WinNT.LPTSTR is not defined. It's apparently supposed to be a pointer (to char I guess?). So, how do I finish this? 解决方案 First of all, I am sorry for my incorrect answer for youSo, I've tested your code right after receiving your question again.I have to make my own class for this issue.Let's look at the prototype of the GetModuleFileNameDWORD WINAPI GetModuleFileName( _In_opt_ HMODULE hModule, _Out_ LPTSTR lpFilename, _In_ DWORD nSize);Your prototype is for the GetModuleFileNameEx not for the GetModuleFileName. linkThe main point i missed is the lpFilename argument that must be muttable object.It can be any muttable objects like array of char or array of bytes as a prameter.I think we can not use the String class as a parameter because it's an immutable class.I figured that the GetModuleFileName is recommended than the GetModuleFileNameEx from the msdn site.You can find at the middle of the article they say, To retrieve the name of a module in the current process, use the GetModuleFileName function. This is more efficient and more reliable than calling GetModuleFileNameEx with a handle to the current processThere are two conditions here.First, My OS is Windows 7 Ultimate 64-bitSecond, you and i have a different developer environment.I downloaded the latest jna.jar and jna-platform.jar from the original site.I have tested four different methods..one of them is failed.My entry point is as followingpublic static void main(String[] args) { testCopyFile(); printProcesses(); testAllocFree(PROCESSID); testAllocFree2(PROCESSID); testModuleFileName(PROCESSID); testModuleFileName2(PROCESSID); }The testCopyFile method just copy some text file with a different approach to yours.private static void testCopyFile() { Function copyFunc = Function.getFunction("kernel32", "CopyFileA"); Object[] params = new Object[3]; params[0] = "C:\\DEV\\temp\\_info.txt"; params[1] = "C:\\DEV\\temp\\_info2.txt"; params[2] = false; copyFunc.invoke(params); }The Function class, Object as parameters and invoke method of the Function class are needed by implementing the same function.Next one is to find process id for the test. private static void printProcesses() { Tlhelp32.PROCESSENTRY32.ByReference processEntry = new Tlhelp32.PROCESSENTRY32.ByReference(); HANDLE snapshot = Kernel32Me.INSTANCE.CreateToolhelp32Snapshot(Tlhelp32.TH32CS_SNAPPROCESS, new DWORD(0)); try { while (Kernel32Me.INSTANCE.Process32Next(snapshot, processEntry)) { System.out.println(processEntry.th32ProcessID + "\t" + Native.toString(processEntry.szExeFile)); } } finally { Kernel32Me.INSTANCE.CloseHandle(snapshot); } }Just pick the one of them displayed on the screen.For convenient reason, I first tested two methods with common functions, VirtualAllocEx and VirtualFreeEx.I tested it successfully done..The following two different methods, testAllocFree and testAllocFree2 functions result the same output.private static void testAllocFree(final int processId) { SIZE_T dwSize = new SIZE_T(1024); DWORD flAllocationType = new DWORD(Kernel32Me.MEM_RESERVE | Kernel32Me.MEM_COMMIT); DWORD flProtect = new DWORD(Kernel32Me.PAGE_READWRITE); Pointer allocPoint = null; boolean ret = false; DWORD options = new DWORD( Kernel32Me.PROCESS_VM_OPERATION | Kernel32Me.PROCESS_VM_WRITE | Kernel32Me.PROCESS_VM_READ | Kernel32Me.PROCESS_CREATE_THREAD | Kernel32Me.PROCESS_QUERY_INFORMATION); DWORD procs = new DWORD(processId); HANDLE hProcess = Kernel32Me.INSTANCE.OpenProcess(options, false, procs); if(null == hProcess) { System.err.println("Can't have a handle for you..sorry"); return; } try { allocPoint = Kernel32Me.INSTANCE.VirtualAllocEx(hProcess, null, dwSize, flAllocationType, flProtect); if(allocPoint==null) { System.err.println("Can't get a memory resource for you..sorry"); int c = Kernel32Me.INSTANCE.GetLastError(); System.out.println("\t>>" + c); //c = Native.getLastError(); //System.out.println("\t" + c); } if (allocPoint != null) { dwSize = new SIZE_T(0); DWORD freeType = new DWORD(Kernel32Me.MEM_RELEASE); System.err.println("allocPoint >>==> " + allocPoint.toString()); ret = Kernel32Me.INSTANCE.VirtualFreeEx(hProcess, allocPoint, dwSize, freeType); if(!ret) { int c = Kernel32Me.INSTANCE.GetLastError(); System.out.println("\t" + c); c = Native.getLastError(); System.out.println("\t" + c); } else { System.out.println("\t Free success"); } } } finally { Kernel32Me.INSTANCE.CloseHandle(hProcess); } }And,private static void testAllocFree2(final int processId) { Function allocFunc = Function.getFunction("kernel32", "VirtualAllocEx"); Function freeFunc = Function.getFunction("kernel32", "VirtualFreeEx"); DWORD flAllocationType = new DWORD(Kernel32Me.MEM_RESERVE | Kernel32Me.MEM_COMMIT); DWORD flProtect = new DWORD(Kernel32Me.PAGE_READWRITE); SIZE_T dwSize = new SIZE_T(1024); DWORD freeType = new DWORD(Kernel32Me.MEM_RELEASE); DWORD options = new DWORD( Kernel32Me.PROCESS_VM_OPERATION | Kernel32Me.PROCESS_VM_WRITE | Kernel32Me.PROCESS_VM_READ | Kernel32Me.PROCESS_CREATE_THREAD | Kernel32Me.PROCESS_QUERY_INFORMATION); DWORD procs = new DWORD(processId); Pointer allocPoint = null; HANDLE hProcess = Kernel32Me.INSTANCE.OpenProcess(options, false, procs); if(null == hProcess) { System.err.println("Can't have a handle for you..sorry"); return; } Object[] inArgs = new Object[5]; inArgs[0] = hProcess; inArgs[1] = null; inArgs[2] = dwSize; inArgs[3] = flAllocationType; inArgs[4] = flProtect; allocPoint = (Pointer) allocFunc.invoke(Pointer.class, inArgs); try { if(allocPoint==null) { System.err.println("Can't get a memory resource for you..sorry"); int c = Kernel32Me.INSTANCE.GetLastError(); System.out.println("\t>>" + c); //c = Native.getLastError(); //System.out.println("\t" + c); } if (allocPoint != null) { Object[] inArgs2 = new Object[4]; inArgs2[0] = hProcess; inArgs2[1] = allocPoint; inArgs2[2] = new SIZE_T(0); inArgs2[3] = freeType; System.err.println("allocPoint ==> " + allocPoint.toString()); freeFunc.invoke(inArgs2); } } finally { Kernel32Me.INSTANCE.CloseHandle(hProcess); } }Finally, the GetModuleFileName and GetModuleFileNameA function tested belowprivate static void testModuleFileName(final int processId) { DWORD nSize = new DWORD(256); char lpFilename[] = new char[256]; byte bFilename[] = new byte[256]; String strFileName = new String(); DWORD options = new DWORD(Kernel32Me.PROCESS_VM_READ | Kernel32Me.PROCESS_QUERY_INFORMATION); DWORD procs = new DWORD(processId); HANDLE hProcess = Kernel32Me.INSTANCE.OpenProcess(options,false, procs); if(null == hProcess) { System.err.println("Can't have a handle for you..sorry"); return; } try { Kernel32Me.INSTANCE.GetModuleFileName(null, lpFilename, nSize); System.err.println("module path is " + new String(lpFilename)); Kernel32Me.INSTANCE.GetModuleFileName(null, bFilename, nSize); System.err.println("module path is " + new String(bFilename)); Kernel32Me.INSTANCE.GetModuleFileNameEx(hProcess, null, strFileName, nSize); System.err.println("module path is " + strFileName); } finally { Kernel32Me.INSTANCE.CloseHandle(hProcess); } }I have two prototypes, one is array bytes and another is array of chars used in the code.DWORD GetModuleFileName(HMODULE hModule, char[] lpFilename, DWORD nSize);DWORD GetModuleFileName(HMODULE hModule, byte[] lpFilename, DWORD nSize);The third one didn't working as i mentioned at the start which told me the UnsatisfiedLinkError..I don't know why..DWORD GetModuleFileNameEx(HANDLE hProcess, HMODULE hModule, String lpFilename, DWORD nSize);Another implementation is also the same..look at the codeprivate static void testModuleFileName2(final int processId) { Function allocFunc = Function.getFunction("kernel32", "GetModuleFileName"); DWORD nSize = new DWORD(256); char[] lpFilename = new char[256]; DWORD procs = new DWORD(processId); DWORD options = new DWORD( Kernel32Me.PROCESS_VM_READ | Kernel32Me.PROCESS_QUERY_INFORMATION); HANDLE hProcess = Kernel32Me.INSTANCE.OpenProcess(options, false, procs); if(null == hProcess) { System.err.println("Can't have a handle for you..sorry"); return; } try { Object[] inArgs = new Object[3]; inArgs[0] = null; inArgs[1] = lpFilename; inArgs[2] = nSize; allocFunc.invoke(inArgs); System.err.println("module path is " + new String(lpFilename)); } finally { Kernel32Me.INSTANCE.CloseHandle(hProcess); } }I found both methods not working finally.Function allocFunc = Function.getFunction("kernel32", "GetModuleFileName");Function allocFunc = Function.getFunction("kernel32", "GetModuleFileNameEx");show me the not found procedure message... java.lang.UnsatisfiedLinkError: Error looking up function 'GetModuleFileName' java.lang.UnsatisfiedLinkError: Error looking up function 'GetModuleFileNameEx'I have to dig it more about these errors at some time near future.Last one...Here is a main prototype classpublic interface Kernel32Me extends StdCallLibrary { final Kernel32Me INSTANCE = (Kernel32Me) Native.loadLibrary("kernel32.dll", Kernel32Me.class, W32APIOptions.DEFAULT_OPTIONS); //https://msdn.microsoft.com/en-us/library/windows/desktop/aa366890(v=vs.85).aspx int PROCESS_CREATE_THREAD = 0x0002; int PAGE_EXECUTE_READWRITE = 0x40; int PROCESS_QUERY_INFORMATION = 0x0400; int PROCESS_VM_OPERATION = 0x0008; int PROCESS_VM_WRITE = 0x0020; int PROCESS_VM_READ = 0x0010; int PAGE_READWRITE = 0x04; int MEM_RESERVE = 0x00002000; int MEM_COMMIT = 0x00001000; int MEM_RESET = 0x00080000; int MEM_DECOMMIT = 0x4000; int MEM_RELEASE = 0x8000; Pointer VirtualAllocEx(HANDLE hProcess, Pointer lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect); boolean VirtualFreeEx(HANDLE hProcess, Pointer lpAddress, SIZE_T dwSize, DWORD dwFreeType); DWORD GetModuleFileName(HMODULE hModule, char[] lpFilename, DWORD nSize); DWORD GetModuleFileName(HMODULE hModule, byte[] lpFilename, DWORD nSize); DWORD GetModuleFileNameEx(HANDLE hProcess, HMODULE hModule, String lpFilename, DWORD nSize); HANDLE CreateToolhelp32Snapshot(DWORD dwFlags, DWORD th32ProcessID); boolean Process32First(HANDLE hSnapshot, PROCESSENTRY32 lppe); boolean Process32Next(HANDLE hSnapshot, PROCESSENTRY32 lppe); HANDLE OpenProcess(DWORD dwDesiredAccess, boolean bInheritHandle, DWORD dwProcessId); boolean CloseHandle(HANDLE hObject); int GetLastError(); }The output might look like below0 [System Process]4 System280 smss.exe444 csrss.exe536 wininit.exe544 csrss.exe7860 chrome.exe8132 chrome.exe7808 chrome.exe7516 chrome.exe6176 chrome.exe8156 chrome.exe7120 chrome.exe7476 chrome.exe8016 chrome.exe5616 devmonsrv.exe1644 chrome.exe6548 chrome.exe5960 chrome.exe5636 chrome.exe8260 chrome.exe3440 notepad.exe8844 chrome.exe9416 chrome.exe6744 chrome.exe6032 chrome.exe9724 javaw.exe Free successallocPoint >>==> native@0x34d0000allocPoint ==> native@0x34d0000module path is C:\DEV\COMP\Java\jdk1.7\bin\javaw.exemodule path is C.... <== The output is strange...Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function 'GetModuleFileNameEx':You need to use array of char than array of byte avoiding character encoding problem.My import statements are,import com.sun.jna.Function;import com.sun.jna.Native;import com.sun.jna.Pointer;import com.sun.jna.platform.win32.BaseTSD.SIZE_T;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.WinDef.HMODULE;import com.sun.jna.platform.win32.WinNT.HANDLE;import com.sun.jna.win32.StdCallLibrary;import com.sun.jna.win32.W32APIOptions;You can use the methods below in turn. printProcesses(); testModuleFileName(PROCESSID);private static final int PROCESSID = 3440; // the process id from printProcesses(); public static void main(String[] args) { printProcesses(); testModuleFileName(PROCESSID); }I hope this may help youP.SFinally, I've got my own answer for this issue...It can be done with Psapi interface...Here is my final test method...private static void testModuleFileName2(final int processId) { DWORD nSize = new DWORD(260); char lpFilename[] = new char[260]; byte bFilename[] = new byte[260]; DWORD options = new DWORD(Kernel32Me.PROCESS_VM_READ | Kernel32Me.PROCESS_QUERY_INFORMATION); DWORD procs = new DWORD(processId); HANDLE hProcess = Kernel32Me.INSTANCE.OpenProcess(options, false, procs); if (null == hProcess) { System.err.println("Can't have a handle for you..sorry"); return; } HMODULE handle = Kernel32.INSTANCE.GetModuleHandle("kernel32.dll"); if (null == handle) { System.err.println("Can't have a handle for you..sorry"); return; } try { Kernel32Me.INSTANCE.GetModuleFileName(handle, lpFilename, nSize); System.err.println("2> module path is " + new String(lpFilename)); Psapi.INSTANCE.GetModuleFileNameExA(hProcess, handle, bFilename, 260); System.err.println("2> module path is " + new String(bFilename)); Psapi.INSTANCE.GetModuleFileNameExW(hProcess, null, lpFilename, 260); System.err.println("2> module path is " + new String(lpFilename)); } finally { Kernel32Me.INSTANCE.CloseHandle(hProcess); }}I opened a notepad.exe and got a its process idThen, I called this method. 这篇关于在Java JNA中使用什么代替LPTSTR?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
06-18 08:16