3

NuGet のインストールの一環として、インストールの完了時に Web ページを開く必要があります。

私たちの要件は次のとおりです。

  1. ページがまだ別のウィンドウで開かれていない場合は、新しいウィンドウで Visual Studio の Web ページを開きます。

Web ページを単独で開くのは簡単です。

... DTE.ItemOperations.Navigate(WebPageUri.ToString(), EnvDTE.vsNavigateOptions.vsNavigateOptionsNewWindow); ...

問題は、ページを開く必要があるかどうかを判断できるように、現在開いている Web ページのリストを取得する方法を見つけることです。

解決策は単純であり、ずっと私たちの顔を見つめてきたと確信しています.

EnvDTE を使用して Visual Studio で現在開いている Web ページのリストを取得するにはどうすればよいですか?

4

1 に答える 1

1

この問題の解決策を以下に示します。このアプローチがベストプラクティスであるとは思えませんが、うまくいくようです。

Visual Studio の Web ブラウザ ウィンドウには、「EnvDTE.Constants.vsWindowKindWebBrowser」の「ObjectKind」値があります。「Object」の値は Internet Explorer ブラウザで、「IWebBrowser2」を実装しています。「IWebBrowser2」は .Net ではありませんが、「System.Windows.Forms.WebBrowser」は (どうやら) 「IWebBrowser2」のラッパーです。「System.Windows.Forms.WebBrowser」にはオーバーライド可能な「AttachInterfaces」メソッドがあり、ウィンドウ オブジェクトを渡して、「System.Windows.Forms.WebBrowser」に面倒な作業を任せることができます。

最終結果は次のとおりです。

public class VisualStudioWebBrowser : System.Windows.Forms.WebBrowser
{
    protected VisualStudioWebBrowser(object IWebBrowser2Object)
    {
        this.IWebBrowser2Object = IWebBrowser2Object;
    }

    protected object IWebBrowser2Object { get; set; }

    public static void Evaluate(EnvDTE.Window WindowReference, Action<System.Windows.Forms.WebBrowser> OnEvaluate)
    {
        //Note: Window of EnvDTE.Constants.vsWindowKindWebBrowser type contains an IWebBrowser2 object
        if (VisualStudioWebBrowser.IsWebBrowserWindow(WindowReference))
        {
            using (System.Threading.ManualResetEvent evt = new System.Threading.ManualResetEvent(false))
            {
                System.Threading.Thread STAThread = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart((o) =>
                {
                    try
                    {
                        using (VisualStudioWebBrowser Browser = new VisualStudioWebBrowser(o))
                        {
                            try
                            {
                                OnEvaluate.Invoke((System.Windows.Forms.WebBrowser)Browser);
                            }
                            catch { }
                        }
                    }
                    catch { }
                    evt.Set();
                }));
                STAThread.SetApartmentState(System.Threading.ApartmentState.STA);
                STAThread.Start(WindowReference.Object);
                evt.WaitOne();
            }
        }
    }
    public static bool IsWebBrowserWindow(EnvDTE.Window WindowReference)
    {
        return (WindowReference != null && WindowReference.ObjectKind.Equals(EnvDTE.Constants.vsWindowKindWebBrowser, StringComparison.InvariantCultureIgnoreCase));
    }
    public static IEnumerable<EnvDTE.Window> GetWebBrowserWindows(EnvDTE.DTE EnvDTEReference)
    {
        List<EnvDTE.Window> BrowserWindows = new List<EnvDTE.Window>();
        foreach (EnvDTE.Window WindowReference in EnvDTEReference.Windows)
        {
            if (VisualStudioWebBrowser.IsWebBrowserWindow(WindowReference) == true)
            {
                BrowserWindows.Add(WindowReference);
            }
        }
        return BrowserWindows;
    }
    public static Uri GetWebBrowserWindowUrl(EnvDTE.Window WindowReference)
    {
        Uri BrowserUrl = new Uri("", UriKind.RelativeOrAbsolute);
        VisualStudioWebBrowser.Evaluate(WindowReference, new Action<System.Windows.Forms.WebBrowser>((wb) =>
        {
            BrowserUrl = wb.Url;
        }));
        return BrowserUrl;
    }
    public static IEnumerable<Uri> GetWebBrowserWindowUrls(EnvDTE.DTE EnvDTEReference)
    {
        List<Uri> BrowserUrls = new List<Uri>();

        foreach (EnvDTE.Window BrowserWindow in VisualStudioWebBrowser.GetWebBrowserWindows(EnvDTEReference))
        {
            try
            {
                Uri BrowserUrl = VisualStudioWebBrowser.GetWebBrowserWindowUrl(BrowserWindow);
                if (String.IsNullOrWhiteSpace(BrowserUrl.LocalPath) == false)
                {
                    BrowserUrls.Add(BrowserUrl);
                }
            }
            catch { }
        }

        return BrowserUrls;
    }

    protected override void AttachInterfaces(object nativeActiveXObject)
    {
        base.AttachInterfaces(this.IWebBrowser2Object);
        //base.AttachInterfaces(nativeActiveXObject);
    }
    protected override void DetachInterfaces()
    {
        base.DetachInterfaces();
        this.IWebBrowser2Object = null;
    }
}

開いている Web ページのリストは、次の方法で検索されます。

IEnumerable<Uri> Urls = VisualStudioWebBrowser.GetWebBrowserWindowUrls(EnvDTEReference);
于 2013-01-10T21:58:54.477 に答える