Saturday, May 31, 2008

Access Windows Registry using 'pure' Java

(rehash of my old post since all those wonderful blog post drafts I was planning to publish are unfortunately out-dated or irrelevant)

One can use the private code of Sun's Preferences API to access values of type REG_SZ in the Windows Registry. Stupid hack. Maybe I should make a library out of this. I have used this soooo many times.

The java.util.prefs.WindowsPreferences is the concrete implementation of AbstractPreferences in the Windows platform. This class provides methods like WindowsRegQueryValueEx, etc. Using Reflection, one can use the methods in this class to query string values under HKEY_LOCAL_MACHINE and HKEY_CURRENT_USER


Given below is a code-snippet that demonstrates how to get the ProxyServer setting on Windows (this is what IE uses/sets) and the Internet Explorer version


import java.lang.reflect.Method;
import java.util.prefs.Preferences;

public class JavaRegistryHack {

private static final int HKEY_CURRENT_USER = 0x80000001;
private static final int KEY_QUERY_VALUE = 1;
private static final int KEY_SET_VALUE = 2;
private static final int KEY_READ = 0x20019;

public static void main(String args[]) {
final Preferences userRoot = Preferences.userRoot();
final Preferences systemRoot = Preferences.systemRoot();
final Class clz = userRoot.getClass();
try {
final Method openKey = clz.getDeclaredMethod("openKey",
byte[].class, int.class, int.class);
openKey.setAccessible(true);

final Method closeKey = clz.getDeclaredMethod("closeKey",
int.class);
closeKey.setAccessible(true);

final Method winRegQueryValue = clz.getDeclaredMethod(
"WindowsRegQueryValueEx", int.class, byte[].class);
winRegQueryValue.setAccessible(true);
final Method winRegEnumValue = clz.getDeclaredMethod(
"WindowsRegEnumValue1", int.class, int.class, int.class);
winRegEnumValue.setAccessible(true);
final Method winRegQueryInfo = clz.getDeclaredMethod(
"WindowsRegQueryInfoKey1", int.class);
winRegQueryInfo.setAccessible(true);


byte[] valb = null;
String vals = null;
String key = null;
Integer handle = -1;

//Query Internet Settings for Proxy
key = "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings";
handle = (Integer) openKey.invoke(userRoot, toCstr(key), KEY_READ, KEY_READ);
valb = (byte[]) winRegQueryValue.invoke(userRoot, handle.intValue(),
toCstr("ProxyServer"));
vals = (valb != null ? new String(valb).trim() : null);
System.out.println("Proxy Server = " + vals);
closeKey.invoke(Preferences.userRoot(), handle);

// Query for IE version
key = "SOFTWARE\\Microsoft\\Internet Explorer";
handle = (Integer) openKey.invoke(systemRoot, toCstr(key), KEY_READ, KEY_READ);
valb = (byte[]) winRegQueryValue.invoke(systemRoot, handle, toCstr("Version"));
vals = (valb != null ? new String(valb).trim() : null);
System.out.println("Internet Explorer Version = " + vals);
closeKey.invoke(Preferences.systemRoot(), handle);

} catch (Exception e) {
e.printStackTrace();
}
}


private static byte[] toCstr(String str) {
byte[] result = new byte[str.length() + 1];
for (int i = 0; i < str.length(); i++) {
result[i] = (byte) str.charAt(i);
}
result[str.length()] = 0;
return result;
}

33 comments:

Anonymous said...

Nice one

Anonymous said...

I've tried this method to read value from HKEY_LOCAL_MACHINE tree. To do that you need another method:
final Method openKey2 = clz.getDeclaredMethod("openKey", int.class, byte[].class, int.class, int.class);

and as first argument use:
final int HKEY_LOCAL_MACHINE = 0x80000002;

No problem reading Strings but I can't read DWORD values. Have you had any success with DWORDs?

Unknown said...

Hi , Very nice way to hack. I want to get the default mail client details from HKEYCLASSESROOT\mailto\shell\open\command, to invoke the mail client Kindly let me know if possible by mail , solution for above key

Anonymous said...

Is this code free to use in any app, does it require a credit?

Tarun Elankath said...

No credits required at all.

Mail client are possbile. dword's was done once..will check up confirm.

I am just not a blog writer..too lazy to respond to even comments. :(

Tarun Elankath said...

I'll post the snippets for the other requests tomorrow..

PLUS: If you are doing lost of win32 integration you should really look at jna.dev.java.net and com4j.dev.java.net. Those are the 'proper' solutions. This is just nothing but a stupid hack.

Anonymous said...

Hi tarun,
Good work here.

I have a question...

How can I get a list of subkeys under a key? For example in under HKLM\Software\JavaSoft, I would like to get the list of subkeys (Java Development Kit, Java Runtime Environment etc). Can
this be done using the library?
Thanks

Anonymous said...

This wont work for dwords for sure This method works only for strings.

Unknown said...

Hello!

Well my project (founded 30 november 2006) do the same like yours!

http://sourceforge.net/projects/java-registry/

Maybe next time search in sourceforge too, so you dont need to create a new solution for the same thing!

Best regards, Joerg

Anonymous said...

What is the way to load DWord Entrys?

madd gear said...

Impressive digging. I knew that the preferences API peered to the registry on windows, but I wasn't aware that you could use that capability to get access to arbitrary keys.
I have looked at jna.dev.java.net and com4j.dev.java.net.
So Thanks.... keep the work!!
Registry Easy

TECO Sodré said...

Is that possible to read windows registry via html page (or via applet) using your code?

Tariq Manj said...

Dear Friend, i have to get the installed path of OpenOffice from Windows registry on the run time. Can you plz help me out.My email id is tariq.javed@live.com.
Please help me, i couldn't understand that example code from ur bloget.

regards,
tariq from Sweden

GodSpeed said...

I am looking everywhere for code to make my java software run at windows startup... Can anyone here helps me please???

sham said...

@ above
Create Exe or jar for your Java application and add its location in to run of registry..

Here is another way to access registry from java

http://technobuz.com/2009/07/how-to-use-windows-api-in-java/

Anonymous said...

you have a nice site. thanks for sharing this site. there are various kinds of ebooks are available here

http://feboook.blogspot.com

Anonymous said...

hi i have a question...

How can I get a list of subkeys under a key? For example in under HKLM\Software\JavaSoft, I would like to get the list of subkeys..
Do you have any sample code for that? Its little urgent. Can anyone respond to this.

Tarun Elankath said...

Hi anonymous,

I'll try putting up the code tomorrow on this outdated blog. A bit busy at the moment.

But as I said, this stupid hack isn't really necessary at all with JNA. (https://jna.dev.java.net/)

Anonymous said...

Thanks for the response Tarun. I would like to uninstall a program that was installed with install shield. For that I need a ID which will be present under the HKLM\Software\Microsoft\WINDOWS\CurrentVersion\Uninstall. But i need to fetch the proper GUID from the uninstall keys list which has a display name of my Product. It would be really great if you can help us. But we are not supposed to use JNA for this. We are maintaining the code someone else had written.

Anonymous said...

Thanks for the response Tarun. I would like to uninstall a program that was installed with install shield. For that I need a ID which will be present under the HKLM\Software\Microsoft\WINDOWS\CurrentVersion\Uninstall. But i need to fetch the proper GUID from the uninstall keys list which has a display name of my Product. It would be really great if you can help us. But we are not supposed to use JNA for this. We are maintaining the code someone else had written. I know how to find the subkeys of a registry key..But Now what I want to know is how to get the keys list under Uninstall.

Anonymous said...

nice ..

how can i make a dynamic list of my current applications using registry.?

Tarun Elankath said...

@anonymous..not sure what you mean by current applications..do you mean the currenntly running processes on windows. I don't think you can do that without a Win32 API call to the functions in kernel32.dll (process32first, process32next). Or you can simply call tasklist.exe :)

Anonymous said...

Hi,
I need a way to find the installation path of one of the programs on my system, using java. That is, i should access the windows registry for this. How do I do this?

Tarun Elankath said...
This comment has been removed by the author.
Tarun Elankath said...

@anon: First determine the registry key path and the value name. Most software follow a scheme like
HKEY_LOCAL_MACHINE/Software/[SofwareProdutName]/.../[SoftwareProductVersion].

After you have figured this out, it should be easy..

GG said...
This comment has been removed by the author.
GG said...

Hi Tarun,
I am trying to access the subkeys under "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MountPoints2\\CPC\\Volume"
I assume winRegEnumValue is supposed to be invoked?
I am not able to figure out the function arguments and return type

Anonymous said...

can i make my own add or remove programs by accessing registry?

Tarun Elankath said...

@GG: The program clearly shows WindowsRegQueryValueEx being used. See the MSDN documentation if you need a clear idea of what this does.

Tarun Elankath said...

@anon: Not sure what you mean by "my own add or remove program", but if you meant an installer, then don't try to hack the registry - use a free install system such as the NullSoft install system http://nsis.sourceforge.net/Main_Page or the Microsoft MSI Installer

Slither said...

Nice

erectile dysfunction drug said...

I know this web page gives quality based articles and other data, is there any other web page which offers such stuff in quality?

erection pills viagra online said...

If you wish for to take a good deal from this post then you have to apply such strategies to your won webpage.