1

这适用于 Visual Studio 2012 中的桌面 C# 应用程序。

我需要使用 C# 中的 WebBrowser 控件登录到 Windows Live 实例,让控件打开页面没什么,但登录让我很头疼。

我尝试了从 Google 收集到的大约 4 种不同的建议,但我没有正确登录。

这就是我所拥有的:

//FORM1 code
//Added reference to 'Microsoft Internet Controls'
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication3
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            webBrowser1.Url = new Uri("http://digitbot.com/live/");
        }
        SHDocVw.WebBrowser nativeBrowser;
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            nativeBrowser = (SHDocVw.WebBrowser)webBrowser1.ActiveXInstance;
            nativeBrowser.NewWindow2 += nativeBrowser_NewWindow2;
        }
        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            nativeBrowser.NewWindow2 -= nativeBrowser_NewWindow2;
            base.OnFormClosing(e);
        }

        void nativeBrowser_NewWindow2(ref object ppDisp, ref bool Cancel)
        {
            var popup = new Form2();
            popup.Show(this);
            ppDisp = popup.Browser.ActiveXInstance;
        }
    }
}



//FORM2 code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication3
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }
        public WebBrowser Browser
        {
            get { return webBrowser1; }
        }
    }
}

这会在第二个窗口中启动登录弹出窗口,但不知何故,它似​​乎永远不会完成该过程。

在浏览器中点击上面代码中的链接应该可以让您登录,并且应该显示日历事件的原始 JSON,然后是个人资料图片。我需要在 WebBrowser 控件中获得相同的结果。

任何帮助都会很棒,我被困住了。

4

1 回答 1

1

从来没有得到我最初的工作方法,所以我转而使用带有 REST 服务器端的 WebClient 和浏览器,因为我需要在用户注销的情况下做一些事情。

这是带有 WPF 的 C# Windows 8 端的基本设置:

static string client_id = "your-client-id";
static string client_secret = "your-client-secret";
static string accessTokenUrl = 
  String.Format(@"https://login.live.com/oauth20_token.srf?client_id={0}&client" + 
  @"_secret={1}&redirect_uri=https://login.live.com/oauth20_desktop.srf&grant_type" + 
  @"=authorization_code&code=", client_id, client_secret);
static string apiUrl = @"https://apis.live.net/v5.0/";
public Dictionary<string, string> tokenData = new Dictionary<string, string>(); 

这是我主窗口中的大部分代码:

private void getAccessToken()
{
    if (App.Current.Properties.Contains("auth_code"))
    {
        makeAccessTokenRequest(accessTokenUrl + App.Current.Properties["auth_code"]);
    }
}

private void makeAccessTokenRequest(string requestUrl)
{
    try
    {
        WebClient wc = new WebClient();
        wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(accessToken_DownloadStringCompleted);
        wc.DownloadStringAsync(new Uri(requestUrl));
        lError.Content = "";
    }
    catch (Exception ex)
    {
        lError.Content = "There has been an internet connection error.";
    }
}

void accessToken_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    tokenData = deserializeJson(e.Result);
    if (tokenData.ContainsKey("access_token"))
    {
        App.Current.Properties.Add("access_token", tokenData["access_token"]);
        App.Current.Properties.Add("refresh_token", tokenData["refresh_token"]);
        getUserInfo();
    }
}

private Dictionary<string, string> deserializeJson(string json)
{
    var jss = new JavaScriptSerializer();
    var d = jss.Deserialize<Dictionary<string, string>>(json);
    return d;
}

private void getUserInfo()
{
    if (App.Current.Properties.Contains("access_token"))
    {
        try
        {
            makeApiRequest(apiUrl + "me?access_token=" + App.Current.Properties["access_token"]);
            lError.Content = "";
        }
        catch (Exception ex)
        {
            lError.Content = "There has been an internet connection error.";
        }
    }
}

private void makeApiRequest(string requestUrl)
{
    try
    {
        WebClient wc = new WebClient();
        wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
        wc.DownloadStringAsync(new Uri(requestUrl));
        lError.Content = "";
    }
    catch (Exception ex)
    {
        lError.Content = "There has been an internet connection error.";
    }
}

void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    changeView(e.Result);
}

private void changeView(string result)
{
    string imgUrl = apiUrl + "me/picture?access_token=" + App.Current.Properties["access_token"];
    imgUser.Source = new BitmapImage(new Uri(imgUrl, UriKind.RelativeOrAbsolute));
    String code = "" + App.Current.Properties["refresh_token"];
    String auth = "" + App.Current.Properties["access_token"];

}

void browser_Closed(object sender, EventArgs e)
{
    try
    {
        getAccessToken();
        lError.Content = "";
    }
    catch (Exception ex)
    {
        lError.Content = "There has been an internet connection error.";
    }
} 

然后,Windows Live 授权将在此浏览器中进行,并在我们登录后消失。

浏览器的 XAML:

<Window x:Class="WpfApplication3.BrowserWindow"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      Title="Sign In" Height="460" Width="423.881" 
      ShowInTaskbar="False" WindowStartupLocation="CenterScreen">
    <Grid>
        <WebBrowser Height="419" HorizontalAlignment="Left" 
           Name="webBrowser" VerticalAlignment="Top" 
           Width="406" LoadCompleted="webBrowser_LoadCompleted" />
    </Grid>
</Window>

这是浏览器代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Text.RegularExpressions;

namespace WpfApplication3

{
    public partial class BrowserWindow : Window
    {
        static string scope = "wl.signin wl.calendars wl.offline_access wl.contacts_calendars";
        static string client_id = "your-client-id";
        static Uri signInUrl = new Uri(String.Format(@"https://login.live.com/oauth20" + 
          @"_authorize.srf?client_id={0}&redirect_uri=https://login.live.com/" + 
          @"oauth20_desktop.srf&response_type=code&scope={1}", client_id, scope));
        MainWindow mainWindow = new MainWindow();

        public BrowserWindow()
        {
            InitializeComponent();
            webBrowser.Navigate(signInUrl);
        }

        private void webBrowser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
        {
            if (e.Uri.AbsoluteUri.Contains("code="))
            {
                if (App.Current.Properties.Contains("auth_code"))
                {
                    App.Current.Properties.Clear();
                }
                string auth_code = Regex.Split(e.Uri.AbsoluteUri, "code=")[1];
                App.Current.Properties.Add("auth_code", auth_code);
                this.Close();
            }
        }
    }
} 

这是一个更冗长的解释的链接:http: //www.codeproject.com/Articles/497199/Switch-to-SMS-Text-Event-Reminders-When-Your-Ultra#live

于 2012-11-29T01:29:30.187 回答