Click here to Skip to main content
16,016,489 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I'm trying to retrieve and read emails from my Outlook mail. Unfortunately my mailbox uses Authenticity, which I need to deal with. I have tried a mailbox that does not use Authenticity and the code works. I followed the instructions here
https://www.emailarchitect.net/eagetmail/ex/c/22.aspx

(I used the library to read a mailbox that does not use OAuth). So I registered my application on Microsoft Azure as instructed (except for authentication, which was the last step). Unfortunately I get this error

System.ComponentModel.Win32Exception
HResult=0x80004005 Message=System cannot find the specified file. Source=System.Diagnostics.Process

I also tried another library https://afterlogic.com/mailbee-net/docs/OAuth2MicrosoftRegularAccountsInstalledApps.html

But with the same result It is larger project, so I will post method where I am getting the error. I will paste more code, if you will need it. Feel free to ask. Thanks for any advice.(The documentation is great, so I didn't want to change it)

C#
const string clientID = "Client ID";
        const string clientSecret = "client Secret";
        const string scope = "https://outlook.office.com/IMAP.AccessAsUser.All%20https://outlook.office.com/POP.AccessAsUser.All%20offline_access%20email%20openid";
        const string authUri = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize";
        const string tokenUri = "https://login.microsoftonline.com/common/oauth2/v2.0/token";

        static int GetRandomUnusedPort()
        {
            var listener = new TcpListener(IPAddress.Loopback, 0);
            listener.Start();
            var port = ((IPEndPoint)listener.LocalEndpoint).Port;
            listener.Stop();
            return port;
        }

        async void DoOauthAndRetrieveEmail()
        {
            // Creates a redirect URI using an available port on the loopback address.
            string redirectUri = string.Format("http://127.0.0.1:{0}/", GetRandomUnusedPort());
            Console.WriteLine("redirect URI: " + redirectUri);

            // Creates an HttpListener to listen for requests on that redirect URI.
            var http = new HttpListener();
            http.Prefixes.Add(redirectUri);
            Console.WriteLine("Listening ...");
            http.Start();

            // Creates the OAuth 2.0 authorization request.
            string authorizationRequest = string.Format("{0}?response_type=code&scope={1}&redirect_uri={2}&client_id={3}&prompt=login",
                authUri,
                scope,
                Uri.EscapeDataString(redirectUri),
                clientID
            );

            // Opens request in the browser.
            //There is issue
            System.Diagnostics.Process.Start(authorizationRequest);

            // Waits for the OAuth authorization response.
            var context = await http.GetContextAsync();

            // Brings the Console to Focus.
            BringConsoleToFront();

            // Sends an HTTP response to the browser.
            var response = context.Response;
            string responseString = string.Format("<html><head></head><body>Please return to the app and close current window.</body></html>");
            var buffer = Encoding.UTF8.GetBytes(responseString);
            response.ContentLength64 = buffer.Length;
            var responseOutput = response.OutputStream;
            Task responseTask = responseOutput.WriteAsync(buffer, 0, buffer.Length).ContinueWith((task) =>
            {
                responseOutput.Close();
                http.Stop();
                Console.WriteLine("HTTP server stopped.");
            });

            // Checks for errors.
            if (context.Request.QueryString.Get("error") != null)
            {
                Console.WriteLine(string.Format("OAuth authorization error: {0}.", context.Request.QueryString.Get("error")));
                return;
            }

            if (context.Request.QueryString.Get("code") == null)
            {
                Console.WriteLine("Malformed authorization response. " + context.Request.QueryString);
                return;
            }

            // extracts the code
            var code = context.Request.QueryString.Get("code");
            Console.WriteLine("Authorization code: " + code);

            string responseText = await RequestAccessToken(code, redirectUri);
            Console.WriteLine(responseText);

            OAuthResponseParser parser = new OAuthResponseParser();
            parser.Load(responseText);

            var user = parser.EmailInIdToken;
            var accessToken = parser.AccessToken;

            Console.WriteLine("User: {0}", user);
            Console.WriteLine("AccessToken: {0}", accessToken);

            RetrieveMailWithXOAUTH2(user, accessToken);
        }


What I have tried:

Using different libraries. A lot of googling.
Posted
Updated 24-Jul-22 23:45pm
Comments
Richard Deeming 25-Jul-22 4:39am    
If Process.Start can't open an https: URL, that suggests there's no web browser installed or configured. Is this code running on a server, or is it a desktop application?

Microsoft's recommended email library is MailKit - you might have better luck with that:
GitHub - jstedfast/MailKit: A cross-platform .NET library for IMAP, POP3, and SMTP.[^]
MimeKit[^]
Petr Barabáš 25-Jul-22 4:43am    
No, it's not going anywhere. I just tried it in the console. So should I edit the App file?
Richard Deeming 25-Jul-22 5:02am    
As I said, if you're getting a "file not found" error trying to launch an https: URL via Process.Start, that would suggest you don't have a default browser installed and configured.

What happens if you right-click on the start button, select "Run", type in eg: "https://www.codeproject.com/", and click "OK" - do you get a browser, or do you get an error message?

Also, which version of .NET are you using? There are some differences in the Process class between .NET Framework 4.x and .NET Core/5/6/...
Petr Barabáš 25-Jul-22 5:17am    
Maybe I should paste code where I am using MailKit and it is much shorter?
Richard Deeming 25-Jul-22 5:35am    
Your question says you're getting an error when you try to launch an https: URL using Process.Start.

Either your system doesn't have a web browser installed and configured, or you're using .NET Core, .NET 5, or .NET 6, where the Process class behaves differently.

1 solution

Quote:
I am using .NET CORE 3.1
In which case, you need to explicitly specify that you want to UseShellExecute to launch your URL.
C#
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
{
    FileName = authorizationRequest,
    UseShellExecute = true,
});
The default is true on .NET Framework apps and false on .NET Core apps.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900