windows 使用来自 C# 应用程序的给定 URL 激活现有浏览器窗口(不触发重新加载)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/878429/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Activate existing browser window with given URL from C# application (without triggering reload)
提问by levinalex
From a C# application I want to activate (brint to front) a site that is already open in the users default browser. I want to do this in a browser agnostic way.
从 C# 应用程序中,我想激活(brint to front)一个已经在用户默认浏览器中打开的站点。我想以浏览器不可知的方式执行此操作。
The difficult part (for me at least) is that I do notwant the browser to open a new tab and the browser must not reloadthe page if it is already open.
困难的部分(至少对我而言)是我不希望浏览器打开一个新选项卡,并且如果页面已经打开,浏览器不能重新加载页面。
I can open the URI in the default browser with
我可以在默认浏览器中打开 URI
System.Diagnostics.Process.Start("http://foo.example");
But the exact behaviour depends on the users default browser (IE6 seems to reuse the current topmost browser window, Google Chrome will always open a new tab and so on)
但确切的行为取决于用户的默认浏览器(IE6 似乎重用了当前最顶层的浏览器窗口,谷歌浏览器总是会打开一个新标签等等)
Another approach I tried was to enumerate all open Windows and find the one I want based on the window title (making the assumption that most browsers set the window title to the title of the currently open page)
我尝试的另一种方法是枚举所有打开的 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
}
}
using it with:
使用它:
EnumWindows(new EnumThreadWindowsCallback(FindWindowByRx), new IntPtr());
This does what I need it to do, but feels very brittle and hackish, and is probably slow.
这做了我需要它做的事情,但感觉非常脆弱和骇人听闻,而且可能很慢。
Is there a better, more elegant way?
有没有更好、更优雅的方式?
采纳答案by Reed Copsey
This will work, IF the user has that site active in their browser. If they're using a tabbed browser, and the site is open, but not in the selected tab, I don't believe you will ever find the browser window. (EnumWindows only enumerates top-level windows).
如果用户在其浏览器中激活了该站点,这将起作用。如果他们使用选项卡式浏览器,并且站点是打开的,但不在选定的选项卡中,我相信您永远不会找到浏览器窗口。(EnumWindows 仅枚举顶级窗口)。
If the user's started a new tab, you'll end up not finding it, and (likely) starting a second copy of the site in a new tab.
如果用户启动了一个新选项卡,您最终将找不到它,并且(很可能)在新选项卡中启动站点的第二个副本。
Personally, if you really need to restrict to a single browser instance, I would consider whether its possible to embed the browser in your application instead of using the default browser. If this can be made a GUI element in your application using a browser control, you'd have much more control and be able to avoid this type of workaround.
就个人而言,如果您确实需要限制为单个浏览器实例,我会考虑是否可以将浏览器嵌入到您的应用程序中,而不是使用默认浏览器。如果这可以使用浏览器控件在您的应用程序中成为 GUI 元素,您将拥有更多的控制权并能够避免这种类型的解决方法。