[英]Process.Start url with hidden WindowStyle
我有一个在服务器上验证我的凭据的URL。 有没有办法让它看不见? 简单的代码看起来完全像这样:
public void DoAuth()
{
String uri = GetUri();
ProcessStartInfo startInfo = new ProcessStartInfo(uri);
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
Process.Start(startInfo);
}
但是ProcessWindowStyle.Hidden
似乎没有做到这一点。 如果我将UseShellExecute
设置为false然后我收到Win32Exception
并显示消息The system cannot find the file specified
url是Spotify服务器上的身份验证以获取播放列表,它看起来像这样https://accounts.spotify.com/authorize/client_id=26d287105as12315e12ds56e31491889f3cd293..
还有其他方法可以使这个过程不可见吗?
编辑:http示例
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;
}
}
包含上述示例的整个.cs文件:
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;
}
}
}
它们被称为这样:
_auth.OnResponseReceivedEvent += _auth_OnResponseReceivedEvent;
_auth.StartHttpServer(8000);
_auth.DoAuth();
带有完整可运行样品的github url在这里: https : //github.com/JohnnyCrazy/SpotifyAPI-NET下载并运行Spotify测试以连接Spotify的web api以重现我的样本。
Windows上GUI程序的入口点是着名的WinMain()函数 。 它看起来像这样:
int CALLBACK WinMain(
_In_ HINSTANCE hInstance,
_In_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine,
_In_ int nCmdShow
);
hInstance和hPrevInstance参数是遗留的,并且可以追溯到Windows版本<= 3,尚未支持进程的版本,并且需要应用程序来处理任务本身的多个实例。 lpCmdLine参数是命令行参数。
nCmdShow
是您的重要问题和主题。 预期值为SW_HIDE,SW_SHOWNORMAL,SW_SHOWMAXIMIZE或SW_SHOWMINIMIZE。 您可以轻松地将它们映射到可能的ProcessWindowStyle枚举值。
它也暴露在桌面上的快捷方式属性中。 例如:
我展开了Run组合框,注意与ProcessWindowStyle枚举值的匹配。 除了Hidden
,那里有一丝麻烦。
典型的C程序将nCmdShow
参数直接传递给ShowWindow()函数以显示主窗口(省略错误检查):
HWND hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
ShowWindow(hWnd, nCmdShow);
你会对这样的节目感到满意。 然而,这并不是许多程序实际工作的方式。 他们检查 nCmdShow
的值并明确过滤掉SW_HIDDEN
。 或者他们恢复用户上次使用的窗口状态。 换句话说,他们这样做:
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);
这是有充分理由的。 恢复以前的状态是一个明显的可用性偏好,许多用户会更喜欢它以这种方式为浏览器工作。 我做。
对于快捷方式配置对话框中缺少Hidden
选项的更多信息,操作系统和精心设计的GUI程序都有意避免产生可用性噩梦。 程序启动的地方,但用户无法激活程序。 隐藏窗口没有任务栏按钮。 Alt + Tab不起作用。 用户重新获得对程序的控制权的唯一方法是使用任务管理器终止它。 它也是可利用的,恶意软件可以启动程序并征用它并且用户从不会注意到它。
这样一个程序阻止这种情况发生的所有好理由。 没有什么可以做的,程序会覆盖你的选择并对此有最后的发言权。
进入Visual Studio中的项目属性,并将项目类型更改为类库。 保存。 然后将其更改为Windows应用程序并保存。
这应该摆脱你没有明确创建自己的UI。
我认为你不需要开始一个新的流程来获得Spoitfy的授权。 您应该进行Get / Post调用并获取授权令牌,然后将其包含在您将来的API调用中。
GET https://accounts.spotify.com/authorize
我指的是Spoitfy的在线帮助页面。
https://developer.spotify.com/web-api/authorization-guide/
经典XY问题,您没有搜索隐藏窗口的方法, 您希望在没有涉及用户操作的情况下对用户进行身份验证 。
由于ImplicitGrantAuth
不适用于简单的HTTP请求,因此您需要一种解决方法:
虽然ImplicitGrantAuth
不是为这种任务而制作的,但它仍然可能但不干净。 你需要一个无头浏览器,你可以在你的C#App中控制它,比如Selenium 。
考虑使用Selenium代码( 相关SO问题 ):
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();
}
这只是伪正确的代码,但你应该明白这个想法。 使用您可以控制的无头浏览器,填写所有表单输入,提交和分析URL。 Facebook登录将是相同的原则。
但是请注意: OAuth不是为这种类型的使用而设计的,并且您可能不应该在生产中使用这种hacky变通方法
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.