INTERNET_PROXY_INFO contém um tipo de acesso DWORD e dois ponteiros de string. A consulta nativa também precisa de espaço de buffer suficiente para seus dados de proxy; Marshal.SizeOf de uma pequena estrutura gerenciada não é um buffer de resultado completo de comprimento variável.

Um auxiliar de compatibilidade de desktop pode usar o ponto de entrada ANSI e copiar as strings antes de liberar esse buffer 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 é INTERNET_OPTION_PROXY; 122 é ERROR_INSUFFICIENT_BUFFER. A primeira chamada obtém a contagem de bytes necessária e a segunda preenche essa alocação. Se o resultado crescer entre as chamadas, a segunda falha é relatada em vez de ler um buffer pequeno demais.

Mantenha AccessType como uint. Em um processo de 64 bits ele continua sendo um DWORD de 32 bits, enquanto os campos de ponteiro se ampliam com a arquitetura do processo. O layout sequencial normal fornece o alinhamento correspondente.

Este exemplo trata do buffer de resultado da opção 38. Não aplique seu padrão de propriedade cegamente a INTERNET_OPTION_PER_CONNECTION_OPTION, cujas opções de string retornadas exigem sua limpeza separada documentada.

O resultado descreve a configuração do WinINet no escopo do identificador escolhido. Não é uma decisão PAC para uma URL arbitrária nem um relatório da rota efetiva de cada navegador. Quando a string de proxy retornada é um mapa específico do protocolo, preserve essa estrutura em vez de tratá-la como um único endpoint. O WinINet é a API de desktop; aplicativos de serviço precisam de sua disposição WinHTTP suportada.

Artigos relacionados