2

I am coding against the Microsoft.OneDrive.SDK and I have also included the Microsoft.OneDrive.SDK.Authentication. The issue I am having is that I have a console application which opens just a white window where it clearly is prompting me to log in.

Code:

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;
        }
    }
}
Community
  • 1
  • 1
jdave
  • 845
  • 2
  • 11
  • 27
  • while debugging the application, if you put a breakpoint on the line `if( oneDriveClient == null)` - is oneDriveClient still null? I imagine that it isn't. Hence, the program will skip over all that code and jump to the try block below it. – prestonsmith Jan 20 '17 at 23:25
  • What is the behavior you are trying to achieve? Unless you have obtained a token by other means, the user will need to authenticate themselves. – Christopher Thomas Jan 20 '17 at 23:37
  • @ChristopherThomas, I am trying to understand why the I am prompted with a white box but nothing is loaded to it. – jdave Jan 20 '17 at 23:39
  • @prestonsmith the `oneDriveClient` is still null since it is a default -- and it is then hitting the if. – jdave Jan 20 '17 at 23:40

2 Answers2

1

Digging through the source code, it looks like the default ui for getting auth details is a Windows Form:

This is a bit new to me, but another post on the subject of running Windows Forms from a console app seems to call Application.EnableVisualStyles(); as the first line in Main().

Perhaps this will allow your console app to draw things properly.

Community
  • 1
  • 1
  • Interesting, however, my logic lives within an `async Task` do you know if there is a way to simply a way to call my `Task` with the `Application.Run()` rather than having to create a new `Form`? – jdave Jan 23 '17 at 14:48
  • My background isn't really Win Forms so forgive me if this doesn't make sense in relation to your comment. msaAuthenticationProvider.AuthenticateUserAsync() from the SDK is trying to create a form for the user to supply credentials (which I assume is the white box you are getting). If you enable visual styles, does the white box show any content? – Christopher Thomas Jan 23 '17 at 15:50
0

MsaAuthenticationProvider uses Windows Forms. In order to draw forms correctly, you need to start running a standard messaging loop. This can be done by Application.Run method.
Another problem is that by calling .Wait() you will make current thread block.

If you don't want to create any forms, you can create your own ApplicationContext, use Application.Run(ApplicationContext) constructor, and then close it manually:

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
        }
    }
}

Or you can just call an Application.Run() overload with no parameters and utilize .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;
        }
    }
}
Yeldar Kurmangaliyev
  • 33,467
  • 12
  • 59
  • 101