使用 win32inet.WinHttpGetProxyForUrl 的正确方法是什么

发布于 2024-07-26 06:13:57 字数 1021 浏览 4 评论 0原文

我正在尝试使用 Win32com 开发人员公开的 Microsoft WinHttp 库的一项功能。 不幸的是,大多数库似乎没有文档记录,并且没有通过 win32com 库使用 win32inet 功能的正确方法的示例。

这就是我到目前为止所做的:

import win32inet
hinternet = win32inet.InternetOpen("foo 1.0", 0, "", "", 0)
# Does not work!!!
proxy = win32inet.WinHttpGetProxyForUrl( hinternet, u"http://www.foo.com", 0  )

如您所见,我想做的就是使用 win32inet 功能来找出哪个代理适合用于给定的 URL,例如他的案例 foo.com。

你能帮我纠正最后一行的语法吗? MSN 有一些有关所包装函数的良好文档 但参数似乎没有完美地映射到 python 库的参数。

该脚本的固定版本应该:

  • 能够查找要使用的代理 对于任何给定的 URL。

  • 它应该始终准确地执行 Internet Explorer 将执行的操作(即使用相同的代理)

  • 它应该在任何网络上都有效有效的 Windows XP 设置。 这意味着它应该与显式配置的代理一起使用,并且根本不需要代理。

  • 它只需要在 Windows XP 32 位和 Python 2.4.4 上运行。 它可以使用任何官方发布的 win32com 版本。

我在 Windows XP 上使用 Python2.4.4 和 Win32Com。

更新 0:

或者...您能给我 cTypes 中的替代实现吗? 只要我能成功我就很高兴了!

I'm trying to use a feature of the Microsoft WinHttp library that has been exposed by the developers of Win32com. Unfortunately most of the library does not seem to be documented and there are no example of the correct way to use the win32inet features via the win32com library.

This is what I have so far:

import win32inet
hinternet = win32inet.InternetOpen("foo 1.0", 0, "", "", 0)
# Does not work!!!
proxy = win32inet.WinHttpGetProxyForUrl( hinternet, u"http://www.foo.com", 0  )

As you can see, all I am trying to do is use the win32inet feature to find out which proxy is the appropriate one to use for a given URL, int his case foo.com.

Can you help me correct the syntax of the last line? MSN has some good documentation for the function being wrapped but the args do not seem to map the to those of the python library perfectly.

The fixed version of this script should:

  • Be able to look up which proxy to use
    for any given URL.

  • It should always do exactly what Internet Explorer would do (i.e. use the same proxy)

  • It should be valid on any valid Windows XP set-up. That means it should work with an explicitly configured proxy and also no proxy at all.

  • It only needs to work on Windows XP 32bit with Python 2.4.4. It can use any official released version of win32com.

I'm using Python2.4.4 with Win32Com on Windows XP.

UPDATE 0:

OR... can you give me an alternative implementation in cTypes? As long as I can make it work I'm happy!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

送君千里 2024-08-02 06:13:57

下面是创建 HINTERNET 会话并使用它来获取代理详细信息的代码,使用 ctypes 直接访问 winhttp DLL。
它可以正常工作,没有任何错误,但我的机器上没有设置代理,您可能需要调整一些常量才能使其正确。 浏览代码中的 msdn 链接,我从那里看到了 API。

import ctypes
import ctypes.wintypes

winHttp = ctypes.windll.LoadLibrary("Winhttp.dll")

# http://msdn.microsoft.com/en-us/library/aa384098(VS.85).aspx
# first get a handle to HTTP session
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY=0
WINHTTP_NO_PROXY_NAME=WINHTTP_NO_PROXY_BYPASS=0
WINHTTP_FLAG_ASYNC=0x10000000
HINTERNET = winHttp.WinHttpOpen("PyWin32", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, WINHTTP_FLAG_ASYNC)
print HINTERNET

# now get proxy using HTTP session
# http://msdn.microsoft.com/en-us/library/aa384097(VS.85).aspx
"""
BOOL WinHttpGetProxyForUrl(
  __in   HINTERNET hSession,
  __in   LPCWSTR lpcwszUrl,
  __in   WINHTTP_AUTOPROXY_OPTIONS *pAutoProxyOptions,
  __out  WINHTTP_PROXY_INFO *pProxyInfo
);
"""
# create C structure for WINHTTP_AUTOPROXY_OPTIONS
#http://msdn.microsoft.com/en-us/library/aa384123(VS.85).aspx
"""
typedef struct {
  DWORD   dwFlags;
  DWORD   dwAutoDetectFlags;
  LPCWSTR lpszAutoConfigUrl;
  LPVOID  lpvReserved;
  DWORD   dwReserved;
  BOOL    fAutoLogonIfChallenged;
} WINHTTP_AUTOPROXY_OPTIONS;
"""
class WINHTTP_AUTOPROXY_OPTIONS(ctypes.Structure):
    _fields_ = [("dwFlags", ctypes.wintypes.DWORD),
                ("dwAutoDetectFlags", ctypes.wintypes.DWORD),
                ("lpszAutoConfigUrl", ctypes.wintypes.LPCWSTR),
                ("lpvReserved", ctypes.c_void_p ),
                ("dwReserved", ctypes.wintypes.DWORD),
                ("fAutoLogonIfChallenged",ctypes.wintypes.BOOL),]

WINHTTP_AUTOPROXY_AUTO_DETECT = 0x00000001;
WINHTTP_AUTO_DETECT_TYPE_DHCP = 0x00000001;
WINHTTP_AUTO_DETECT_TYPE_DNS_A = 0x00000002;
options = WINHTTP_AUTOPROXY_OPTIONS()
options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT
options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP|WINHTTP_AUTO_DETECT_TYPE_DNS_A
options.lpszAutoConfigUrl = 0
options.fAutoLogonIfChallenged = False

# create C structure for WINHTTP_AUTOPROXY_OPTIONS
# http://msdn.microsoft.com/en-us/library/aa383912(VS.85).aspx
"""
struct WINHTTP_PROXY_INFO {
  DWORD  dwAccessType;
  LPWSTR lpszProxy;
  LPWSTR lpszProxyBypass;
};
"""
class WINHTTP_PROXY_INFO(ctypes.Structure):
    _fields_ = [("dwAccessType", ctypes.wintypes.DWORD),
                ("lpszProxy", ctypes.wintypes.LPCWSTR),
                ("lpszProxyBypass", ctypes.wintypes.LPCWSTR),]

info = WINHTTP_PROXY_INFO()

ret = winHttp.WinHttpGetProxyForUrl(HINTERNET, "http://www.google.com", ctypes.pointer(options), ctypes.pointer(info) )
print "proxy success?",ret
if not ret:
    # some error lets see what is that?
    import win32api
    import win32con
    errorCode = win32api.GetLastError()
    print "win32 Error:",errorCode
    s = ""
    print win32api.FormatMessage(errorCode)

print info.dwAccessType, info.lpszProxy, info.lpszProxyBypass

Here is the code which creates HINTERNET session and uses that to get proxy details, using ctypes to directly access winhttp DLL.
It works without any error but I have no proxy set on my machine, you may have to tweak few constants to get it right. Go thru the msdn links in code, from where I have seen the API.

import ctypes
import ctypes.wintypes

winHttp = ctypes.windll.LoadLibrary("Winhttp.dll")

# http://msdn.microsoft.com/en-us/library/aa384098(VS.85).aspx
# first get a handle to HTTP session
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY=0
WINHTTP_NO_PROXY_NAME=WINHTTP_NO_PROXY_BYPASS=0
WINHTTP_FLAG_ASYNC=0x10000000
HINTERNET = winHttp.WinHttpOpen("PyWin32", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, WINHTTP_FLAG_ASYNC)
print HINTERNET

# now get proxy using HTTP session
# http://msdn.microsoft.com/en-us/library/aa384097(VS.85).aspx
"""
BOOL WinHttpGetProxyForUrl(
  __in   HINTERNET hSession,
  __in   LPCWSTR lpcwszUrl,
  __in   WINHTTP_AUTOPROXY_OPTIONS *pAutoProxyOptions,
  __out  WINHTTP_PROXY_INFO *pProxyInfo
);
"""
# create C structure for WINHTTP_AUTOPROXY_OPTIONS
#http://msdn.microsoft.com/en-us/library/aa384123(VS.85).aspx
"""
typedef struct {
  DWORD   dwFlags;
  DWORD   dwAutoDetectFlags;
  LPCWSTR lpszAutoConfigUrl;
  LPVOID  lpvReserved;
  DWORD   dwReserved;
  BOOL    fAutoLogonIfChallenged;
} WINHTTP_AUTOPROXY_OPTIONS;
"""
class WINHTTP_AUTOPROXY_OPTIONS(ctypes.Structure):
    _fields_ = [("dwFlags", ctypes.wintypes.DWORD),
                ("dwAutoDetectFlags", ctypes.wintypes.DWORD),
                ("lpszAutoConfigUrl", ctypes.wintypes.LPCWSTR),
                ("lpvReserved", ctypes.c_void_p ),
                ("dwReserved", ctypes.wintypes.DWORD),
                ("fAutoLogonIfChallenged",ctypes.wintypes.BOOL),]

WINHTTP_AUTOPROXY_AUTO_DETECT = 0x00000001;
WINHTTP_AUTO_DETECT_TYPE_DHCP = 0x00000001;
WINHTTP_AUTO_DETECT_TYPE_DNS_A = 0x00000002;
options = WINHTTP_AUTOPROXY_OPTIONS()
options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT
options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP|WINHTTP_AUTO_DETECT_TYPE_DNS_A
options.lpszAutoConfigUrl = 0
options.fAutoLogonIfChallenged = False

# create C structure for WINHTTP_AUTOPROXY_OPTIONS
# http://msdn.microsoft.com/en-us/library/aa383912(VS.85).aspx
"""
struct WINHTTP_PROXY_INFO {
  DWORD  dwAccessType;
  LPWSTR lpszProxy;
  LPWSTR lpszProxyBypass;
};
"""
class WINHTTP_PROXY_INFO(ctypes.Structure):
    _fields_ = [("dwAccessType", ctypes.wintypes.DWORD),
                ("lpszProxy", ctypes.wintypes.LPCWSTR),
                ("lpszProxyBypass", ctypes.wintypes.LPCWSTR),]

info = WINHTTP_PROXY_INFO()

ret = winHttp.WinHttpGetProxyForUrl(HINTERNET, "http://www.google.com", ctypes.pointer(options), ctypes.pointer(info) )
print "proxy success?",ret
if not ret:
    # some error lets see what is that?
    import win32api
    import win32con
    errorCode = win32api.GetLastError()
    print "win32 Error:",errorCode
    s = ""
    print win32api.FormatMessage(errorCode)

print info.dwAccessType, info.lpszProxy, info.lpszProxyBypass
谁对谁错谁最难过 2024-08-02 06:13:57

除非有充分的理由使用 win32inet(由于 SWIG 的限制,这方面很混乱),我建议您使用 ctypes反而。

Unless there is a strong reason for using win32inet (which is messy in this area due to limitations of SWIG), I recommend that you use ctypes instead.

没有你我更好 2024-08-02 06:13:57

至少对于 Windows XP x86 和 Windows 8 x64 上的 Python 2.7.6Pywin 218 来说,它可以工作:

import win32inet
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa384098(v=vs.85).aspx
hinternet = win32inet.WinHttpOpen("foo", 0, "", "", 0)

# http://msdn.microsoft.com/en-us/library/windows/desktop/aa384123(v=vs.85).aspx
autoproxy_options = (2, 0, u"http://your-proxy-script-path", None, 0, 1)

# http://msdn.microsoft.com/en-us/library/windows/desktop/aa384097(v=vs.85).aspx
proxy = win32inet.WinHttpGetProxyForUrl(hinternet, u"http://www.google.com",
                    autoproxy_options)

print proxy

值得一提的是,该示例使用自动代理选项 WINHTTP_AUTOPROXY_CONFIG_URL 来传入一个明确的 URL。 您可以使用其他选项,例如,如果您想使用 DNS 或 DHCP 自动检测,您可以这样做:

autoproxy_options = (1, 1|2, u"", None, 0, 1)

您可以在上面显示的链接中找到其他选项(在代码中)

At least with Python 2.7.6 and Pywin 218 on Windows XP x86 and Windows 8 x64, it works:

import win32inet
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa384098(v=vs.85).aspx
hinternet = win32inet.WinHttpOpen("foo", 0, "", "", 0)

# http://msdn.microsoft.com/en-us/library/windows/desktop/aa384123(v=vs.85).aspx
autoproxy_options = (2, 0, u"http://your-proxy-script-path", None, 0, 1)

# http://msdn.microsoft.com/en-us/library/windows/desktop/aa384097(v=vs.85).aspx
proxy = win32inet.WinHttpGetProxyForUrl(hinternet, u"http://www.google.com",
                    autoproxy_options)

print proxy

Worth to mention that the example uses the autoproxy option WINHTTP_AUTOPROXY_CONFIG_URL in order to pass in an explicit URL. You can use other options, for instance, if you want to autodetect using DNS or DHCP you can do:

autoproxy_options = (1, 1|2, u"", None, 0, 1)

You can find other options in the link showed above (in the code)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文