INTERNET_PROXY_INFO conține un tip de acces DWORD și doi pointeri la șiruri. Interogarea nativă are nevoie și de suficient spațiu de buffer pentru datele sale proxy; Marshal.SizeOf al unei structuri mici gestionate nu este un buffer de rezultat complet cu lungime variabilă.

Un ajutor de compatibilitate pentru desktop poate folosi punctul de intrare ANSI și poate copia șirurile înainte de a elibera acel buffer de interogare:

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 este INTERNET_OPTION_PROXY; 122 este ERROR_INSUFFICIENT_BUFFER. Primul apel obține numărul necesar de octeți, iar al doilea umple acea alocare. Dacă rezultatul crește între apeluri, se raportează a doua eroare în loc să se citească un buffer prea mic.

Păstrați AccessType ca uint. Într-un proces pe 64 de biți rămâne un DWORD pe 32 de biți, în timp ce câmpurile pointer se lărgesc odată cu arhitectura procesului. Aspectul secvențial normal oferă alinierea corespunzătoare.

Acest exemplu se referă la bufferul de rezultat al opțiunii 38. Nu aplicați modelul său de proprietate orbește la INTERNET_OPTION_PER_CONNECTION_OPTION, ale cărui opțiuni de șir returnate necesită curățarea separată documentată.

Rezultatul descrie configurația WinINet în domeniul handle-ului ales. Nu este o decizie PAC pentru un URL arbitrar și nici un raport al rutei efective a fiecărui browser. Când șirul proxy returnat este o hartă specifică protocolului, păstrați acea structură în loc să o tratați ca un singur punct final. WinINet este API-ul de desktop; aplicațiile de serviciu au nevoie de aranjamentul lor WinHTTP acceptat.

Articole similare