InternetQueryOption with INTERNET_OPTION_PROXY returns 空字符串而不是设置的代理设置

InternetQueryOption with INTERNET_OPTION_PROXY returns empty strings instead of the set proxy settings

使用 InternetOpen 设置代理服务器 (127.0.0.1:5401) 并绕过 (<-loopback>) 但是,当 InternetQueryOption 选项设置为 INTERNET_OPTION_PROXY, returned 字符串, 在 INTERNET_PROXY_INFO 结构中, 是空的, 但访问类型是正确的, INTERNET_OPEN_TYPE_PROXY.

这是 InternetQueryOptionINTERNET_PROXY_INFO 结构的签名,也许我做错了什么:

[DllImport("wininet.dll", SetLastError = true)]
public static extern bool InternetQueryOption([In] IntPtr hInternet, [In] INTERNET_OPTION option, [In, Out] IntPtr buffer, [In, Out] ref int bufferSize);

public enum INTERNET_OPTION : uint
{
    PROXY = 38
}

public enum INTERNET_OPEN_TYPE : uint
{
    PRECONFIG,
    DIRECT,
    PROXY = 3,
    PRECONFIG_WITH_NO_AUTOPROXY
}

[StructLayout(LayoutKind.Sequential)]
public struct INTERNET_PROXY_INFO
{
    public INTERNET_OPEN_TYPE accessType;
    private fixed char proxy[500];
    private fixed char proxyBypass[500];
}

请注意,我已经尝试了该结构的所有可能变体:

1) proxyproxyBypassstringMarshalAs(ByValTStr, 500);

2) proxyproxyBypassstring 并为它们分配一个字符串,该字符串是 0 个字符中的 500 个;

3) 以上 2 个变体,但结构是 class.

所有 3 个 return PROXY 的正确 accessType 但其他 2 个字段是空字符串。

INTERNET_PROXY_INFO 需要一大块内存,WinINet 会为您设置字符串指针。

public class WinApi
{

public enum INTERNET_OPTION : uint { PROXY = 38 }

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct INTERNET_PROXY_INFOA
{
    public IntPtr accessType;
    public string proxy;
    public string proxyBypass;
}

[DllImport("wininet.dll", SetLastError = true)]
public static extern int InternetQueryOptionA([In] IntPtr hInternet, [In] INTERNET_OPTION option, [In, Out] IntPtr buffer, [In, Out] ref int bufferSize);

}

您可以分配一块内存并希望它足够大或询问函数:

int cb = 0;
WinApi.InternetQueryOptionA(IntPtr.Zero, WinApi.INTERNET_OPTION.PROXY, IntPtr.Zero, ref cb);
IntPtr data = Marshal.AllocCoTaskMem(cb);
int succ = WinApi.InternetQueryOptionA(IntPtr.Zero, WinApi.INTERNET_OPTION.PROXY, data, ref cb);
if (succ != 0)
{
    WinApi.INTERNET_PROXY_INFOA info = (WinApi.INTERNET_PROXY_INFOA) Marshal.PtrToStructure(data, typeof(WinApi.INTERNET_PROXY_INFOA));
    Console.WriteLine(string.Format("{2}: {0}|{1}", info.proxy, info.proxyBypass, info.accessType));
}
Marshal.FreeCoTaskMem(data);