使用来自C#应用程序的给定URL激活现有浏览器窗口(不触发重新加载)

时间:2009-05-18 15:54:20

标签: c# windows winforms

从C#应用程序我想激活(brint到前面)已在用户默认浏览器中打开的站点。我想以浏览器无关的方式做到这一点。

困难的部分(至少对我来说)是我希望浏览器打开新标签,浏览器不得重新加载页面如果是已经开放了。

我可以使用

在默认浏览器中打开URI
System.Diagnostics.Process.Start("http://foo.example");

但确切的行为取决于用户默认浏览器(IE6似乎重用当前最顶层的浏览器窗口,Google Chrome将始终打开新标签等)

我尝试的另一种方法是枚举所有打开的Windows并根据窗口标题找到我想要的那个(假设大多数浏览器将窗口标题设置为当前打开页面的标题)

public delegate bool EnumThreadWindowsCallback(int hWnd, int lParam);

[DllImport("user32.dll")]
static extern bool SetForegroundWindow(IntPtr hWnd);

[DllImport("user32.dll")]
static extern bool EnumWindows(EnumThreadWindowsCallback callback, IntPtr extraData);

[DllImport("user32.dll")]
static extern int GetWindowText(int hWnd, StringBuilder text, int count);

private bool FindWindowByRx(int hWnd, int lParam)
{
    Regex pattern = new Regex("Example Title of Page", RegexOptions.IgnoreCase);
    StringBuilder windowTitle = new StringBuilder(256);
    GetWindowText(hWnd, windowTitle, 255);

    if (pattern.IsMatch(windowTitle.ToString()))
    {
        SetForegroundWindow(new IntPtr(hWnd));
        return false; // abort search
    }
    else
    {
        return true; // keep on searching
    }
}

使用它:

EnumWindows(new EnumThreadWindowsCallback(FindWindowByRx), new IntPtr());

这就是我需要它做的事情,但感觉非常脆弱和hackish,并且可能很慢。

有更好,更优雅的方式吗?

1 个答案:

答案 0 :(得分:1)

如果用户在浏览器中激活了该网站,则此功能将起作用。如果他们使用标签式浏览器,并且该网站已打开,但未在所选标签中,我不相信您会找到浏览器窗口。 (EnumWindows只枚举顶级窗口。)

如果用户启动了新标签页,您将最终找不到该标签,并且(可能)在新标签页中启动该网站的第二个副本。

就个人而言,如果你真的需要限制一个浏览器实例,我会考虑是否可以将浏览器嵌入你的应用程序而不是使用默认浏览器。如果可以使用浏览器控件在应用程序中创建GUI元素,那么您将拥有更多控制权并能够避免这种类型的变通方法。