本文永久地址:https://my.oschina.net/bysu/blog/1519205
由于公司的网络必须使用代理才能访问外网,从注册表里面把自动更改上网策略(是否使用代理)的注册表项的值已经清空了,以为这样就万事大吉了,谁知道第二天上班,开电脑又不能访问外网了。于是第一时间去看代理是否被取消了,果然不出所料,一切被恢复原状了。估计是电脑里面的杀毒软件或者某个安全策略设置了,电脑重启就重置了上网的策略。由于不知道是哪里的问题,再加上权限问题,就算找到估计也无法更改,还好现在还有注册表可以动,那么就从注册表入手吧~
先把获取注册表的java代码铺出来吧~
下面代码转自:https://stackoverflow.com/questions/62289/read-write-to-windows-registry-using-java
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.ArrayList;
import java.util.List;
import java.util.prefs.Preferences;
public class GetRegeditValue{
public static final int HKEY_CURRENT_USER = 0x80000001;
public static final int HKEY_LOCAL_MACHINE = 0x80000002;
public static final int REG_SUCCESS = 0;
public static final int REG_NOTFOUND = 2;
public static final int REG_ACCESSDENIED = 5;
private static final int KEY_ALL_ACCESS = 0xf003f;
private static final int KEY_READ = 0x20019;
private static final Preferences userRoot = Preferences.userRoot();
private static final Preferences systemRoot = Preferences.systemRoot();
private static final Class<? extends Preferences> userClass = userRoot.getClass();
private static final Method regOpenKey;
private static final Method regCloseKey;
private static final Method regQueryValueEx;
private static final Method regEnumValue;
private static final Method regQueryInfoKey;
private static final Method regEnumKeyEx;
private static final Method regCreateKeyEx;
private static final Method regSetValueEx;
private static final Method regDeleteKey;
private static final Method regDeleteValue;
static {
try {
regOpenKey = userClass.getDeclaredMethod("WindowsRegOpenKey",new Class[] { int.class, byte[].class, int.class });
regOpenKey.setAccessible(true);
regCloseKey = userClass.getDeclaredMethod("WindowsRegCloseKey",new Class[] { int.class });
regCloseKey.setAccessible(true);
regQueryValueEx = userClass.getDeclaredMethod("WindowsRegQueryValueEx",new Class[] { int.class, byte[].class });
regQueryValueEx.setAccessible(true);
regEnumValue = userClass.getDeclaredMethod("WindowsRegEnumValue",new Class[] { int.class, int.class, int.class });
regEnumValue.setAccessible(true);
regQueryInfoKey = userClass.getDeclaredMethod("WindowsRegQueryInfoKey1",new Class[] { int.class });
regQueryInfoKey.setAccessible(true);
regEnumKeyEx = userClass.getDeclaredMethod("WindowsRegEnumKeyEx", new Class[] { int.class, int.class,int.class });
regEnumKeyEx.setAccessible(true);
regCreateKeyEx = userClass.getDeclaredMethod("WindowsRegCreateKeyEx", new Class[] { int.class,byte[].class });
regCreateKeyEx.setAccessible(true);
regSetValueEx = userClass.getDeclaredMethod("WindowsRegSetValueEx", new Class[] { int.class,byte[].class, byte[].class });
regSetValueEx.setAccessible(true);
regDeleteValue = userClass.getDeclaredMethod("WindowsRegDeleteValue", new Class[] { int.class,byte[].class });
regDeleteValue.setAccessible(true);
regDeleteKey = userClass.getDeclaredMethod("WindowsRegDeleteKey", new Class[] { int.class,byte[].class });
regDeleteKey.setAccessible(true);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
private GetRegeditValue() { }
/**
* Read a value from key and value name
* @param hkey HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
* @param key
* @param valueName
* @return the value
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static String readString(int hkey, String key, String valueName)
throws IllegalArgumentException, IllegalAccessException,InvocationTargetException {
if (hkey == HKEY_LOCAL_MACHINE) {
return readString(systemRoot, hkey, key, valueName);
}
else if (hkey == HKEY_CURRENT_USER) {
return readString(userRoot, hkey, key, valueName);
}
else {
throw new IllegalArgumentException("hkey=" + hkey);
}
}
/**
*读取某个项的下一级子项
* Read value(s) and value name(s) form given key
* @param hkey HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
* @param key
* @return the value name(s) plus the value(s)
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static Map<String, String> readStringValues(int hkey, String key) throws IllegalArgumentException, IllegalAccessException,InvocationTargetException {
if (hkey == HKEY_LOCAL_MACHINE) {
return readStringValues(systemRoot, hkey, key);
}
else if (hkey == HKEY_CURRENT_USER) {
return readStringValues(userRoot, hkey, key);
}
else {
throw new IllegalArgumentException("hkey=" + hkey);
}
}
/**
* Read the value name(s) from a given key
* @param hkey HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
* @param key
* @return the value name(s)
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static List<String> readStringSubKeys(int hkey, String key) throws IllegalArgumentException, IllegalAccessException,InvocationTargetException {
if (hkey == HKEY_LOCAL_MACHINE) {
return readStringSubKeys(systemRoot, hkey, key);
}
else if (hkey == HKEY_CURRENT_USER) {
return readStringSubKeys(userRoot, hkey, key);
}
else {
throw new IllegalArgumentException("hkey=" + hkey);
}
}
/**
* Create a key
* @param hkey HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
* @param key
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static void createKey(int hkey, String key) throws IllegalArgumentException, IllegalAccessException,InvocationTargetException
{
int [] ret;
if (hkey == HKEY_LOCAL_MACHINE) {
ret = createKey(systemRoot, hkey, key);
regCloseKey.invoke(systemRoot, new Object[] { new Integer(ret[0]) });
}
else if (hkey == HKEY_CURRENT_USER) {
ret = createKey(userRoot, hkey, key);
regCloseKey.invoke(userRoot, new Object[] { new Integer(ret[0]) });
}
else {
throw new IllegalArgumentException("hkey=" + hkey);
}
if (ret[1] != REG_SUCCESS) {
throw new IllegalArgumentException("rc=" + ret[1] + " key=" + key);
}
}
/**给某项添加值
* Write a value in a given key/value name
* @param hkey
* @param key
* @param valueName
* @param value
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static void writeStringValue(int hkey, String key, String valueName, String value) throws IllegalArgumentException, IllegalAccessException,InvocationTargetException{
if (hkey == HKEY_LOCAL_MACHINE) {
writeStringValue(systemRoot, hkey, key, valueName, value);
}
else if (hkey == HKEY_CURRENT_USER) {
writeStringValue(userRoot, hkey, key, valueName, value);
}
else {
throw new IllegalArgumentException("hkey=" + hkey);
}
}
/**删除一个键
* Delete a given key
* @param hkey
* @param key
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static void deleteKey(int hkey, String key)
throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException
{
int rc = -1;
if (hkey == HKEY_LOCAL_MACHINE) {
rc = deleteKey(systemRoot, hkey, key);
}
else if (hkey == HKEY_CURRENT_USER) {
rc = deleteKey(userRoot, hkey, key);
}
if (rc != REG_SUCCESS) {
throw new IllegalArgumentException("rc=" + rc + " key=" + key);
}
}
/**删除一个键的值
* delete a value from a given key/value name
* @param hkey
* @param key
* @param value
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static void deleteValue(int hkey, String key, String value)
throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException
{
int rc = -1;
if (hkey == HKEY_LOCAL_MACHINE) {
rc = deleteValue(systemRoot, hkey, key, value);
}
else if (hkey == HKEY_CURRENT_USER) {
rc = deleteValue(userRoot, hkey, key, value);
}
if (rc != REG_SUCCESS) {
throw new IllegalArgumentException("rc=" + rc + " key=" + key + " value=" + value);
}
}
// =====================
private static int deleteValue
(Preferences root, int hkey, String key, String value)
throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException
{
int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {
new Integer(hkey), toCstr(key), new Integer(KEY_ALL_ACCESS) });
if (handles[1] != REG_SUCCESS) {
return handles[1]; // can be REG_NOTFOUND, REG_ACCESSDENIED
}
int rc =((Integer) regDeleteValue.invoke(root,
new Object[] {
new Integer(handles[0]), toCstr(value)
})).intValue();
regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
return rc;
}
private static int deleteKey(Preferences root, int hkey, String key)
throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException
{
int rc =((Integer) regDeleteKey.invoke(root,
new Object[] { new Integer(hkey), toCstr(key) })).intValue();
return rc; // can REG_NOTFOUND, REG_ACCESSDENIED, REG_SUCCESS
}
private static String readString(Preferences root, int hkey, String key, String value)
throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException
{
int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {
new Integer(hkey), toCstr(key), new Integer(KEY_READ) });
if (handles[1] != REG_SUCCESS) {
return null;
}
byte[] valb = (byte[]) regQueryValueEx.invoke(root, new Object[] {
new Integer(handles[0]), toCstr(value) });
regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
return (valb != null ? new String(valb).trim() : null);
}
private static Map<String,String> readStringValues(Preferences root, int hkey, String key)throws IllegalArgumentException, IllegalAccessException,InvocationTargetException {
HashMap<String, String> results = new HashMap<String,String>();
int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {
new Integer(hkey), toCstr(key), new Integer(KEY_READ) });
if (handles[1] != REG_SUCCESS) {
return null;
}
int[] info = (int[]) regQueryInfoKey.invoke(root,new Object[] { new Integer(handles[0]) });
int count = info[0]; // count
int maxlen = info[3]; // value length max
for(int index=0; index<count; index++) {
byte[] name = (byte[]) regEnumValue.invoke(root, new Object[] {
new Integer(handles[0]), new Integer(index), new Integer(maxlen + 1)});
String value = readString(hkey, key, new String(name));
results.put(new String(name).trim(), value);
}
regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
return results;
}
//获取某项下一级所有的子项名字
private static List<String> readStringSubKeys(Preferences root, int hkey, String key)throws IllegalArgumentException, IllegalAccessException,InvocationTargetException {
List<String> results = new ArrayList<String>();
int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {
new Integer(hkey), toCstr(key), new Integer(KEY_READ)});
if (handles[1] != REG_SUCCESS) {
return null;
}
int[] info = (int[]) regQueryInfoKey.invoke(root,new Object[] { new Integer(handles[0])});
int count = info[0]; // Fix: info[2] was being used here with wrong results. Suggested by davenpcj, confirmed by Petrucio
int maxlen = info[3]; // value length max
for(int index=0; index<count; index++) {
byte[] name = (byte[]) regEnumKeyEx.invoke(root, new Object[] {
new Integer(handles[0]), new Integer(index), new Integer(maxlen + 1)});
results.add(new String(name).trim());
}
regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
return results;
}
private static int [] createKey(Preferences root, int hkey, String key)throws IllegalArgumentException, IllegalAccessException,InvocationTargetException {
return (int[]) regCreateKeyEx.invoke(root,
new Object[] { new Integer(hkey), toCstr(key) });
}
private static void writeStringValue(Preferences root, int hkey, String key, String valueName, String value) throws IllegalArgumentException, IllegalAccessException,InvocationTargetException{
int[] handles = (int[])regOpenKey.invoke(root, new Object[] {
new Integer(hkey), toCstr(key), new Integer(KEY_ALL_ACCESS) });
regSetValueEx.invoke(root,new Object[] {
new Integer(handles[0]), toCstr(valueName), toCstr(value)});
regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
}
// utility
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;
}
}
根据我对注册表的观察,注册表中各项跟IE局域网(LAN)设置中的各项对应如下图
简略说明如下:
AutoConfigProxy:为空时,那么就不勾选;
AutoConfigURL:为空或者不存在时,不勾选;
ProxyEnable:值为1是勾选;
ProxyServer:值为代理服务器的ip和端口,譬如:10.10.10.10::8080
ProxyOverride:值为<local>时为勾选。
那么知道了以上这些,通过上面的代码,更改对应的值即可.
我的代码如下
TestGetRegeditvalue.java
import java.lang.reflect.InvocationTargetException;
/**
* @author 苏宝伢 E-mail:by.su@qq.com
* @version 创建时间: 2017年8月15日 上午10:24:45
*/
public class TestGetRegeditValue{
public static void main(String[] args)throws IllegalAccessException,InvocationTargetException{
String[] values = {"AutoConfigProxy","AutoConfigURL","ProxyEnable","ProxyServer","ProxyOverride"};
String value = "";
for(String str:values){
switch(str){
case "AutoConfigProxy":
value = GetRegeditValue.readString(GetRegeditValue.HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",str);
if(value != ""&&value != null){
GetRegeditValue.deleteValue(GetRegeditValue.HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",str);
System.out.println("delete successful");
}
break;
case "AutoConfigURL":
value = GetRegeditValue.readString(GetRegeditValue.HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",str);
if(value != ""&&value != null){
GetRegeditValue.deleteValue(GetRegeditValue.HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",str);
System.out.println("delete successful");
}
break;
case "ProxyEnable":
value = GetRegeditValue.readString(GetRegeditValue.HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",str);
System.out.println("ProxyEnable: " + value);
if(value!=null){
if(!value.equals("1")){
//GetRegeditValue.deleteValue(GetRegeditValue.HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",str);
GetRegeditValue.writeStringValue(GetRegeditValue.HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",str,"1");
System.out.println("change successful");
}
}else{
GetRegeditValue.writeStringValue(GetRegeditValue.HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",str,"1");
System.out.println("change successful");
}
break;
case "ProxyServer":
value = GetRegeditValue.readString(GetRegeditValue.HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",str);
System.out.println("ProxyServer: " + value);
if(value != null){
if(!value.equals("10.17.1xx.11:8080")){
//GetRegeditValue.deleteValue(GetRegeditValue.HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",str);
GetRegeditValue.writeStringValue(GetRegeditValue.HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",str,"10.17.1xx.11:8080");
System.out.println("change successful");
}
}else{
GetRegeditValue.writeStringValue(GetRegeditValue.HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",str,"10.17.1xx.11:8080");
System.out.println("change successful");
}
break;
case "ProxyOverride":
value = GetRegeditValue.readString(GetRegeditValue.HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",str);
System.out.println("ProxyOverride: " + value);
if(value != null){
if(!value.equals("<local>")){
//GetRegeditValue.deleteValue(GetRegeditValue.HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",str);
GetRegeditValue.writeStringValue(GetRegeditValue.HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",str,"<local>");
System.out.println("change successful");
}
}else{
GetRegeditValue.writeStringValue(GetRegeditValue.HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",str,"<local>");
System.out.println("change successful");
}
break;
}
}
System.out.println("修改完毕~!");
}
}
---------------更新时间:2017年9月4日15:54:23---------------------------
以上看似很完美,至少当时搞完以为能达到自己需要想要的目的,但是随后很沮丧地发现,通过java操作注册表是成功了,但是需要手动逐步打开代理设置的窗口,修改注册表才生效。去请教那些资深网管,除了让我装一个代理软件,也别无他法。
于是只能先放下,直至今天,意外发现直接导入注册表方式修改网络代理值则可以直接生效。既然这样,那就好办了。先把已经设置了网络代理的注册表相关项导出到本地(我这里命名为:proxy.reg),然后待网络被某软件还原回去之后,执行上面的java代码,接着通过批处理导入proxy.reg文件(这一步主要就是让修改后的网络代理生效)。所以上述执行java代码,导入注册表通过一个批处理就直接搞定了。批处理如下:
@echo off
:1
echo "进行代理替换"
cd "D:\bysu\WorkSpace\java\proxy\"
java TestGetRegeditValue
regedit /s "proxy.reg"
ping -n 600 127.0.0.1 >nul
goto 1
现在是10分钟自动执行一次,后续通过java代码判断AutoConfigURL的值来控制。