OneDrive SDK 为 OAuth 显示空白 window

OneDrive SDK showing empty White window for OAuth

我正在根据 Microsoft.OneDrive.SDK 进行编码,并且我还包含了 Microsoft.OneDrive.SDK.Authentication。我遇到的问题是我有一个控制台应用程序,它只打开一个白色 window,它显然在提示我登录。

代码:

using System;
using System.Threading.Tasks;
using Microsoft.OneDrive.Sdk;
using Microsoft.OneDrive.Sdk.Authentication;

namespace SecondTake_OneDrive_SDK
{
class Program
{
    [STAThread]
    static void Main()
    {
        RunTask().Wait();
    }

    static async Task RunTask(OneDriveClient oneDriveClient = null)
    {
        Task authTask = null;
        if (oneDriveClient == null)
        {
            var msaAuthenticationProvider = new MsaAuthenticationProvider("CLIENT_ID",null, "https://login.live.com/oauth20_desktop.srf", new[] { "onedrive.readonly", "wl.signin" }, null, new CredentialVault("CLIENT_ID));
            authTask =  msaAuthenticationProvider.AuthenticateUserAsync();
        }
        try
        {
            await authTask;
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw;
        }
    }
}

通过 source code 挖掘,看起来获取身份验证详细信息的默认 ui 是 Windows 表单:

这对我来说有点新,但是 another post 关于 运行 Windows 控制台应用程序的表单似乎调用 Application.EnableVisualStyles();作为 Main() 中的第一行。

也许这会让您的控制台应用程序正确绘制内容。

MsaAuthenticationProvider 使用 Windows 表格。为了正确绘制表单,您需要启动 运行 标准消息循环。这可以通过 Application.Run 方法来完成。
另一个问题是,通过调用 .Wait() 您将使当前线程阻塞。

如果不想创建任何表单,可以创建自己的ApplicationContext,使用Application.Run(ApplicationContext)构造函数,然后手动关闭它:

class Program
{
    [STAThread]
    static void Main()
    {
        var appContext = new ApplicationContext();
        RunTask(appContext); // run task asynchronously, pass ApplicationContext
        Application.Run(); // start processing messages
    }

    static async Task RunTask(ApplicationContext appContext, OneDriveClient oneDriveClient = null)
    {
        try
        {
            Task authTask = null;
            if (oneDriveClient == null)
            {
                var msaAuthenticationProvider = new MsaAuthenticationProvider("CLIENT_ID",null, "https://login.live.com/oauth20_desktop.srf", new[] { "onedrive.readonly", "wl.signin" }, null, new CredentialVault("CLIENT_ID));
                authTask =  msaAuthenticationProvider.AuthenticateUserAsync();
            }

            await authTask;
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw;
        }
        finally
        {
            appContext.ExitThread(); // stop messaging loop
        }
    }
}

或者您可以调用 Application.Run() overload with no parameters 并利用 .ContinueWith:

class Program
{
    [STAThread]
    static void Main()
    {
        RunTask().ContinueWith(t => { Application.Exit(); }); // run task asynchronously, then exit
        Application.Run(); // start processing messages
    }

    static async Task RunTask(OneDriveClient oneDriveClient = null)
    {
        try
        {
            Task authTask = null;
            if (oneDriveClient == null)
            {
                var msaAuthenticationProvider = new MsaAuthenticationProvider("CLIENT_ID",null, "https://login.live.com/oauth20_desktop.srf", new[] { "onedrive.readonly", "wl.signin" }, null, new CredentialVault("CLIENT_ID));
                authTask =  msaAuthenticationProvider.AuthenticateUserAsync();
            }

            await authTask;
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw;
        }
    }
}