Process.Start url with hidden WindowStyle

I have a url that authenticates my credentials on the server. Is there any way to make it invisible? Simple code looks something like this:

public void DoAuth() { String uri = GetUri(); ProcessStartInfo startInfo = new ProcessStartInfo(uri); startInfo.WindowStyle = ProcessWindowStyle.Hidden; Process.Start(startInfo); } 

however ProcessWindowStyle.Hidden does not seem to do the trick. If I set UseShellExecute to false, I get a Win32Exception with the message The system cannot find the file specified URL is authentication on the Spotify server to receive playlists and looks something like this: https://accounts.spotify.com/authorize/client_id=26d287105as12315e12ds56e31491889f3cd293..

Is there any other way to make this process invisible?

Edit: http sample

 public void DoAuth() { String uri = GetUri(); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri); HttpWebResponse webResponse; try { webResponse = (HttpWebResponse)request.GetResponse(); Console.WriteLine("Error code: {0}", webResponse.StatusCode); using (Stream data = webResponse.GetResponseStream()) using (var reader = new StreamReader(data)) { //do what here? } } catch (Exception e) { throw; } } 

The entire .cs file containing the example above:

 using SpotifyAPI.Web.Enums; using SpotifyAPI.Web.Models; using System; using System.IO; using System.Net; using System.Text; using System.Threading; namespace SpotifyAPI.Web.Auth { public class ImplicitGrantAuth { public delegate void OnResponseReceived(Token token, String state); private SimpleHttpServer _httpServer; private Thread _httpThread; public String ClientId { get; set; } public String RedirectUri { get; set; } public String State { get; set; } public Scope Scope { get; set; } public Boolean ShowDialog { get; set; } public event OnResponseReceived OnResponseReceivedEvent; /// <summary> /// Start the auth process (Make sure the internal HTTP-Server ist started) /// </summary> public void DoAuth() { String uri = GetUri(); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri); HttpWebResponse webResponse; try { webResponse = (HttpWebResponse)request.GetResponse(); Console.WriteLine("Error code: {0}", webResponse.StatusCode); using (Stream data = webResponse.GetResponseStream()) using (var reader = new StreamReader(data)) { //nothing } } catch (Exception e) { throw; } /*ProcessStartInfo startInfo = new ProcessStartInfo(uri); startInfo.WindowStyle = ProcessWindowStyle.Hidden; Process.Start(startInfo); */ } private String GetUri() { StringBuilder builder = new StringBuilder("https://accounts.spotify.com/authorize/?"); builder.Append("client_id=" + ClientId); builder.Append("&response_type=token"); builder.Append("&redirect_uri=" + RedirectUri); builder.Append("&state=" + State); builder.Append("&scope=" + Scope.GetStringAttribute(" ")); builder.Append("&show_dialog=" + ShowDialog); return builder.ToString(); } /// <summary> /// Start the internal HTTP-Server /// </summary> public void StartHttpServer(int port = 80) { _httpServer = new SimpleHttpServer(port, AuthType.Implicit); _httpServer.OnAuth += HttpServerOnOnAuth; _httpThread = new Thread(_httpServer.Listen); _httpThread.Start(); } private void HttpServerOnOnAuth(AuthEventArgs e) { OnResponseReceivedEvent?.Invoke(new Token { AccessToken = e.Code, TokenType = e.TokenType, ExpiresIn = e.ExpiresIn, Error = e.Error }, e.State); } /// <summary> /// This will stop the internal HTTP-Server (Should be called after you got the Token) /// </summary> public void StopHttpServer() { _httpServer.Dispose(); _httpServer = null; } } } 

And they are called like this:

 _auth.OnResponseReceivedEvent += _auth_OnResponseReceivedEvent; _auth.StartHttpServer(8000); _auth.DoAuth(); 

The github url with the full runnable sampe is here: https://github.com/JohnnyCrazy/SpotifyAPI-NET Download it and run the Spotify Test to connect to the Spotify web api to play the sample that I have.

+6
source share
4 answers

The classic XY problem, you are not looking for a way to hide the window, you want to authenticate the user without user intervention .

Since ImplicitGrantAuth will not work with simple HTTP requests, you will need a workaround:

Userless Authentication: Headless Browser

Until ImplicitGrantAuth was created for this kind of task, it is still possible, but not clean. You will need a browser without a header that you can control in your C # application, such as Selenium .

Consider the following code using Selenium (a related SO question ):

 void DoAuth() { IWebDriver driver = new FirefoxDriver(); driver.Navigate().GoToUrl(GetUri()); IWebElement query = driver.FindElement(By.Name("username")); //You need to search for the correct element query.SendKeys("username"); query = driver.FineElement(By.Name("password")); query.SendKeys("password"); //Somehow submit the form and wait till you get the Token via URL //Thread.Sleep(5000); String urlWithToken = driver.Url; //Analyze it and get the token out of it driver.Quit(); } 

This is just pseudo-correct code, but you should get this idea. Use a mute browser that you can control, fill out all form input, submit and parse URLs. Facebook-Login will be the same principle.

But note: OAuth was not intended for this type of use, and you probably should not use such hacker workarounds in production

+1
source

The first point of a GUI program in Windows is the well-known WinMain () function. It looks like this:

  int CALLBACK WinMain( _In_ HINSTANCE hInstance, _In_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow ); 

The hInstance and hPrevInstance arguments are obsolete and are dated by versions of Windows <= 3, versions that did not yet support support processes, and an application was needed to serve several instances of the task itself. The lpCmdLine argument is command line arguments.

nCmdShow is important and subject to your question. Expected values: SW_HIDE, SW_SHOWNORMAL, SW_SHOWMAXIMIZE or SW_SHOWMINIMIZE. You can easily match them with the possible values ​​of the ProcessWindowStyle enumeration.

It also appears in the shortcut properties on the desktop. For instance:

enter image description here

I expanded the Run field, note the match with the values ​​of the ProcessWindowStyle enumeration. Besides Hidden , a hint of trouble.


A typical C program passes the nCmdShow argument directly to the ShowWindow () function to display the main window (a validation error is omitted):

  HWND hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); ShowWindow(hWnd, nCmdShow); 

You will be pleased with such a program. However, this is not how many programs actually work. They check the value of nCmdShow and explicitly filter SW_HIDDEN . Or they restore the state of the window that the user last used. In other words, they do this:

  HWND hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (nCmdShow == SW_HIDDEN) nCmdShow = SW_SHOWNORMAL; if (HasPreviousWindowState) nCmdShow = PreviousWindowState; // optional ShowWindow(hWnd, nCmdShow); 

This is done for good reason. Restoring to its former state is an obvious preference for usability, many users will prefer that it works just like that, for example, for a browser. I do.

More about the missing Hidden option in the shortcut configuration dialog box, both the OS and well-designed GUI programs intentionally avoid creating a usability nightmare. When the program starts, but the user is not allowed to activate the program. There is no taskbar button for a hidden window. Alt + Tab does not work. The only way to return the user control over the program is to terminate it using the task manager. It can also be used, malware can run the program and execute the command, and the user never notices.

All good reasons why such a program interferes with this. You can not do anything about it, the program redefines your choice and has the last word.

+3
source

Go to the project properties in Visual Studio and change the project type to Class Library. Save it. Then change it to the Windows application and save.

This should get rid of any user interface that you are not explicitly creating yourself.

+2
source

I don’t think you need to start a new process in order to get authorization from Spoitfy. You should make a Get / Post call and get an authorization token, and then include it in your future API calls.

 GET https://accounts.spotify.com/authorize 

I mean the Spoitfy man page.

 https://developer.spotify.com/web-api/authorization-guide/ 
+2
source

All Articles