INTERNET_PROXY_INFO contiene un tipo de acceso DWORD y dos punteros a cadenas. La consulta nativa también necesita suficiente espacio de búfer para sus datos de proxy; Marshal.SizeOf de una estructura administrada pequeña no es un búfer de resultado completo de longitud variable.

Un auxiliar de compatibilidad de escritorio puede usar el punto de entrada ANSI y copiar las cadenas antes de liberar ese búfer de consulta:

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 es INTERNET_OPTION_PROXY; 122 es ERROR_INSUFFICIENT_BUFFER. La primera llamada obtiene el número de bytes necesario y la segunda llena esa asignación. Si el resultado crece entre llamadas, se informa el segundo fallo en lugar de leer un búfer demasiado pequeño.

Mantenga AccessType como uint. En un proceso de 64 bits sigue siendo un DWORD de 32 bits, mientras que los campos de puntero se amplían con la arquitectura del proceso. La disposición secuencial normal proporciona la alineación correspondiente.

Este ejemplo se refiere al búfer de resultado de la opción 38. No aplique su patrón de propiedad a ciegas a INTERNET_OPTION_PER_CONNECTION_OPTION, cuyas opciones de cadena devueltas requieren su limpieza separada documentada.

El resultado describe la configuración de WinINet en el ámbito del identificador elegido. No es una decisión PAC para una URL arbitraria ni un informe de la ruta efectiva de cada navegador. Cuando la cadena de proxy devuelta es un mapa específico del protocolo, conserve esa estructura en lugar de tratarla como un solo extremo. WinINet es la API de escritorio; las aplicaciones de servicio necesitan su disposición WinHTTP compatible.

Artículos relacionados