INTERNET_PROXY_INFO contient un type d'accès DWORD et deux pointeurs de chaîne. La requête native a aussi besoin d'un espace de tampon suffisant pour ses données proxy ; Marshal.SizeOf d'une petite structure managée n'est pas un tampon de résultat complet de longueur variable.

Un utilitaire de compatibilité de bureau peut utiliser le point d'entrée ANSI et copier les chaînes avant de libérer ce tampon de requête :

static class WinInetProxy
{
    [System.Runtime.InteropServices.StructLayout(
        System.Runtime.InteropServices.LayoutKind.Sequential)]
    struct ProxyInfo
    {
        public uint AccessType;
        public IntPtr Proxy;
        public IntPtr Bypass;
    }

    [System.Runtime.InteropServices.DllImport(
        "wininet.dll", EntryPoint = "InternetQueryOptionA",
        SetLastError = true)]
    [return: System.Runtime.InteropServices.MarshalAs(
        System.Runtime.InteropServices.UnmanagedType.Bool)]
    static extern bool Query(
        IntPtr handle, uint option, IntPtr buffer, ref uint size);

    public static (uint Type, string Proxy, string Bypass) Read()
    {
        uint size = 0;
        Query(IntPtr.Zero, 38, IntPtr.Zero, ref size);
        int error = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
        if (error != 122 || size == 0)
            throw new System.ComponentModel.Win32Exception(error);

        IntPtr buffer = System.Runtime.InteropServices.Marshal
            .AllocHGlobal(checked((int)size));
        try
        {
            if (!Query(IntPtr.Zero, 38, buffer, ref size))
                throw new System.ComponentModel.Win32Exception(
                    System.Runtime.InteropServices.Marshal.GetLastWin32Error());
            var value = System.Runtime.InteropServices.Marshal
                .PtrToStructure<ProxyInfo>(buffer);
            return (value.AccessType,
                System.Runtime.InteropServices.Marshal.PtrToStringAnsi(value.Proxy) ?? "",
                System.Runtime.InteropServices.Marshal.PtrToStringAnsi(value.Bypass) ?? "");
        }
        finally
        {
            System.Runtime.InteropServices.Marshal.FreeHGlobal(buffer);
        }
    }
}

38 est INTERNET_OPTION_PROXY ; 122 est ERROR_INSUFFICIENT_BUFFER. Le premier appel obtient le nombre d'octets requis, et le second remplit cette allocation. Si le résultat grandit entre les appels, le second échec est signalé au lieu de lire un tampon trop petit.

Conservez AccessType en uint. Dans un processus 64 bits, il reste un DWORD 32 bits, tandis que les champs pointeur s'élargissent avec l'architecture du processus. La disposition séquentielle normale fournit l'alignement correspondant.

Cet exemple concerne le tampon de résultat de l'option 38. N'appliquez pas son modèle de propriété aveuglément à INTERNET_OPTION_PER_CONNECTION_OPTION, dont les options de chaîne renvoyées exigent leur nettoyage séparé documenté.

Le résultat décrit la configuration WinINet dans la portée du handle choisi. Ce n'est pas une décision PAC pour une URL arbitraire ni un rapport sur la route effective de chaque navigateur. Lorsque la chaîne proxy renvoyée est une carte propre au protocole, conservez cette structure au lieu de la traiter comme un seul point de terminaison. WinINet est l'API de bureau ; les applications de service ont besoin de leur disposition WinHTTP prise en charge.

Articles similaires