InternetQueryOption с INTERNET_OPTION_PROXY возвращает пустые строки вместо установленных настроек прокси - PullRequest
0 голосов
/ 21 октября 2019

Используется InternetOpen с установленным прокси-сервером (127.0.0.1:5401) и обходом (<-loopback>), но при выполнении InternetQueryOption с параметром, установленным на INTERNET_OPTION_PROXY, возвращаемые строки в структуре INTERNET_PROXY_INFO, пустые, но тип доступа правильный, INTERNET_OPEN_TYPE_PROXY.

. Здесь sig для InternetQueryOption и структуры INTERNET_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) proxy и proxyBypass, являющиеся string с MarshalAs(ByValTStr, 500);

2) proxy иproxyBypass равен string и присваивает им строку, равную 500 из 0 символов;

3) 2 вышеупомянутых варианта, но со структурой, являющейся классом.

Все 3 возвращаютправильный accessType из PROXY, но остальные 2 поля являются пустыми строками.

1 Ответ

0 голосов
/ 21 октября 2019

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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...