在WinInet中使用用户名和密码

时间:2014-04-29 18:11:49

标签: c#

我正在使用WinInet为我的应用程序WebBrowser控件应用代理,该方法的好处是它不会影响系统的代理,只会将代理应用于我的应用程序。但是它仅适用于没有用户名和密码的代理。

这是代码

private const int INTERNET_OPEN_TYPE_DIRECT = 1;
private const int INTERNET_OPEN_TYPE_PRECONFIG = 0;
public static string ApplicationName;

[DllImport("user32.dll", SetLastError = true)]
public static IntPtr FindWindow(string lpClassName, string lpWindowName);

[DllImport("user32.dll")]
public static bool ShowWindow(IntPtr hwnd, User32.WindowShowStyle nCmdShow);

[DllImport("user32.dll")]
public static bool EnableWindow(IntPtr hwnd, bool enabled);

[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static IntPtr InternetOpen(string lpszAgent, int dwAccessType, string lpszProxyName, string lpszProxyBypass, int dwFlags);

[DllImport("wininet.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static bool InternetCloseHandle(IntPtr hInternet);

[DllImport("wininet.dll", CharSet = CharSet.Ansi, SetLastError = true)]
private static bool InternetSetOption(IntPtr hInternet, User32.InternetOption dwOption, IntPtr lpBuffer, int lpdwBufferLength);

[DllImport("wininet.dll", EntryPoint = "InternetQueryOption", CharSet = CharSet.Ansi, SetLastError = true)]
private static bool InternetQueryOptionList(IntPtr handle, User32.InternetOption optionFlag, ref User32.InternetPerConnOptionList optionList, ref int size);

public static bool SetConnectionProxy(string proxyServer)
{
  IntPtr hInternet = User32.InternetOpen(User32.ApplicationName, 1, (string) null, (string) null, 0);
  User32.InternetPerConnOption[] internetPerConnOptionArray = new User32.InternetPerConnOption[2]
  {
    new User32.InternetPerConnOption()
    {
      dwOption = 1,
      Value = {
        dwValue = 2
      }
    },
    new User32.InternetPerConnOption()
    {
      dwOption = 2,
      Value = {
        pszValue = Marshal.StringToHGlobalAnsi(proxyServer)
      }
    }
  };
  IntPtr ptr1 = Marshal.AllocCoTaskMem(Marshal.SizeOf((object) internetPerConnOptionArray[0]) + Marshal.SizeOf((object) internetPerConnOptionArray[1]));
  IntPtr ptr2 = ptr1;
  foreach (User32.InternetPerConnOption internetPerConnOption in internetPerConnOptionArray)
  {
    Marshal.StructureToPtr((object) internetPerConnOption, ptr2, false);
    ptr2 = (IntPtr) ((int) ptr2 + Marshal.SizeOf((object) internetPerConnOption));
  }
  User32.InternetPerConnOptionList perConnOptionList = new User32.InternetPerConnOptionList()
  {
    pOptions = ptr1
  };
  perConnOptionList.Size = Marshal.SizeOf((object) perConnOptionList);
  perConnOptionList.Connection = IntPtr.Zero;
  perConnOptionList.OptionCount = internetPerConnOptionArray.Length;
  perConnOptionList.OptionError = 0;
  int num1 = Marshal.SizeOf((object) perConnOptionList);
  IntPtr num2 = Marshal.AllocCoTaskMem(num1);
  Marshal.StructureToPtr((object) perConnOptionList, num2, true);
  bool flag = User32.InternetSetOption(hInternet, User32.InternetOption.InternetOptionPerConnectionOption, num2, num1);
  Marshal.FreeCoTaskMem(ptr1);
  Marshal.FreeCoTaskMem(num2);
  User32.InternetCloseHandle(hInternet);
  if (!flag)
    throw new ApplicationException(" Set Internet Option Failed!");
  else
    return true;
}

private static User32.InternetPerConnOptionList GetSystemProxy()
{
  User32.InternetPerConnOption[] internetPerConnOptionArray = new User32.InternetPerConnOption[3]
  {
    new User32.InternetPerConnOption()
    {
      dwOption = 1
    },
    new User32.InternetPerConnOption()
    {
      dwOption = 2
    },
    new User32.InternetPerConnOption()
    {
      dwOption = 3
    }
  };
  IntPtr num = Marshal.AllocCoTaskMem(Marshal.SizeOf((object) internetPerConnOptionArray[0]) + Marshal.SizeOf((object) internetPerConnOptionArray[1]) + Marshal.SizeOf((object) internetPerConnOptionArray[2]));
  IntPtr ptr = num;
  foreach (User32.InternetPerConnOption internetPerConnOption in internetPerConnOptionArray)
  {
    Marshal.StructureToPtr((object) internetPerConnOption, ptr, false);
    ptr = (IntPtr) ((int) ptr + Marshal.SizeOf((object) internetPerConnOption));
  }
  User32.InternetPerConnOptionList optionList = new User32.InternetPerConnOptionList()
  {
    pOptions = num
  };
  optionList.Size = Marshal.SizeOf((object) optionList);
  optionList.Connection = IntPtr.Zero;
  optionList.OptionCount = internetPerConnOptionArray.Length;
  optionList.OptionError = 0;
  int size = Marshal.SizeOf((object) optionList);
  if (!User32.InternetQueryOptionList(IntPtr.Zero, User32.InternetOption.InternetOptionPerConnectionOption, ref optionList, ref size))
    throw new ApplicationException(" Set Internet Option Failed! ");
  else
    return optionList;
}

public static bool RestoreSystemProxy()
{
  IntPtr hInternet = User32.InternetOpen(User32.ApplicationName, 1, (string) null, (string) null, 0);
  User32.InternetPerConnOptionList systemProxy = User32.GetSystemProxy();
  int num1 = Marshal.SizeOf((object) systemProxy);
  IntPtr num2 = Marshal.AllocCoTaskMem(num1);
  Marshal.StructureToPtr((object) systemProxy, num2, true);
  bool flag = User32.InternetSetOption(hInternet, User32.InternetOption.InternetOptionPerConnectionOption, num2, num1);
  Marshal.FreeCoTaskMem(systemProxy.pOptions);
  Marshal.FreeCoTaskMem(num2);
  if (!flag)
    throw new ApplicationException(" Set Internet Option Failed! ");
  User32.InternetSetOption(hInternet, User32.InternetOption.InternetOptionSettingsChanged, IntPtr.Zero, 0);
  User32.InternetSetOption(hInternet, User32.InternetOption.InternetOptionRefresh, IntPtr.Zero, 0);
  User32.InternetCloseHandle(hInternet);
  return true;
}

public enum WindowShowStyle : uint
{
  Hide = 0U,
  ShowNormal = 1U,
  ShowMinimized = 2U,
  Maximize = 3U,
  ShowMaximized = 3U,
  ShowNormalNoActivate = 4U,
  Show = 5U,
  Minimize = 6U,
  ShowMinNoActivate = 7U,
  ShowNoActivate = 8U,
  Restore = 9U,
  ShowDefault = 10U,
  ForceMinimized = 11U,
}

private enum InternetOption
{
  InternetOptionRefresh = 37,
  InternetOptionSettingsChanged = 39,
  InternetOptionPerConnectionOption = 75,
}

private enum InternetOptionPerConnFlags
{
  ProxyTypeDirect = 1,
  ProxyTypeProxy = 2,
  ProxyTypeAutoProxyUrl = 4,
  ProxyTypeAutoDetect = 8,
}

private struct InternetPerConnOption
{
  public int dwOption;
  public User32.InternetPerConnOptionOptionUnion Value;
}

private struct InternetPerConnOptionList
{
  public int Size;
  public IntPtr Connection;
  public int OptionCount;
  public int OptionError;
  public IntPtr pOptions;
}

[StructLayout(LayoutKind.Explicit)]
private struct InternetPerConnOptionOptionUnion
{
  [FieldOffset(0)]
  public int dwValue;
  [FieldOffset(0)]
  public IntPtr pszValue;
  [FieldOffset(0)]
  private readonly System.Runtime.InteropServices.ComTypes.FILETIME ftValue;
}

private enum InternetPerConnOptionEnum
{
  InternetPerConnFlags = 1,
  InternetPerConnProxyServer = 2,
  InternetPerConnProxyBypass = 3,
  InternetPerConnAutoconfigUrl = 4,
  InternetPerConnAutodiscoveryFlags = 5,
  InternetPerConnAutoconfigSecondaryUrl = 6,
  InternetPerConnAutoconfigReloadDelayMins = 7,
  InternetPerConnAutoconfigLastDetectTime = 8,
  InternetPerConnAutoconfigLastDetectUrl = 9,
  InternetPerConnFlagsUi = 10,
}

问题:我如何使用该代码来应用具有用户名和密码的代理?

备注

  1. 我知道这里有几个类似的问题,但我不能 从中得到一个好的答案。
  2. 我听说这可以使用InternetSetOption来实现 我找不到如何实现这个原因我没有足够的 关于windoes功能等的知识......

1 个答案:

答案 0 :(得分:0)

http://msdn.microsoft.com/en-us/library/windows/desktop/aa385328(v=vs.85).aspx

中显示的INTERNET_OPTION_PROXY_USERNAMEINTERNET_OPTION_PROXY_PASSWORD {@ 1}}和{{1}}中设置代理凭据的正确选项

可能需要实现IAuthenticate,因为其他调用实际上是针对WinINET句柄,当您使用Web浏览器控件时,这些句柄不会公开。