קריאת INTERNET_OPTION_PROXY ב-WinINet עם מאגר C# בגודל מתאים
אחזרו את INTERNET_OPTION_PROXY עם שאילתת גודל ומאגר מקורי בגודל נכון, בהתאמה לשדות DWORD והמצביע ב-C#.
INTERNET_PROXY_INFO מכיל סוג גישה DWORD ושני מצביעי מחרוזת. השאילתה המקורית זקוקה גם למספיק מקום במאגר לנתוני ה-proxy שלה; 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. בתהליך 64 סיביות הוא נשאר DWORD של 32 סיביות, בעוד שדות המצביע מתרחבים עם ארכיטקטורת התהליך. פריסה רציפה רגילה מספקת את היישור המתאים.
דוגמה זו עוסקת במאגר התוצאה של אפשרות 38. אל תחילו את דפוס הבעלות שלה באופן עיוור על INTERNET_OPTION_PER_CONNECTION_OPTION, שאפשרויות המחרוזת המוחזרות שלו דורשות ניקוי נפרד מתועד.
התוצאה מתארת את תצורת WinINet בטווח הידית הנבחר. היא אינה החלטת PAC עבור URL שרירותי ואינה דוח של המסלול האפקטיבי של כל דפדפן. כאשר מחרוזת ה-proxy המוחזרת היא מפה ספציפית לפרוטוקול, שמרו על המבנה הזה במקום להתייחס אליו כנקודת קצה אחת. WinINet הוא ה-API של שולחן העבודה; יישומי שירות זקוקים לסידור WinHTTP הנתמך שלהם.