从C#应用程序我想激活(brint到前面)已经在用户默认浏览器中打开的网站。 我想以浏览器不可知的方式做到这一点。
困难的部分(至less对我来说)是我不希望浏览器打开一个新的标签,浏览器不能重新加载页面,如果它已经打开。
我可以在默认浏览器中打开URI
System.Diagnostics.Process.Start("http://foo.example");
但确切的行为取决于用户的默认浏览器(IE6似乎重用当前最高的浏览器窗口,谷歌浏览器将始终打开一个新的标签等)
我尝试的另一种方法是枚举所有打开的Windows,并根据窗口标题find我想要的(假设大多数浏览器将窗口标题设置为当前打开的页面的标题)
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());
这就是我所需要做的,但感觉非常脆弱,而且可能很慢。
有更好,更优雅的方式吗?
如果用户在浏览器中激活了该站点,这将起作用。 如果他们使用的是标签浏览器,并且该网站已经打开,但是没有被选中,我不相信你会找到浏览器窗口。 (EnumWindows只能枚举顶层窗口)。
如果用户启动了一个新标签,那么您最终将无法找到该标签,并且(可能)会在新标签中启动该网站的第二个副本。
就个人而言,如果你真的需要限制到一个浏览器实例,我会考虑是否有可能在浏览器中嵌入浏览器,而不是使用默认浏览器。 如果这可以在您的应用程序中使用浏览器控件作为GUI元素,那么您将拥有更多的控制权并且能够避免这种类型的解决方法。