c# - Process.Start url 隐藏 WindowStyle

标签 c# url process styles webclient

我有一个 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 服务器上用于获取播放列表的身份验证,它看起来像这样

有没有其他方法可以让这个过程不可见?

编辑: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 的网络 API 以重现我拥有的示例。

最佳答案

Windows 上 GUI 程序的入口点是著名的 WinMain() function .它看起来像这样:

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

hInstance 和 hPrevInstance 参数是遗留的,可以追溯到 <= 3 的 Windows 版本,这些版本还没有支持进程并且需要一个应用来处理一个任务本身的多个实例。 lpCmdLine 参数是命令行参数。

nCmdShow 是重要的,也是您问题的主题。预期值为 SW_HIDE、SW_SHOWNORMAL、SW_SHOWMAXIMIZE 或 SW_SHOWMINIMIZE。您可以自己轻松地将它们映射到可能的 ProcessWindowStyle 枚举值。

它也暴露在桌面快捷方式的属性中。例如:

enter image description here

我展开了运行组合框,注意与 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 不起作用。用户重新获得对该程序的控制权的唯一方法是使用任务管理器终止它。它也是可利用的,恶意软件可以启动程序并征用它,而用户永远不会注意到。

这样的程序可以防止这种情况发生的所有充分理由。您对此无能为力,程序会覆盖您的选择并拥有最终决定权。

关于c# - Process.Start url 隐藏 WindowStyle,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36962235/

相关文章:

c# - Azure 网站 - 502 - Web 服务器在充当网关或代理服务器时收到无效响应

c# - WPF 依赖属性 - 数据绑定(bind)不起作用

html - 在不执行 GET 的情况下检查重复内容

url - docker hub的url设计有什么意义?

c# - 有没有工具可以分析C#和WPF项目是否可以移植到Silverlight?

php - 帮助破解 Gruber 的自由 URL 正则表达式

ruby-on-rails - 如果我使用 w.keepalive,God Gem 会开始监视,但如果我使用 $god sidekiq start 则不会

ios - 如何以编程方式终止 iOS 中的进程

java - 从另一个java程序运行java程序

c# - 静态与实例方法用法