使用 Python 以编程方式检测 Windows XP 上的系统代理设置

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1068212/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 12:44:16  来源:igfitidea点击:

Programmatically detect system-proxy settings on Windows XP with Python

pythonwindowsnetworkingproxysetuptools

提问by Salim Fadhley

I develop a critical application used by a multi-national company. Users in offices all around the globe need to be able to install this application.

我开发了一个跨国公司使用的关键应用程序。全球各地办公室的用户都需要能够安装此应用程序。

The application is actually a plugin to Excel and we have an automatic installer based on Setuptools' easy_install that ensures that all a project's dependancies are automatically installed or updated any time a user switches on their Excel. It all works very elegantly as users are seldom aware of all the installation which occurs entirely in the background.

该应用程序实际上是 Excel 的插件,我们有一个基于 Setuptools 的 easy_install 的自动安装程序,可确保在用户打开 Excel 时自动安装或更新所有项目的依赖项。这一切都非常优雅,因为用户很少意识到完全在后台发生的所有安装。

Unfortunately we are expanding and opening new offices which all have different proxy settings. These settings seem to change from day to day so we cannot keep up with the outsourced security guys who change stuff without telling us. It sucks but we just have to work around it.

不幸的是,我们正在扩大和开设新的办公室,它们都有不同的代理设置。这些设置似乎每天都在变化,因此我们无法跟上那些在不告诉我们的情况下更改内容的外包安全人员。这很糟糕,但我们只需要解决它。

I want to programatically detect the system-wide proxy settings on the Windows workstations our users run:

我想以编程方式检测用户运行的 Windows 工作站上的系统范围代理设置:

Everybody in the organisazation runs Windows XP and Internet Explorer. I've verified that everybody can download our stuff from IE without problems regardless of where they are int the world.

组织中的每个人都运行 Windows XP 和 Internet Explorer。我已经证实每个人都可以毫无问题地从 IE 下载我们的东西,无论他们身在何处。

So all I need to do is detect what proxy settings IE is using and make Setuptools use those settings. Theoretically all of this information should be in the Registry.. but is there a better way to find it that is guaranteed not to change with people upgrade IE? For example is there a Windows API call I can use to discover the proxy settings?

所以我需要做的就是检测 IE 正在使用的代理设置,并使 Setuptools 使用这些设置。理论上所有这些信息都应该在注册表中..但是有没有更好的方法来找到它保证不会随着人们升级IE而改变?例如,是否有可用于发现代理设置的 Windows API 调用?

In summary:

总之:

  • We use Python 2.4.4 on Windows XP
  • We need to detect the Internet Explorer proxy settings (e.g. host, port and Proxy type)
  • I'm going to use this information to dynamically re-configure easy_install so that it can download the egg files via the proxy.
  • 我们在 Windows XP 上使用 Python 2.4.4
  • 我们需要检测 Internet Explorer 代理设置(例如主机、端口和代理类型)
  • 我将使用此信息动态重新配置easy_install,以便它可以通过代理下载egg 文件。

UPDATE0:

更新0:

I forgot one important detail: Each site has an auto-config "pac" file.

我忘记了一个重要的细节:每个站点都有一个自动配置的“pac”文件。

There's a key in Windows\CurrentVersion\InternetSettings\AutoConfigURL which points to a HTTP document on a local server which contains what looks like a javascript file.

Windows\CurrentVersion\InternetSettings\AutoConfigURL 中有一个键指向本地服务器上的 HTTP 文档,其中包含看起来像 javascript 文件的内容。

The pac script is basically a series of nested if-statements which compare URLs against a regexp and then eventually return the hostname of the chosen proxy-server. The script is a single javascript function called FindProxyForURL(url, host)

pac 脚本基本上是一系列嵌套的 if 语句,它们将 URL 与正则表达式进行比较,然后最终返回所选代理服务器的主机名。该脚本是一个名为 FindProxyForURL(url, host) 的 javascript 函数

The challenge is therefore to find out for any given server which proxy to use. The only 100% guaranteed way to do this is to look up the pac file and call the Javascript function from Python.

因此,挑战在于为任何给定的服务器找出要使用的代理。唯一 100% 保证的方法是查找 pac 文件并从 Python 调用 Javascript 函数。

Any suggestions? Is there a more elegant way to do this?

有什么建议?有没有更优雅的方法来做到这一点?

采纳答案by sunqiang

As far as I know, In a Windows environment, if no proxy environment variables are set, proxy settings are obtained from the registry's Internet Settings section. . Isn't it enough?

据我所知,在 Windows 环境中,如果没有设置代理环境变量,代理设置是从注册表的 Internet 设置部分获取的。. 还不够吗?

Or u can get something useful info from registry: HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ProxyServer

或者你可以从注册表中获取一些有用的信息:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ProxyServer

Edit:
sorry for don't know how to format comment's source code, I repost it here.

编辑:
抱歉不知道如何格式化评论的源代码,我在这里重新发布。

>>> 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

回答by rapdum

Here's a sample that should create a bullet green (proxy enable) or red (proxy disable) in your systray

这是一个示例,它应该在您的系统托盘中创建一个项目符号绿色(代理启用)或红色(代理禁用)

It shows how to read and write in windows registry

它显示了如何在 Windows 注册表中读写

it uses gtk

它使用 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()