Intereting Posts
Существуют ли std :: fill, std :: copy для std :: vector ? Функция memcpy в эквиваленте от C ++ до Java Современный эквивалент BoundsChecker для Visual Studio 2008 C ++: динамическое распределение массива-члена структур с использованием конструктора, отличного от стандартного COM-сервер как служба Windows, не может передать массив как аргумент функции Настройка eclipse в OS X (C ++) ОШИБКА: запуск не выполнен, двоичные файлы не найдены? Почему я всегда получаю «завершение вызова после бросания экземпляра …» при метании моего деструктора? Невозможно понять различия в поиске имен между int и определенным пользователем типом – возможно, ADL union для uint32_t и uint8_t неопределенное поведение? Использование openssl для создания пары ключей DSA Полный захват и рендеринг всего экрана в DirectX Бенчмаркинг с использованием и переупорядочения команд Метод Const, который изменяет * это без const_cast QString для String и vica versa Как реализовать быстрый обратный sqrt без неопределенного поведения?

Что использовать вместо LPTSTR в java JNA?

Я добавляю методы User32Ext в JNI. В частности, я расширил исходный class UserExt:

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

Я хочу добавить функцию GetModuleFileNameEx .

Я бы написал это так:

 public abstract DWORD getModuleFileName(WinNT.HANDLE hProcess, WinNT.HMODULE hModule, WinNT.LPTSTR pathString, WinNT.DWORD pathStringLength); 

Но WinNT.LPTSTR не определен. По-видимому, это должен быть указатель (на мой взгляд?). Итак, как мне закончить это?

    Прежде всего, я сожалею о своем неправильном ответе за вас

    Итак, я проверил ваш код сразу после получения вашего вопроса. Я должен сделать свой собственный class для этой проблемы.

    Давайте посмотрим на прототип GetModuleFileName

     DWORD WINAPI GetModuleFileName( _In_opt_ HMODULE hModule, _Out_ LPTSTR lpFilename, _In_ DWORD nSize ); 

    Ваш прототип для GetModuleFileNameEx не для GetModuleFileName . ссылка на сайт

    Основная проблема, которую я пропустил, – это аргумент lpFilename, который должен быть объектом muttable.

    Это могут быть любые объекты muttable, такие как массив символов или массив байтов в виде prameter.

    Я думаю, что мы не можем использовать class String в качестве параметра, потому что это неизменный class.

    Я решил, что GetModuleFileName рекомендуется, чем GetModuleFileNameEx с сайта msdn.

    Вы можете найти в середине статьи, которую они говорят,

    Чтобы получить имя модуля в текущем процессе, используйте функцию GetModuleFileName. Это более эффективно и надежнее, чем вызов GetModuleFileNameEx с дескриптором текущего процесса

    Здесь есть два условия. Во-первых, моя ОС – Windows 7 Ultimate 64-bit Second, у вас и у меня отличная среда для разработчиков.

    Я загрузил последние jna.jar и jna-platform.jar с исходного сайта .

    Я протестировал четыре разных метода. Один из них потерпел неудачу.

    Моя точка входа следующая:

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

    Класс Function, Object как параметры и метод вызова classа Function необходимы для реализации одной и той же функции.

    Далее нужно найти идентификатор процесса для теста.

     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’

    Я должен больше узнать об этих ошибках в ближайшее время.

    Последний … Вот основной class прототипов

     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 System 280 smss.exe 444 csrss.exe 536 wininit.exe 544 csrss.exe 7860 chrome.exe 8132 chrome.exe 7808 chrome.exe 7516 chrome.exe 6176 chrome.exe 8156 chrome.exe 7120 chrome.exe 7476 chrome.exe 8016 chrome.exe 5616 devmonsrv.exe 1644 chrome.exe 6548 chrome.exe 5960 chrome.exe 5636 chrome.exe 8260 chrome.exe 3440 notepad.exe 8844 chrome.exe 9416 chrome.exe 6744 chrome.exe 6032 chrome.exe 9724 javaw.exe Free success allocPoint >>==> native@0x34d0000 allocPoint ==> native@0x34d0000 module path is C:\DEV\COMP\Java\jdk1.7\bin\javaw.exe module path is C.... <== The output is strange... Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function 'GetModuleFileNameEx': 

    Вам нужно использовать массив символов, чем массив байтов, избегая проблемы с кодировкой символов.

    Мои операторы импорта,

     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 и получил идентификатор процесса

    Затем я назвал этот метод.