- Windows registry and java
- Working with Windows registry using java.util.prefs.Preferences
- 2 Answers 2
- Dmitry Soloviev
- Поиск
- Site about programming in Java, its features and surprises with examples of coding.
- Чтение / запись в реестр Windows с использованием Java
- 24 ответа
- Reading the Windows Registry from Java without JNI
- Operation
- Caveats
Windows registry and java
Самый простой способ работы в языке java с реестром windows — это с помощью внешних программ, которые уже встроены в данную операционную систему. Сегодня мы будем использовать командную строку и программу reg. Код программы, вносящей изменения в реестр:
Пара комментариев по тексту программы. Здесь используются три метода: readWinReg (чтение реестра), addWinReg (добавление значения), delWinReg (удаление значения). В основном методе (void main) последовательно выполняется запись-чтение-удаление-чтение. Для примера я выбрал путь в реестре, в котором хранятся значения от компании Intel, раздел Audio. Мы записываем в этот раздел поле с названием «name» и значением «value». Тип REG_SZ — обыкновенная строка в кодировке Unicode. Если все в порядке, то сначала программа выведет что-то типа этого:
AudioDriverPresent REG_BINARY 01
name REG_SZ value
AudioDriverPresent REG_BINARY 01
и закончит работу.
Вот так несложно можно работать с реестром windows на Java. Если у вас остались вопросы или есть какие-либо комментарии, а также требуется написать практическую работу на java, решить задачу на данном языке или необходима программа, то смело пишите на почту up777up@yandex.ru — я с удовольствием помогу вам. За небольшую плату.
Автор этого материала — я — Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML — то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.
статьи IT, java, реестр
Working with Windows registry using java.util.prefs.Preferences
I have some questions about the registry.
We have
it will return true.
After it:
We see that it has one child: «Windows». But
returns false. Why?
UPDATE
Ok. I have some mistakes. Let me try again: Why does
2 Answers 2
If you execute the code lines shown, in the order shown, when you get to the line
p does not anymore point to the user root, but to «/HKEY_CURRENT_USER/Software/Policies».
Btw you have a probable omission in your third code sample:
I stumbled on this one today. The answer you’ve accepted is completely wrong.
You seem to be under the impression that Java Preferences is a general tool to manipulate the Windows Registry. It is not. It just so happens that the default implementation of Preferences on the Windows platform happens to store its data in the Windows Registry.
The implementation on Windows stores stuff under the following Registry paths:
For systemRoot: HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Prefs
For userRoot : HKEY_CURRENT_USER\Software\JavaSoft\Prefs
(note: The registry paths changes a bit if you are using a 32bit JRE on a 64-bit OS but that has nothing to do with Java and everything to do with Windows. Sun’s code always use the above paths.)
The point to make is that you can maybe use Java Preferences interface to read or change values in the Windows Registry but only below the above registry paths. The reason why I say ‘maybe’ is that this is just how it happens to be at the moment. Sun/Oracle could at any point in time decide to not to use the Windows Registry or use the Windows Registry but without using sub-nodes, i.e. store everything in one big XML string or something. The point is that Java Preferences is designed to shield you from this.
A lot of Java software that use the Java Preferences provide their own implementation (which is pretty simple to do) to avoid Sun’s default implementation that uses the Windows Registry. Not everyone can write to the Windows Registry these days so that was a pretty bad design decision on Sun’s part. Fortunately very easy to change.
Dmitry Soloviev
Поиск
Site about programming in Java, its features and surprises with examples of coding.
Если программа на Java контактирует со средой Windows, то иногда приходиться пользоваться данными хранящимися в реестре Windows. Существует несколько способов обратиться к ресурсам из этого хранилища. Например, можно воспользоваться обёрткой высокого уровня WinRegistryWrapper.java. но мне не понравилось это решение тем, что при работе в русском Windows (в конкретном моем приложении) стала происходить путаница с кодовыми страницами. Ещё есть способ с использованием методов библиотеки deploy, которая входит к тому же в Java SDK, но сама библиотека оказалась очень большой по размеру, что неприлично увеличило размер итогового jar-файла приложения. Поэтому я решил пойти другим путём — воспользоваться обращением к API Windows через Java JNA (Java Native Access). К тому-же, к библиотеке jna так или иначе приходится обращаться, если java-приложение позиционируется в основном под Windows.
В этой заметке я предлагаю на рассмотрение примеры обращения к API Windows (работа будет происходить с библиотекой user32.dll). А именно — чтение и запись строковых значений по ключу реестра Windows. Это реализовано с помощью методов getStrRegKey(WinReg.HKEY rootKey, String regKey, String keyName) и putStrRegKey(WinReg.HKEY rootKey, String regKey, String keyName, String strValue). Для работы методов необходимо подключить две библиотеки: jna-4.2.1.jar, jna-platform-4.2.1.jar.
Аргумент rootKey представляет собой один из корневых разделов реестра, например — WinReg.HKEY_CURRENT_USER.
Примечание: на момент написания заметки версия JNA — 4.2.1.
Чтение / запись в реестр Windows с использованием Java
Как можно читать/записывать в реестр Windows с помощью java?
24 ответа
Я знаю, что этот вопрос старый, но это первый результат поиска в google для «java read/write to registry». Недавно я нашел этот удивительный фрагмент кода, который:
- Может читать/писать в ЛЮБОЙ части реестра.
- НЕ ИСПОЛЬЗУЕТ JNI.
- НЕ ИСПОЛЬЗУЕТ ЛЮБЫЕ 3-Й ПАРТИИ/ВНЕШНИЕ ПРИЛОЖЕНИЯ ДЛЯ РАБОТЫ.
- НЕ ИСПОЛЬЗУЕТ WINDOWS API (напрямую)
Это чистый, Java-код.
Он использует отражение для работы, фактически получая доступ к частным методам в классе java.util.prefs.Preferences. Внутренности этого класса сложны, но сам класс очень прост в использовании.
Например, следующий код получает точное распределение окон из реестра:
Вот оригинальный класс. Просто скопируйте его, и он должен работать:
Мне не удалось найти и отдать должное оригинальному автору этого кода. Если вы найдете какие-либо подробности, добавьте комментарий, и я добавлю его здесь.
Вам действительно не нужен сторонний пакет. У Windows есть утилита reg для всех операций реестра. Чтобы получить формат команды, перейдите в прокси файл DOS и введите:
Вы можете вызвать reg через класс Runtime:
Редактирование клавиш и добавление новых можно выполнить с помощью команды выше. Чтобы прочитать реестр, вам нужно получить результирующий выход, и это немного сложно. Здесь код:
Java Native Access (JNA) — отличный проект для работы с родными библиотеками и поддерживает реестр Windows в платформе library (platform.jar) через Advapi32Util и Advapi32.
Обновление:. Вот фрагмент с некоторыми примерами того, как легко использовать JNA для работы с реестром Windows с помощью JNA 3.4.1,
Я сделал это, прежде чем использовать jRegistryKey. Это LGPL Java/JNI-библиотека, которая может делать то, что вам нужно. Вот пример того, как я использовал его для включения редактирования реестра через regedit, а также опции «Показать параметры папки» для себя в Windows через реестр.
Я увеличил чистый код Java, первоначально опубликованный Дэвидом, чтобы разрешить 32-разрядную секцию реестра с 64-разрядной JVM и наоборот. Я не думаю, что любые другие ответы касаются этого.
Да, используя API java.util.Preferences, поскольку его реализация использует реестр в качестве бэкэнд.
В конце концов, это зависит от того, что вы хотите сделать: сохранение предпочтений для вашего приложения — это то, что настройки действительно великолепны. Если вы хотите на самом деле изменить ключи реестра, не связанные с вашим приложением, вам понадобится приложение JNI, как описано Марк (бесстыдный кражи здесь):
Из быстрого google: Проверьте WinPack для JNIWrapper. Он имеет полную поддержку доступа к реестру Windows, включая чтение и запись.
В WinPack Demo реализовано средство просмотра реестра.
Существует также возможность вызова внешнего приложения, которое отвечает за чтение/запись реестра.
Из быстрого google:
Проверьте WinPack для JNIWrapper. Это имеет полный доступ к реестру Windows включая чтение и письмо.
У WinPack Demo есть средство просмотра реестра реализованный в качестве примера.
Существует также возможность вызова внешнего приложения, которое отвечает за чтение/запись реестра.
Здесь представлена модифицированная версия решения Олега. Я заметил, что в моей системе (Windows Server 2003) вывод «reg query» не разделяется вкладками (‘\ t’), а на 4 пробела.
Я также упростил решение, поскольку нить не требуется.
Благодаря оригинальному сообщению. Я обновил этот класс утилиты и воспользовался недостатками, которые были у него ранее, подумал, что это может помочь другим, поэтому размещайте здесь. Я также добавил некоторые дополнительные утилиты. Теперь он может читать любой файл в реестре Windows (включая REG_DWORD, REG_BINARY, REG_EXPAND_SZ и т.д.). Все методы работают как шарм. Просто скопируйте и вставьте его, и он должен работать. Вот отредактированный и измененный класс:
Пример использования методов:
Ниже метод извлекает значение ключа из заданного пути:
String hex = WinRegistry.valueForKey(WinRegistry.HKEY_LOCAL_MACHINE, «SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WindowsUpdate\\Auto Update», «AUOptions»);
Этот метод извлекает все данные для указанного пути (в виде ключей и значений):
Map map = WinRegistry.valuesForPath(WinRegistry.HKEY_LOCAL_MACHINE, «SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WSMAN»);
Этот метод извлекает значение рекурсивно для ключа из заданного пути:
String val = WinRegistry.valueForKeyPath(WinRegistry.HKEY_LOCAL_MACHINE, «System», «TypeID»);
и он извлекает все значения рекурсивно для ключа из заданного пути:
List list = WinRegistry.valuesForKeyPath( WinRegistry.HKEY_LOCAL_MACHINE, //HKEY «SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall», //path «DisplayName» //Key );
Здесь, в приведенном выше коде, я получил все установленные имена программ в системе Windows.
Примечание. См. документацию по этим методам
И этот извлекает все подразделы данного пути:
List list3 = WinRegistry.subKeysForPath(WinRegistry.HKEY_CURRENT_USER, «Software»);
Важное примечание. В этом процессе я изменил только методы чтения цели, а не методы написания, такие как createKey, deleteKey и т.д. Они все равно такие же, как я их получил.
Reading the Windows Registry from Java without JNI
Here is a class that allows you to read the Windows Registry without having to install any JNI library. It is implemented purely using introspection and will therefore compile and run on any platform. It would be possible to extend this to also write to the registry, but I didn’t need this functionality. I hesistate to call this «pure Java» as it does make native calls, but it does avoid the need for external dependencies to do so.
Operation
I forget who first pointed this out to me, but the java.util.prefs.WindowsPreferences implementation contains handy native methods to read and write any registry key, not just those under Software\Java\Prefs. By evil use of introspection, one can force these to be accessible and use them to read the registry without needing to install a new JNI library.
Figuring out which methods are needed and how to use them is a simple matter of tracing the getSpi() method in WindowsPreferences. From there, one can use the Method.setAccessible() method to bypass JVM security checks and execute them through introspection.
I have not implemented the write methods as I had no need for them, but they should be equally easy to do.
Caveats
Of course, this approach is pure evil*: breaking encapsulation and accessing private members is morally objectionable and liable to break under future versions. For my purposes, the requirement was not mission-critical. It works well enough and there will be no ill-effects if it fails in the future. On non-Windows platforms, or if the WindowsPreferences implementation changes, a BackingStoreException will be thrown.
However, if registry access is critical to your application, try something like JNIRegistry instead.