I have a url that authenticates my credentials on a server. Is there a way to make it invisible? The simple code looks exactly like this:
public void DoAuth()
{
String uri = GetUri();
ProcessStartInfo startInfo = new ProcessStartInfo(uri);
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
Process.Start(startInfo);
}
however ProcessWindowStyle.Hidden
doesn't seem to do the trick. If I set UseShellExecute
to false then I get Win32Exception
with the message The system cannot find the file specified
The url is a authentication on Spotify server to get the playlists and it looks something like this https://accounts.spotify.com/authorize/client_id=26d287105as12315e12ds56e31491889f3cd293..
Is there an 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 sample 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 a full runnable sampe is here: https://github.com/JohnnyCrazy/SpotifyAPI-NET Download it and run the Spotify Test to connect to Spotify's web api to reproduce the sample I have.
The entrypoint of a GUI program on Windows is the famous 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 legacy and date back to Windows versions <= 3, versions that did not have support processes yet and required an app to take care of multiple instances of a task itself. The lpCmdLine argument are the command line arguments.
nCmdShow
is the important one and the subject of your question. Expected values are SW_HIDE, SW_SHOWNORMAL, SW_SHOWMAXIMIZE or SW_SHOWMINIMIZE. You can easily map them yourself to the possible ProcessWindowStyle enum values.
It is also exposed in the properties of a shortcut on your desktop. For example:
I expanded the Run combobox, note the match with the ProcessWindowStyle enum values. Except Hidden
, hint of trouble there.
A typical C program passes the nCmdShow
argument directly to the ShowWindow() function to display the main window (error checking omitted):
HWND hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
ShowWindow(hWnd, nCmdShow);
You'd be happy with such a program. It is however not the way many programs actually work. They check the value of nCmdShow
and explicitly filter out SW_HIDDEN
. Or they restore the window state 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 for a done for good reasons. Restoring the previous state is an obvious usability preference, many users will prefer it works that way for a browser for example. I do.
More to the point for the missing Hidden
option in the shortcut configuration dialog, both the OS and well-designed GUI programs intentionally avoid creating a usability nightmare. Where the program gets started but there is no way for the user to activate the program. There is no taskbar button for a hidden window. Alt+Tab does not work. The only way the user can regain control over the program is to terminate it with Task Manager. It is also exploitable, malware could start a program and commandeer it and the user never notices.
All good reasons why such a program prevents this from happening. Nothing you can do about it, the program overrides your choice and has the last say about it.
Go into the project properties in Visual Studio and change your project type to Class Library. Save it. Then change it to Windows Application and save.
That should get rid of any UI you are not explicitly creating yourself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With