2013年2月27日 星期三

Python 修改 IE Proxy 設定

網路上怎麼找,都找到這種程式碼,但這些改法只是改『區域網路』的部份,並非我真正要的。

improt _winreg
key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER,r"Software\Microsoft\Windows\CurrentVersion\Internet Settings",0,_winreg.KEY_ALL_ACCESS)
_winreg.SetValueEx(key,"ProxyEnable",0, _winreg.REG_DWORD, 1) 
_winreg.SetValueEx(key,"ProxyServer",0, _winreg.REG_SZ, "proxy:port")

真的需要修改的位置應該位於
r"Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections"



再來得看adsl設定什麼名稱就修改那個檔案

但到這一步,就遇到了難題 登錄檔的 檔式 為 REG_BINARY 二進位檔
不像修改區域網路的部份為 REG_SZ 可以直接設定 實際 IP 數值
winreg.SetValueEx(key,"ProxyServer",0, winreg.REG_SZ, "proxy:port")

網路上也難以找到相關資料,或好用的修改方式、模組

只好認命一點,取出對應的值的替換掉

第一步,一樣先取所在位置的所有值:

key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER,r"Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections",0, _winreg.KEY_ALL_ACCESS)

再來查詢 adsl 名稱,取出value

adsl = _winreg.QueryValueEx(key, 'adsl')
返回tuple 值

選第一個

a = adsl[0]

我們所需要修改的部份 為第5個值跟第9個值,還有proxy ip 設定的第17個起,往後算20個位置





每個我們在 IE 裡設定,啟用proxy 或關閉proxy 第5個值都會自動加1
啟用proxy的話 第9個值 為3

瞭解原理後,要修改就不太難了

修改 REG_BINARY 二進位檔,我所能想到的方式就是轉 16進位來替換修改

所以導入 binascii 模組

import binascii


adsl_ascii = binascii.b2a_hex(a)


adsl_ascii 的內容,會是類似以下這樣:

'46000000010000000300000014000000
3231382e3138382e31332e3233373a383
838380000000000000000000000000000
000000000000000000000000000000000
000000000000000000000'

修改方式

adsl_ascii = adsl_ascii[:9] + '1' + adsl_ascii[10:17] + '3' + adsl_ascii[18:]

原本的第5跟第9,換算成16進位變 第10跟第18的位置
替換後轉回 二進位檔

adsl_binary = binascii.a2b_hex(adsl_ascii )

然後再修改註冊表
_winreg.SetValueEx(key, "adsl", 0, _winreg.REG_BINARY, adsl_binary) 

這樣 proxy 就啟用了,如要關閉就是用:

adsl_ascii = adsl_ascii[:9] + '0' + adsl_ascii[10:17] + '1' + adsl_ascii[18:]
adsl_binary = binascii.a2b_hex(adsl_ascii )
_winreg.SetValueEx(key, "adsl", 0, _winreg.REG_BINARY, adsl_binary) 

但因為proxy 的 ip 還未要設定所以,我們再添加修改ip的位置
# 啟用 Proxy
adsl_ascii = adsl_ascii[:9] + '1' + adsl_ascii[10:17] + '3' + adsl_ascii[18:]
# 設定 Proxy IP
adsl_ascii = adsl_ascii[32] + proxy_ip + i[72:]

但一般proxy IP 格式為 221.130.23.82:80
一樣得先轉成 16進位的格式再來做替換

所以簡單的寫個 轉換函數

def proxy2hex(proxy):
        proxy_hex = ''
        for i in proxy:
            proxy_hex += (hex(ord(i)))[2:]
        proxy_hex += '0' * (40 - len(proxy_hex))
        return proxy_hex

proxy_ip  = proxy2hex("221.130.23.82:80")
'3232312e3133302e32332e38323a383000000000'

 adsl_ascii = adsl_ascii[32] + proxy_ip + i[72:]
 adsl_binary = binascii.a2b_hex(adsl_ascii )
_winreg.SetValueEx(key, "adsl", 0, _winreg.REG_BINARY, adsl_binary) 
這樣就能啟用IE的proxy跟設定ip位置

如不想關掉ie再重開讓設定生效

def refresh(self):
        import ctypes
        INTERNET_OPTION_REFRESH = 37
        INTERNET_OPTION_SETTINGS_CHANGED = 39
        internet_set_option = ctypes.windll.Wininet.InternetSetOptionW
        internet_set_option(0, INTERNET_OPTION_REFRESH, 0, 0)
        internet_set_option(0, INTERNET_OPTION_SETTINGS_CHANGED, 0, 0)


如有更好的修改方式,請告知一下,修改REG_BINARY格式蠻麻煩的!!