2009-07-03 6 views
3

Ich versuche, eine Funktion der Microsoft WinHttp-Bibliothek zu verwenden, die von den Entwicklern von Win32com ausgesetzt wurde. Leider scheint der größte Teil der Bibliothek nicht dokumentiert zu sein und es gibt kein Beispiel für die korrekte Verwendung der win32inet-Funktionen über die win32com-Bibliothek.Was ist die richtige Art zu verwenden win32inet.WinHttpGetProxyForUrl

Dies ist, was ich bisher:

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

Wie Sie sehen können, alles, was ich zu tun versuche, ist die win32inet Funktion verwenden, um herauszufinden, welche Proxy die geeignete ist für eine bestimmte URL zu verwenden, In seinem Fall foo.com.

Können Sie mir helfen, die Syntax der letzten Zeile zu korrigieren? MSN hat einige good documentation for the function being wrapped aber die Argumente scheinen nicht zu denen der Python-Bibliothek perfekt zuordnen.

Die feste Version dieses Skript sollte:

  • der Lage zu sehen, welche Proxy für einen bestimmten URL zu verwenden.

  • Es sollte immer genau tun, was Internet Explorer tun würde (das heißt den gleichen Proxy verwenden)

  • Es sollte auf jedem gültigen Windows XP gültig sein Set-up. Das bedeutet, dass es mit einem explizit konfigurierten Proxy und auch ohne Proxy funktionieren sollte.

  • Es muss nur unter Windows XP 32bit mit Python 2.4.4 arbeiten. Es kann jede offiziell veröffentlichte Version von win32com verwenden.

Ich benutze Python2.4.4 mit Win32Com unter Windows XP.

UPDATE 0:

OR ... können Sie mir eine alternative Implementierung in ctypes geben? Solange ich es schaffen kann, bin ich glücklich!

+0

Wenn Sie schreiben "Funktioniert nicht !!!": gibt es eine Fehlermeldung? ist das Ergebnis anders als erwartet? etc .. Bitte geben Sie weitere Informationen. – ars

Antwort

6

Hier ist der Code, der HINTERNET-Sitzung erstellt und verwendet, um Proxy-Details zu erhalten, mit Ctypes direkt WinHTTP DLL zugreifen. Es funktioniert ohne Fehler, aber ich habe keine Proxy-Set auf meinem Rechner, müssen Sie möglicherweise einige Konstanten zwicken, um es richtig zu machen. Gehe durch die MSDN-Links im Code, von wo ich die API gesehen habe.

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

Okay, das ist eine erstaunliche Hilfe ... und jetzt, wo ich über ctypes.wintypes weiß, kann ich theoretisch jede Struktur machen, die ich mag. Es ist erstaunlich, wie hilfreich es ist, nur ein Rezept zu haben, um damit anzufangen. –

1

Es sei denn, es gibt einen starken Grund für die Verwendung win32inet (was in diesem Bereich aufgrund von Einschränkungen von SWIG chaotisch ist), empfehle ich stattdessen ctypes zu verwenden.

+0

Warum ist das? Ist das win32inet-Modul nicht vertrauenswürdig? –

+0

Nun, wenn es funktioniert hätte, würde ich annehmen, dass du diese Frage nicht gestellt hättest ;-). Sie haben immer noch nicht die Frage beantwortet (was ist der Fehler, den Sie bekommen), deshalb bin ich mir nicht sicher, auf welches Problem Sie stoßen. Ich bekomme einen getargs-Fehler, der auf nicht standardmäßige Argumente hinweist, was eine Konsequenz der erwähnten Einschränkungen ist. –

+0

Ja, das ist der Fehler. Die Argumente sind falsch - ich bin mir nicht sicher, was die richtigen sind! –

1

Mindestens mit Python 2.7.6 und Pywin 218 unter Windows XP x86 und Windows 8 x64, funktioniert es:

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 

wert zu erwähnen, dass das Beispiel der Autoproxy-Option WINHTTP_AUTOPROXY_CONFIG_URL verwendet, um in einem expliziten passieren URLSie können andere Optionen verwenden, zum Beispiel, wenn Sie DNS oder DHCP automatisch erkennen wollen verwenden, können Sie tun:

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

Sie können andere Optionen finden in der Link oben zeigte (im Code)