C# InternetQueryOption with INTERNET_OPTION_PROXY返回空字符串,而不是设置代理设置

C# InternetQueryOption with INTERNET_OPTION_PROXY返回空字符串,而不是设置代理设置,c#,winapi,pinvoke,wininet,C#,Winapi,Pinvoke,Wininet,在设置代理服务器(127.0.0.1:5401)和旁路()的情况下使用InternetOpen),但在执行InternetQueryOption时,选项设置为internetoption\u proxy,返回的字符串在internetproxy\u INFO结构中为空,但访问类型正确,互联网\u打开\u类型\u代理 这是InternetQueryOption的sig和internetproxy\u INFO结构,可能我做错了什么: [DllImport("wininet.dll", SetLas

在设置代理服务器(
127.0.0.1:5401
)和旁路(
)的情况下使用
InternetOpen
),但在执行
InternetQueryOption
时,选项设置为
internetoption\u proxy
,返回的字符串在
internetproxy\u INFO
结构中为空,但访问类型正确,
互联网\u打开\u类型\u代理

这是
InternetQueryOption
的sig和
internetproxy\u 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)
proxy
proxyBypass
marshallas(ByValTStr,500)
一起成为
string

2)
proxy
proxyBypass
string
并为其分配一个0个字符中的500个字符的字符串

3) 上面的两个变体,但结构是一个类


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

INTERNET\u PROXY\u信息需要很大的内存,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);

nvm,它确实有效,但仅适用于ANSI版本的
InternetQueryOption
。如果是unicode版本,则返回类似
瑨灴ㄽ㜲〮〮\u312e㠺㠸‸瑨灴㵳㈱⸷⸰⸰㨱㠸㠸栀,考虑到可以通过unicode版本检索用户代理名称,这很奇怪。WinInet的某些部分实际上与Ansi一样工作得更好。我明天可以尝试Unicode,但即使这样,这也不是获得代理的首选方式。IEv5添加了Microsoft建议您使用的不同的“每连接”选项。INTERNET\u选项\u代理不支持Unicode AFAIK。使用Unicode的INTERNET\u选项\u PER\u CONNECTION\u选项,但它可能只是调用Ansi函数并转换结果。回复较晚,但我在
InternetQueryOptionW
中找到了使用它的方法。Sins字符串在unicode版本的函数中使用时,默认情况下作为LPWStr封送。
INTERNET\u选项\u代理
工作的方法是将属性
[MarshalAs(UnmanagedType.LPStr)]应用于
代理
proxyBypass
字段
InternetQueryOptionW
只需在我测试的Windows版本上调用它不理解的选项和它不理解的
InternetQueryOptionA
marshallas(UnmanagedType.LPStr)
与我为结构所做的
CharSet.Ansi
相同。