2009-05-18 4 views
2

Von einer C# -Anwendung möchte ich eine Seite aktivieren, die bereits im Standardbrowser des Benutzers geöffnet ist. Ich möchte dies auf eine browser-agnostische Weise tun.Vorhandenes Browserfenster mit gegebener URL von C# -Anwendung aus aktivieren (ohne erneutes Laden auszulösen)

Der schwierige Teil (zumindest für mich) ist, dass ich tun nicht der Browser eine neue Registerkarte öffnen möchten, und den Browser nicht die Seite, wenn es bereits geöffnet ist nachladen muss.

Ich kann den URI öffnen im Standardbrowser mit

System.Diagnostics.Process.Start("http://foo.example"); 

Aber das genaue Verhalten hängt von dem Benutzer Standard-Browser (IE6 scheint das aktuelle oberste Browser-Fenster wieder zu verwenden, wird Google Chrome immer einen neuen Tab öffnen und so weiter)

Ein anderer Ansatz, den ich versuchte, war, alle offenen Windows aufzuzählen und den gewünschten zu finden, basierend auf dem Fenstertitel (unter der Annahme, dass die meisten Browser den Fenstertitel auf den Titel der aktuell geöffneten Seite setzten).

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 
    } 
} 

die Verwendung mit:

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

Das tut, was ich es tun müssen, fühlt sich aber sehr spröde und hackish und ist wahrscheinlich langsam.

Gibt es einen besseren, eleganteren Weg?

Antwort

1

Dies funktioniert, wenn der Benutzer diese Website in ihrem Browser aktiviert hat. Wenn sie einen Tabbed-Browser verwenden und die Site geöffnet ist, aber nicht auf der ausgewählten Registerkarte, glaube ich nicht, dass Sie jemals das Browserfenster finden werden. (EnumWindows zählt nur Top-Level-Fenster auf).

Wenn der Benutzer einen neuen Tab gestartet hat, werden Sie ihn nicht finden und (wahrscheinlich) eine zweite Kopie der Site in einem neuen Tab starten.

Persönlich, wenn Sie wirklich auf eine einzelne Browserinstanz beschränken müssen, würde ich überlegen, ob es möglich ist, den Browser in Ihrer Anwendung einzubetten, anstatt den Standardbrowser zu verwenden. Wenn dies über ein Browsersteuerelement in Ihrer Anwendung zu einem GUI-Element gemacht werden kann, haben Sie viel mehr Kontrolle und können diese Art von Problemumgehung umgehen.

+0

Ich kann mit der Einschränkung leben, dass dies nicht mit Hintergrund-Registerkarten funktioniert. Das Einbinden eines Browser-Kontos in meine App ist leider keine Option. (Weil es den exsting Workflow zu viel ändern würde) Was ich hoffe, ideal für so etwas wie OpenUriInDefaultBrowser („http: //foo.example“, OpenUriOptions.ActivateOnly) ich wahrscheinlich sollte erwähnen, dass ich auch die Kontrolle über die Browserseite der Dinge, also vielleicht, wenn es eine Möglichkeit gäbe, ein Browserfenster 'von innen' zu aktivieren, würde das auch für mich funktionieren (vielleicht ist es möglich, etwas schlaues mit benutzerdefinierten URI-Schemas zu machen?) – levinalex

+0

Leider da ist keine browser-agnostische Möglichkeit, dies zu tun. Sie könnten dies möglicherweise über Browser-Add-Ins in IE und Firefox tun, aber ich denke nicht, dass das für Chrome oder Opera funktionieren würde. –

Verwandte Themen