【问题标题】:How to close tab in external web browser?如何关闭外部网络浏览器中的选项卡?
【发布时间】:2012-03-30 23:47:13
【问题描述】:

我正在编写一个桌面应用程序,其中一部分是通过 OAuth 2.0 流程。

步骤如下:

  1. 开始进程 - 打开带有登录页面的网络浏览器。
  2. 用户登录并授权我的应用。
  3. 在后台搜索具有特定名称的进程,将其(名称)保存在应用程序中。
  4. 最后我关闭了网络浏览器。

问题在于,如果用户之前在网络浏览器中打开了一些选项卡 - 在第 1 点。添加了新选项卡,在第 4 点。所有内容都已关闭(带有所有选项卡的网络浏览器)。

你能告诉我是否有办法在网络浏览器中关闭单个标签吗? 或者也许还有其他/更简单的方式来通过 OAuth?

作为手动解决方案,我将简单地向用户显示信息“现在您可以关闭此选项卡”,但我想自动执行此操作。

这是 C# .Net 4.0 WPF 项目。

string strAuthUrl = "http://accounts.example.com/login",
       strAuthCode = string.Empty;

// Request authorization from the user (by opening a browser window):
ProcessStartInfo startInfo = new ProcessStartInfo(strAuthUrl);
startInfo.CreateNoWindow = false;

//1.        
Process.Start(startInfo);   
//2. - is happening in web browser
//3.        
do
{
    foreach (Process proc in Process.GetProcesses())
    {
        if (proc.MainWindowTitle.StartsWith("Success code="))
        {
            strAuthCode = proc.MainWindowTitle.ToString().Substring(13, 30);
//4.
            try
            {

                // Close process by sending a close message to its main window.
                proc.CloseMainWindow();
                // Free resources associated with process.
                proc.Close();
                // Wait 500 milisecs for exit
                proc.WaitForExit(500);

                //if proc has not exited so far - kill it
                if (proc.HasExited == false)
                {
                    proc.Kill();
                    proc.WaitForExit();
                }
            }
            catch (Exception ex)
            {
                //Do something with exception
            }

            break;
        }
    }
}
while (string.IsNullOrEmpty(strAuthCode));

感谢您的建议。

【问题讨论】:

  • +1 是我见过的最奇特的身份验证方式
  • 有关主题的更多信息:您可能会考虑使用现有的 C# OAuth 库之一而不是此浏览器的东西 - 例如,来自stackoverflow.com/questions/3997172/…的答案之一
  • 您可以使用原生的WebBrowser 控件将其保留在您的应用程序中。
  • 强制 url 在默认浏览器的新实例中加载? stackoverflow.com/questions/742598/…
  • 只需使用 HttpWebRequest。无需涉及外部 Web 浏览器。

标签: c# wpf process oauth browser


【解决方案1】:

正如斯蒂芬·李·帕克所建议的那样,确实可以将击键发送到某个窗口。也就是说,假设您拥有浏览器窗口的句柄。

另外,您选择的浏览器应该支持关闭单独选项卡的热键,但 Ctrl+W 大部分时间都有效。

与:

using System.Runtime.InteropServices;

[DllImportAttribute("user32.dll", EntryPoint = "SetForegroundWindow")]
[return: MarshalAsAttribute(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow([InAttribute()] IntPtr hWnd);

[DllImport("user32.dll")]
public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo);

byte W = 0x57; //the keycode for the W key

public static void Send(byte KeyCode, bool Ctrl, bool Alt, bool Shift, bool Win)
{
    byte Keycode = (byte)KeyCode;

    uint KEYEVENTF_KEYUP = 2;
    byte VK_CONTROL = 0x11;
    byte VK_MENU = 0x12;
    byte VK_LSHIFT = 0xA0;
    byte VK_LWIN = 0x5B;

    if (Ctrl)
        keybd_event(VK_CONTROL, 0, 0, 0);
    if (Alt)
        keybd_event(VK_MENU, 0, 0, 0);
    if (Shift)
        keybd_event(VK_LSHIFT, 0, 0, 0);
    if (Win)
        keybd_event(VK_LWIN, 0, 0, 0);

    //true keycode
    keybd_event(Keycode, 0, 0, 0); //down
    keybd_event(Keycode, 0, KEYEVENTF_KEYUP, 0); //up

    if (Ctrl)
        keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
    if (Alt)
        keybd_event(VK_MENU, 0, KEYEVENTF_KEYUP, 0);
    if (Shift)
        keybd_event(VK_LSHIFT, 0, KEYEVENTF_KEYUP, 0);
    if (Win)
        keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP, 0);

}

您几乎可以将键盘上的任何键码发送到当前活动的窗口。由于您可以很容易地使用 Win32 设置前台窗口,因此这应该适用于大多数应用程序。

您还可以看到,此代码首先“按下”任何选定的修饰键,然后在释放所有内容之前按下具有给定键码的键,使其能够发送 CTRL+W。

    void CloseTab()
    {
       SetForegroundWindow(_browserWindow.Handle);
       Send(W, true, false, false, false); //Ctrl+W
    }

祝你好运!

(这也是我的第一个答案,所以我真的希望我能够帮助你们中的一些人)

【讨论】:

  • 干杯!老帖子,但你让我免于挖掘很多旧的 w32 代码:)
  • 不客气!自从发布此答案以来,我了解到使用 SendInput 方法而不是 Keybd_Event 实际上更好。在某些情况下,比如一些全屏游戏,它只能与 SendInput 一起使用。
【解决方案2】:

还有其他方法可以做到这一点,例如使用dotnetopenauth。但是如果你真的想使用网络浏览器,我建议你使用.Net的WebBrowser控件来完成任务,并处理Navigated事件来决定何时关闭它。

【讨论】:

    【解决方案3】:

    可能回答的时间太长了,但是今天我遇到了同样的问题,我将使用这种方式: 在新的浏览器进程中打开 url。 Open a URL in a new browser process

    然后在身份验证或任何您想要的之后;例如就我而言;当用户将 pin 输入到我的 WPF 中时;从 twitter 生成,我可以轻松关闭单个进程。 这样一来,您就不必担心其他选项卡,因为打开了一个新的浏览器进程。

    【讨论】:

      【解决方案4】:

      我通过将 CTRL-W 发送到浏览器窗口来完成此操作...

      【讨论】:

        猜你喜欢
        • 2015-12-27
        • 2012-10-30
        • 1970-01-01
        • 2013-07-19
        • 1970-01-01
        • 2012-09-11
        • 2013-08-16
        • 2021-08-06
        • 1970-01-01
        相关资源
        最近更新 更多