Thinker

            - long way to go...

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            24 隨筆 :: 0 文章 :: 143 評論 :: 0 Trackbacks
          最近由于工作和學習需要在家里裝上了小區寬帶(80元/月),整個小區共享30M帶寬,開始以為會很慢,結果用起來速度還是挺不錯的。不說廢話了,言歸正傳,由于家里和公司的IP設置不一樣(都是靜態的),每次回家和去公司都需要手動改IP,改了幾天嫌麻煩就想寫個小程序可以自動設置IP,只需要雙擊一下程序就搞定IP設置。就上網搜了一下,大概有這么幾種方法:使用Windows的腳本(http://www.microsoft.com/china/technet/community/scriptcenter/topics/networking/default.mspx)或者編寫一個批處理使用netsh命令來完成這個任務,當然用C/C++也是絕對可以的。不過為了練習一下Python和想更多了解一下Python,所以就決定用Python來寫個自動設置IP的程序。參考文章:http://www.pconline.com.cn/pcedu/empolder/gj/vc/0508/694212.html
          代碼如下:
            1 # FileName: modify_ip.py
            2 # Author  : qujinlong
            3 # Email   : qujinlong123@gmail.com
            4 # Date    : 2007-06-20
            5 
            6 import _winreg
            7 
            8 from ctypes import *
            9 
           10 # MessageBox = windll.user32.MessageBoxA
           11 # MessageBox(0, 'Welcome!', 'Hello', 0)
           12 
           13 print '正在修改IP,請稍后'
           14 
           15 netCfgInstanceID = None
           16 
           17 hkey = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, \
           18                        r'System\CurrentControlSet\Control\Class\{4d36e972-e325-11ce-bfc1-08002be10318}')
           19 
           20 keyInfo = _winreg.QueryInfoKey(hkey)
           21 
           22 # 尋找網卡對應的適配器名稱 netCfgInstanceID
           23 for index in range(keyInfo[0]):
           24     hSubKeyName = _winreg.EnumKey(hkey, index)
           25     hSubKey = _winreg.OpenKey(hkey, hSubKeyName)
           26 
           27     try:
           28         hNdiInfKey = _winreg.OpenKey(hSubKey, r'Ndi\Interfaces')
           29         lowerRange = _winreg.QueryValueEx(hNdiInfKey, 'LowerRange')
           30 
           31         # 檢查是否是以太網
           32         if lowerRange[0] == 'ethernet':
           33             driverDesc = _winreg.QueryValueEx(hSubKey, 'DriverDesc')[0]
           34             # print 'DriverDesc: ', driverDesc
           35             netCfgInstanceID = _winreg.QueryValueEx(hSubKey, 'NetCfgInstanceID')[0]
           36             # print 'NetCfgInstanceID: ', netCfgInstanceID
           37             break
           38 
           39         _winreg.CloseKey(hNdiInfKey) # 關閉 RegKey
           40     except WindowsError:
           41         print r'Message: No Ndi\Interfaces Key'
           42 
           43     # 循環結束,目前只提供修改一個網卡IP的功能
           44     _winreg.CloseKey(hSubKey)
           45 
           46 _winreg.CloseKey(hkey)
           47 
           48 if netCfgInstanceID == None:
           49     print '修改IP失敗 - 沒有找到網絡適配器'    
           50     exit()
           51 
           52 # print netCfgInstanceID
           53 
           54 # 通過修改注冊表設置IP
           55 strKeyName = 'System\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\' + netCfgInstanceID
           56 
           57 # print strKeyName
           58 
           59 hkey = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, \
           60                        strKeyName, \
           61                        0, \
           62                        _winreg.KEY_WRITE)
           63 
           64 # 定義需要修改的IP地址、子網掩碼、默認網關和DNS等
           65 ipAddress = ['192.168.1.135']
           66 subnetMask = ['255.255.255.0']
           67 gateway = ['192.168.1.10']
           68 dnsServer = ['202.106.196.115''202.106.0.20']
           69 
           70 try:
           71     _winreg.SetValueEx(hkey, 'IPAddress', None, _winreg.REG_MULTI_SZ, ipAddress)
           72     _winreg.SetValueEx(hkey, 'SubnetMask', None, _winreg.REG_MULTI_SZ, subnetMask)
           73     _winreg.SetValueEx(hkey, 'DefaultGateway', None, _winreg.REG_MULTI_SZ, gateway)
           74     _winreg.SetValueEx(hkey, 'NameServer', None, _winreg.REG_SZ, ','.join(dnsServer))
           75 except WindowsError:
           76     print 'Set IP Error'
           77     exit()
           78 
           79 _winreg.CloseKey(hkey)
           80 
           81 # 調用DhcpNotifyConfigChange函數通知IP被修改
           82 DhcpNotifyConfigChange = windll.dhcpcsvc.DhcpNotifyConfigChange
           83 
           84 inet_addr = windll.Ws2_32.inet_addr
           85 
           86 # DhcpNotifyConfigChange 函數參數列表:
           87 # LPWSTR lpwszServerName,  本地機器為None
           88 # LPWSTR lpwszAdapterName, 網絡適配器名稱
           89 # BOOL bNewIpAddress,      True表示修改IP
           90 # DWORD dwIpIndex,         表示修改第幾個IP, 從0開始
           91 # DWORD dwIpAddress,       修改后的IP地址
           92 # DWORD dwSubNetMask,      修改后的子碼掩碼
           93 # int nDhcpAction          對DHCP的操作, 0 - 不修改, 1 - 啟用, 2 - 禁用
           94 DhcpNotifyConfigChange(None, \
           95                        netCfgInstanceID, \
           96                        True, \
           97                        0, \
           98                        inet_addr(ipAddress[0]), \
           99                        inet_addr(subnetMask[0]), \
          100                        0)
          101 
          102 print '修改IP結束'
          103 
          Python寫起來真是清爽啊,沒有一點拖泥帶水,沒有任何的指針、引用傳進傳出,也不用搞復雜的類型變來變去。
          代碼中用到了winreg模塊去讀取和修改Windows的注冊表,還用到了ctypes去鏈接DLL調用Windows API。
          至于程序所使用的修改IP的原理在參考文章中描述的很清楚,有什么問題可以mail我。
          程序以簡單起見,在修改IP的過程中一些例外情況并沒有處理,呵呵,只要自己能正常使用就行了:)
          等過兩天有時間寫個界面程序,可以設置和讀取IP配置,類似于Windows的網絡設置的UI界面。

          不喜歡上面代碼中有行號的朋友可以下載這個源程序:自動修改IP的Python程序

          改進性能從點滴做起:
          (1).由于Python中的字符串是不可變的,每次使用“+”號創建新字符串會拷貝原有的字符串構造新的字符串,降低性能,所以應避免使用“+”號構造字符串(類似于Java)。據此可將上面的一句代碼更改如下:
          strKeyName = r'System\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\%s' % netCfgInstanceID
          (2).待續...

          (2007-06-21增加)
          笨笨狗的提示,研究了一下在Python中使用WMI來實現這個功能,比上面的修改注冊表方法簡單的太多,而且比使用Windows的腳本也簡單了一點。先將新版本的代碼貼出來(其中使用了Tim Golden對WMI的包裝模塊,并且這個模塊使用了Python for Windows extensions(pywin32)):
           1 # -*- coding: cp936 -*-
           2 
           3 # FileName: modify_ip(wmi).py
           4 # Author  : qujinlong
           5 # Email   : qujinlong123@gmail.com
           6 # Date    : 2007-06-21
           7 
           8 import wmi
           9 
          10 print '正在修改IP,請稍后'
          11 
          12 wmiService = wmi.WMI()
          13 
          14 colNicConfigs = wmiService.Win32_NetworkAdapterConfiguration(IPEnabled = True)
          15 
          16 #for objNicConfig in colNicConfigs:
          17 #    print objNicConfig.Index
          18 #    print objNicConfig.SettingID
          19 #    print objNicConfig.Description
          20 #    print objNicConfig.IPAddress
          21 #    print objNicConfig.IPSubnet
          22 #    print objNicConfig.DefaultIPGateway
          23 #    print objNicConfig.DNSServerSearchOrder
          24 
          25 if len(colNicConfigs) < 1:
          26     print '沒有找到可用的網絡適配器'
          27     exit()
          28 
          29 # 獲取第一個網絡適配器的設置
          30 objNicConfig = colNicConfigs[0]
          31 
          32 #for method_name in objNicConfig.methods:
          33 #   method = getattr(objNicConfig, method_name)
          34 #   print method
          35 
          36 arrIPAddresses = ['192.168.1.136']
          37 arrSubnetMasks = ['255.255.0.0']
          38 arrDefaultGateways = ['192.168.1.1']
          39 arrGatewayCostMetrics = [1]
          40 arrDNSServers = ['192.168.1.3''202.106.46.151''202.106.0.20']
          41 intReboot = 0
          42 
          43 returnValue = objNicConfig.EnableStatic(IPAddress = arrIPAddresses, SubnetMask = arrSubnetMasks)
          44 if returnValue[0] == 0:
          45     print '  成功設置IP'
          46 elif returnValue[0] == 1:
          47     print '  成功設置IP'
          48     intReboot += 1
          49 else:
          50     print '修改IP失敗(IP設置發生錯誤)'
          51     exit()
          52 
          53 returnValue = objNicConfig.SetGateways(DefaultIPGateway = arrDefaultGateways, GatewayCostMetric = arrGatewayCostMetrics)
          54 if returnValue[0] == 0:
          55     print '  成功設置網關'
          56 elif returnValue[0] == 1:
          57     print '  成功設置網關'
          58     intReboot += 1
          59 else:
          60     print '修改IP失敗(網關設置發生錯誤)'
          61     exit()
          62 
          63 returnValue = objNicConfig.SetDNSServerSearchOrder(DNSServerSearchOrder = arrDNSServers)
          64 if returnValue[0] == 0:
          65     print '  成功設置DNS'
          66 elif returnValue[0] == 1:
          67     print '  成功設置DNS'
          68     intReboot += 1
          69 else:
          70     print '修改IP失敗(DNS設置發生錯誤)'
          71     exit()
          72 
          73 if intReboot > 0:
          74     print '需要重新啟動計算機'
          75 else:
          76     print ''
          77     print '  修改后的配置為:'
          78     print '  IP: '''.join(objNicConfig.IPAddress)
          79     print '  掩碼:'''.join(objNicConfig.IPSubnet)
          80     print '  網關:'''.join(objNicConfig.DefaultIPGateway)
          81     print '  DNS:'''.join(objNicConfig.DNSServerSearchOrder)
          82 
          83 print '修改IP結束'
          84 
          簡單了很多,呵呵
          源碼下載:modify_ip(wmi).zip

          http://www.aygfsteel.com/qujinlong123/

          posted on 2007-06-20 23:28 Long 閱讀(24096) 評論(15)  編輯  收藏 所屬分類: Python

          評論

          # re: 用Python干實事(一)自動修改Windows的IP、網關和DNS設置 2007-06-21 10:29 kergee
          請問Linux下怎么修改呢  回復  更多評論
            

          # re: 用Python干實事(一)自動修改Windows的IP、網關和DNS設置 2007-06-21 11:16 Zoom.Quiet
          咔咔咔,不錯!Python 就是用來使用的!
          不過GNU/Linux 中就不用這么麻煩了,
          一般配置Shell 腳本就足夠了,
          因為都是純文本的配置文件,預先組織好,復制一下就好  回復  更多評論
            

          # re: 用Python干實事(一)自動修改Windows的IP、網關和DNS設置 2007-06-21 12:02 笨笨狗
          用python操作wim修改,要比這個簡單得多……  回復  更多評論
            

          # re: 用Python干實事(一)自動修改Windows的IP、網關和DNS設置 2007-06-21 12:12 Long
          @笨笨狗
          你說的是WMI?
          呵呵,去看一下  回復  更多評論
            

          # re: 用Python干實事(一)自動修改Windows的IP、網關和DNS設置 2007-06-21 12:15 Long
          微軟官網的腳本中心中有用Windows腳本修改IP的示例,就是使用WMI
          大概瀏覽了一下,看到它寫的需要重啟電腦,所以就沒看了  回復  更多評論
            

          # re: 用Python干實事(一)自動修改Windows的IP、網關和DNS設置 2007-06-21 15:41 Long
          @笨笨狗
          呵呵,謝謝你的提示,已添加了利用WMI修改IP設置的版本  回復  更多評論
            

          # re: 用Python干實事(一)自動修改Windows的IP、網關和DNS設置 2007-07-02 17:13 zb
          Tw的有個人也寫一個這樣的。easyipconfig.  回復  更多評論
            

          # re: 用Python干實事(一)自動修改Windows的IP、網關和DNS設置 2007-07-12 12:15 程鑫
          不錯,學到知識了   回復  更多評論
            

          # re: 用Python干實事(一)自動修改Windows的IP、網關和DNS設置 2008-01-05 00:03 guest8888
          vista下 無法修改成功 是否和權限有關?  回復  更多評論
            

          # re: 用Python干實事(一)自動修改Windows的IP、網關和DNS設置 2009-05-13 06:49 網友
          @guest8888
          同感~  回復  更多評論
            

          # re: 用Python干實事(一)自動修改Windows的IP、網關和DNS設置 2009-08-03 14:27 路過
          netsh interface ip set address name="本地連接" source=static addr=192.168.1.36 mask=255.255.255.0 gateway=192.168.1.1 gwmetric=auto
          echo 更改DNS執行中..

          ————————————
          一句話搞定 不是更簡單嗎。。  回復  更多評論
            

          # re: 用Python干實事(一)自動修改Windows的IP、網關和DNS設置 2010-07-07 16:40 淘寶網
          ),每次回家和去公司都需要手動改IP,改了幾天嫌麻煩就想寫個小程序可以自動設置IP,只需要雙擊一下程序就搞定IP設置  回復  更多評論
            

          # re: 用Python干實事(一)自動修改Windows的IP、網關和DNS設置 2012-01-19 20:57 白目
          如果能再加入一個GUI用戶選擇界面就完善了!  回復  更多評論
            

          # re: 用Python干實事(一)自動修改Windows的IP、網關和DNS設置 2016-04-12 10:34 guest123
          @Long
          用wmi修改沒有成功,returnValue=(-2147217405,)。請問是什么原因?  回復  更多評論
            

          # re: 用Python干實事(一)自動修改Windows的IP、網關和DNS設置 2016-04-12 10:39 guest123
          @guest8888
          https://msdn.microsoft.com/zh-SG/library/aa389395(v=vs.85)
          查了相關文檔,returnValue=(-2147217405,)一般是權限或者安全性問題。用管理員身份執行py腳本可以修改成功。  回復  更多評論
            


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 汶川县| 瓮安县| 景德镇市| 阳西县| 常州市| 嘉善县| 柳州市| 桃源县| 江口县| 宁波市| 从化市| 扬州市| 罗甸县| 静海县| 汕头市| 锦屏县| 南阳市| 岗巴县| 凉城县| 赣榆县| 修水县| 万载县| 汾西县| 浦东新区| 仙居县| 涞源县| 邮箱| 澄江县| 惠安县| 抚顺市| 庆城县| 吉隆县| 绥滨县| 河东区| 墨竹工卡县| 固安县| 绍兴县| 惠水县| 大兴区| 崇仁县| 洞口县|