2009-07-03 4 views
3

Win32com 개발자가 노출 한 Microsoft WinHttp 라이브러리의 기능을 사용하려고합니다. 불행히도 대부분의 라이브러리는 문서화되어 있지 않으며 win32com 라이브러리를 통해 win32inet 기능을 사용하는 올바른 방법의 예가 없습니다. 당신이 볼 수 있듯이win32inet.WinHttpGetProxyForUrl을 사용하는 올바른 방법은 무엇입니까

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

는, 내가하려고 모두가 주어진 URL에 사용하는 적절한 하나입니다 프록시 찾기 위해 win32inet 기능을 사용할 수 있습니다 :

내가 지금까지 무엇을 가지고 , 그의 사건 foo.com.

마지막 줄의 구문을 수정하도록 도와 줄 수 있습니까? MSN은 일부 good documentation for the function being wrapped을 가지고 있지만 args는 파이썬 라이브러리의 그것들에 완벽하게 매핑하지 않는 것 같습니다.

이 스크립트의 수정 버전을 수행해야합니다

  • 가 특정 URL에 대한 을 사용할 프록시를 찾아 볼 수 있어야합니다. 그것은 항상 Internet Explorer가 할 것 않습니다해야 정확히

  • (즉 같은 프록시를 사용)

  • 그것은 유효한 Windows XP에서 유효해야이 설정합니다. 이는 명시 적으로 구성된 프록시와 프록시가 전혀 작동하지 않아야 함을 의미합니다.

  • 파이썬 2.4.4가 설치된 Windows XP 32 비트에서만 작동하면됩니다. Win32com의 공식 릴리스 버전을 사용할 수 있습니다.

Windows XP에서 Win32Com과 함께 Python2.4.4를 사용하고 있습니다.

UPDATE 0 :

OR은 ... 당신이 나에게하는 ctypes에서 대체 구현을 줄 수 있습니까? 내가 할 수있는 한 행복해!

+0

당신이 쓸 때 : 당신은 DNS 또는 DHCP를 사용하여 자동으로 감지하려는 경우 당신이 할 수있는, 예를 들어, 다른 옵션을 사용할 수 있습니다 "작동하지 않습니다 !!!": 오류 메시지가 있습니까? 결과가 예상과 다른가? 자세한 정보를 제공해주십시오. – ars

답변

6

다음은 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 
+0

좋아, 그게 놀라운 도움이야 ... 이제는 내가 ctypes.wintypes에 대해 knopw 내가 이론적으로 내가 좋아하는 모든 구조를 만들 수 있습니다. 하나의 제조법을 시작하는 것이 얼마나 도움이되는지 놀라워합니다. –

1

(SWIG의 제한으로 인해이 영역에서 지저분한) win32inet을 사용해야하는 강력한 이유가없는 한, ctypes을 대신 사용하는 것이 좋습니다.

+0

왜 그럴까요? win32inet 모듈은 신뢰할 수 있습니까? –

+0

글쎄, 그것이 효과가 있었다면, 나는이 질문을 게시하지 않았을 것이라고 추정한다 ;-). 아직'ars'의 질문에 답을하지 않았기 때문에 (어떤 오류가 발생했는지), 어떤 문제에 빠져 있는지 잘 모르겠습니다. 내가 언급 한 제한의 결과 인 비표준 인수 전달을 가리키는 getargs 오류가 발생합니다. –

+0

예, 이것이 오류입니다. 논쟁은 잘못되었습니다 - 나는 옳은 것이 무엇인지 확신 할 수 없습니다! –

1

은 적어도 윈도우 XP의 x86 및 윈도우 8 64에 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.

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

당신은 다른 옵션을 찾을 수 있습니다 링크 (코드에) 위에서 보여 주었다에