INTERNET_PROXY_INFO contiene un tipo di accesso DWORD e due puntatori a stringhe. La query nativa necessita anche di spazio buffer sufficiente per i dati proxy; Marshal.SizeOf di una piccola struttura gestita non è un buffer di risultato completo a lunghezza variabile.

Un helper di compatibilità desktop può usare il punto di ingresso ANSI e copiare le stringhe prima di liberare quel buffer di query:

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. La prima chiamata ottiene il numero di byte necessario e la seconda riempie quell'allocazione. Se il risultato cresce tra le chiamate, viene segnalato il secondo errore invece di leggere un buffer troppo piccolo.

Mantieni AccessType come uint. In un processo a 64 bit rimane un DWORD a 32 bit, mentre i campi puntatore si ampliano con l'architettura del processo. Il normale layout sequenziale fornisce l'allineamento corrispondente.

Questo esempio riguarda il buffer di risultato dell'opzione 38. Non applicare il suo modello di proprietà ciecamente a INTERNET_OPTION_PER_CONNECTION_OPTION, le cui opzioni stringa restituite richiedono la loro pulizia separata documentata.

Il risultato descrive la configurazione di WinINet nell'ambito dell'handle scelto. Non è una decisione PAC per un URL arbitrario né un rapporto sulla rotta effettiva di ogni browser. Quando la stringa proxy restituita è una mappa specifica del protocollo, conserva quella struttura invece di trattarla come un singolo endpoint. WinINet è l'API desktop; le applicazioni di servizio necessitano della loro disposizione WinHTTP supportata.

Articoli correlati