Я не совсем уверен, что вы можете достичь того, чего хотите, но я сделаю все возможное, чтобы ответить на ваши вопросы, чтобы приблизить вас к цели.
Есть два способа получить файлинформация: одна более общая для Java / JNA, а другая требует, чтобы вы смотрели внутри пространства памяти процесса.Я рассмотрю первый.
Вместо того, чтобы иметь дело с дескриптором окна, давайте получим ID процесса, который будет проще использовать позже.Это относительно просто:
IntByReference pidPtr = new IntByReference();
com.sun.jna.platform.win32.User32.INSTANCE.GetWindowThreadProcessId(hWnd, pidPtr);
int pid = pidPtr.getValue();
(Следует заметить, что у вас, вероятно, должен быть собственный интерфейс User32
, расширяющий приведенный выше, чтобы вы могли просто использовать один класс и не нужно полностью квалифицировать версию JNA, как ясделал.)
Теперь, вооружившись PID, есть несколько вариантов, чтобы попытаться получить путь.
Если вам повезло, и пользователь открылнапрямую (вместо «Файл»> «Открыть»), вы можете восстановить используемую ими командную строку, и он, скорее всего, будет иметь путь.Вы можете получить это из класса WMI Win32_Process
.Полный код вы можете найти в моем проекте OSHI в классе WindowsOperatingSystem или вы можете попробовать использовать Runtime.getRuntime().exec()
для использования версии WMI командной строки: wmic path Win32_Process where ProcessID=1234 get CommandLine
, получая результат в BufferedReader
(или см. OSHI'sExecutingCommand
класс для реализации.)
Если проверка командной строки не удалась, вы можете найти, какие файловые дескрипторы открыты этим процессом.Самый простой способ сделать это - загрузить утилиту Handle (но все ваши пользователи должны будут это сделать), а затем просто выполнить командную строку handle -p 1234
.В этом списке будут перечислены открытые файлы, хранящиеся в этом процессе.
Если вы не можете полагаться на то, что ваши пользователи загружают Handle, вы можете попробовать реализовать тот же код самостоятельно.Это недокументированный API, использующий NtQuerySystemInformation
.См. Проект JNA Issue 657 для примера кода, который будет повторять все дескрипторы операционной системы, позволяя вам просматривать файлы.Учитывая, что вы уже знаете PID, вы можете сократить итерацию после SYSTEM_HANDLE sh = info.Handles[i];
, пропустив оставшуюся часть кода, если sh.ProcessID
не соответствует вашему pid.Как указывалось в этом выпуске, указанный код является в основном неподдерживаемым и опасным .Нет гарантии, что он будет работать в будущих версиях Windows.
Наконец, вы можете увидеть, что вы можете сделать с памятью процесса.Вооружившись PID, вы можете открыть Process, чтобы получить дескриптор:
HANDLE pHandle = Kernel32.INSTANCE.OpenProcess(WinNT.PROCESS_QUERY_INFORMATION, false, pid);
Затем вы можете перечислить его модули с помощью EnumProcessModules ;для каждого модуля используйте GetModuleInformation , чтобы получить структуру MODULEINFO .Это дает вам указатель на память, которую вы можете исследовать к своему сердцу.Конечно, для точного знания того, с какими смещениями для поиска какой информации требуется API-интерфейс для исследуемого исполняемого файла (Word, WordPad и т. Д., И соответствующей версии). Вам также необходимы права администратора.Это исследование оставлено читателю в качестве упражнения.