يحتوي INTERNET_PROXY_INFO على نوع وصول DWORD ومؤشري سلسلة نصية. يحتاج الاستعلام الأصلي أيضًا إلى مساحة مخزن كافية لبيانات الوكيل؛ وMarshal.SizeOf لبنية صغيرة مُدارة ليس مخزن نتيجة كاملًا متغير الطول.

يمكن لمساعد توافق سطح المكتب استخدام نقطة الدخول ANSI ونسخ السلاسل قبل تحرير مخزن الاستعلام:

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. يجلب الاستدعاء الأول عدد البايتات المطلوب، ويملأ الثاني ذلك التخصيص. إذا كبر الناتج بين الاستدعاءين، يُبلَّغ عن الفشل الثاني بدلًا من قراءة مخزن أصغر من اللازم.

أبقِ AccessType من النوع uint. يظل DWORD بعرض 32 بت داخل عملية 64 بت، بينما تتسع حقول المؤشر مع بنية العملية. ويوفر التخطيط المتتابع العادي المحاذاة المطابقة.

يتعلق هذا المثال بمخزن نتيجة الخيار 38. لا تطبق نمط ملكيته على INTERNET_OPTION_PER_CONNECTION_OPTION دون تفكير، فخيارات السلاسل التي يعيدها تحتاج إلى التنظيف المنفصل الموثق.

يصف الناتج إعداد WinINet عند نطاق المقبض المحدد. وهو ليس قرار PAC لعنوان URL عشوائي ولا تقريرًا عن المسار الفعلي لكل متصفح. وعندما تكون سلسلة الوكيل المعادة خريطة خاصة بالبروتوكول، حافظ على تلك البنية بدلًا من معاملتها كنقطة نهاية واحدة. WinINet هي واجهة سطح المكتب؛ وتطبيقات الخدمات تحتاج إلى ترتيب WinHTTP المدعوم لديها.

مقالات ذات صلة