使用Python在Windows XP上编程检测系统代理设置

5
我开发了一款关键应用程序,被跨国公司使用。全球各地的办公室用户需要能够安装此应用程序。
该应用程序实际上是Excel的插件,我们有一个基于Setuptools的easy_install自动安装程序,可以确保每当用户打开Excel时,所有项目的依赖项都会自动安装或更新。这一切都非常优雅,因为用户很少意识到所有安装都完全在后台进行。
不幸的是,我们正在扩张并开设新办事处,这些办事处都有不同的代理设置。这些设置似乎每天都在变化,所以我们无法跟上外包的安全人员更改内容而没有告知我们的情况。这很糟糕,但我们只能绕过去。
我想编写程序来检测Windows工作站上运行的系统范围代理设置:
组织中的每个人都运行Windows XP和Internet Explorer。我已经验证,无论他们身在何处,每个人都可以从IE下载我们的东西而没有问题。
因此,我需要做的就是检测IE正在使用哪些代理设置,并使Setuptools使用这些设置。理论上,所有这些信息都应该在注册表中..但是否有更好的方法来查找它,以确保在人们升级IE时不会更改?例如,是否有Windows API调用可以用于发现代理设置?
总结一下:
我们在Windows XP上使用Python 2.4.4
我们需要检测Internet Explorer的代理设置(例如主机、端口和代理类型)
我将使用这些信息动态重新配置easy_install,以便它可以通过代理下载egg文件。
更新0:
我忘记了一个重要的细节:每个站点都有一个自动配置“pac”文件。
在Windows\CurrentVersion\InternetSettings\AutoConfigURL中有一个关键字,指向本地服务器上包含类似javascript文件的HTTP文档。 pac脚本基本上是一系列嵌套的if语句,将URL与正则表达式进行比较,然后最终返回所选代理服务器的主机名。该脚本是一个名为FindProxyForURL(url,host)的单个javascript函数。
因此,挑战就在于找出任何给定服务器要使用哪个代理。唯一100%保证的方法是查找pac文件并从Python调用Javascript函数。
有什么建议吗?是否有更优雅的方法来做到这一点?

如果你看到FindProxyForURL(url, host),那么它肯定是代理自动配置设置(PAC)http://en.wikipedia.org/wiki/Proxy_auto-config。你可以使用pacparser解析JavaScript文件以确定代理服务器和端口。https://code.google.com/p/pacparser/ - RP.
可能是重复的问题:如何查找浏览器的代理设置? - Ian Goldby
2个回答

4
这是一个示例,应该在系统托盘中创建一个绿色的圆点(代理已启用)或红色的圆点(代理已禁用)
它展示了如何读写Windows注册表。使用GTK实现。
#!/usr/bin/env python
import gobject
import gtk
from _winreg import *

class ProxyNotifier:
    def __init__(self):        
        self.trayIcon = gtk.StatusIcon()
        self.updateIcon()

        #set callback on right click to on_right_click
        self.trayIcon.connect('popup-menu', self.on_right_click)
        gobject.timeout_add(1000, self.checkStatus)

    def isProxyEnabled(self):

        aReg = ConnectRegistry(None,HKEY_CURRENT_USER)

        aKey = OpenKey(aReg, r"Software\Microsoft\Windows\CurrentVersion\Internet Settings") 
        subCount, valueCount, lastModified = QueryInfoKey(aKey)

        for i in range(valueCount):                                           
            try:
                n,v,t = EnumValue(aKey,i)
                if n == 'ProxyEnable':
                    return v and True or False
            except EnvironmentError:                                               
                break
        CloseKey(aKey)  

    def invertProxyEnableState(self):
        aReg = ConnectRegistry(None,HKEY_CURRENT_USER)
        aKey = OpenKey(aReg, r"Software\Microsoft\Windows\CurrentVersion\Internet Settings", 0, KEY_WRITE)
        if self.isProxyEnabled() : 
            val = 0 
        else:
            val = 1
        try:   
            SetValueEx(aKey,"ProxyEnable",0, REG_DWORD, val) 
        except EnvironmentError:                                          
            print "Encountered problems writing into the Registry..."
        CloseKey(aKey)

    def updateIcon(self):
        if self.isProxyEnabled():
            icon=gtk.STOCK_YES
        else:
            icon=gtk.STOCK_NO
        self.trayIcon.set_from_stock(icon)

    def checkStatus(self):
        self.updateIcon()
        return True


    def on_right_click(self, data, event_button, event_time):
        self.invertProxyEnableState()
        self.updateIcon()


if __name__ == '__main__':
    proxyNotifier = ProxyNotifier()
    gtk.main()

不错的解决方案,但请检查更新。顺便说一下,这必须在 Excel 后台运行,因此我们不能使用 GTK。 - Salim Fadhley

3
据我所知,在Windows环境中,如果没有设置代理环境变量,则代理设置将从注册表的Internet设置部分获取。这就足够了吗?
或者您可以从注册表中获取一些有用的信息: HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ProxyServer 编辑: 抱歉不知道如何格式化评论的源代码,我在这里重新发布它。
>>> import win32com.client
>>> js = win32com.client.Dispatch('MSScriptControl.ScriptControl')
>>> js.Language = 'JavaScript'
>>> js.AddCode('function add(a, b) {return a+b;}')
>>> js.Run('add', 1, 2)
3

你确定吗?我拥有"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings",但是它并没有包含名为ProxyServer的对象。 - Salim Fadhley
Salim,我觉得现在可能是JavaScript解析器的问题?我对JavaScript几乎没有任何经验。有人告诉我Microsoft的scriptcontrol可能会有用:...不知道如何在这里格式化源代码,我会重新发布演示代码到答案部分。 - sunqiang
是的,这就是解决方案!我可以通过win32com执行Pac文件,并找到正确的代理使用。太棒了。 - Salim Fadhley
2
@SalimFadhley,你能否发布一下你用来发现正确代理的代码?如果可以的话,我会非常感激! - duhaime

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接