[英]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.