質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

1回答

4731閲覧

WebBrowserを拡張してWebBrowser2イベントを拾う際にInvalidActiveXStateExceptionが出てしまいます。

toshi0607

総合スコア56

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

1クリップ

投稿2015/09/26 11:44

概要

・C#においてWebBrowserで特定のサイトにアクセスした際にボタンをクリックすると、IEが立ち上がってしまいました。そのため、新規ウィンドウを開こうとするときにNewWindow2イベントを拾ってWebBrowser内で立ち上げるためにWebBrowserを拡張してNewWindow2イベントを扱えるようにしようとしています。
・主にこのWebページ(新規ウィンドウを自前のForm(WebBrowser)で開きたい)を参考に下記のようなコードを足しました。

lang

1public class ExtendedWebBrowser : WebBrowser 2 { 3 private AxHost.ConnectionPointCookie cookie; 4 private WebBrowser2EventHelper helper; 5 6 [DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] 7 [DispIdAttribute(200)] 8 9 public object Application 10 { 11 get 12 { 13 if (this.ActiveXInstance == null) 14 { 15 throw new AxHost.InvalidActiveXStateException("Application", AxHost.ActiveXInvokeKind.PropertyGet); 16 } 17 return this.ActiveXInstance.GetType().InvokeMember("Application", System.Reflection.BindingFlags.GetProperty, null, this.ActiveXInstance, null); 18 19 20 } 21 } 22 23 [DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] 24 [DispIdAttribute(552)] 25 public bool RegisterAsBrowser 26 { 27 get 28 { 29 if (this.ActiveXInstance == null) 30 { 31 throw new AxHost.InvalidActiveXStateException("RegisterAsBrowser", AxHost.ActiveXInvokeKind.PropertyGet); 32 } 33 return (bool)this.ActiveXInstance.GetType().InvokeMember("RegisterAsBrowser", System.Reflection.BindingFlags.GetProperty, null, this.ActiveXInstance, null); 34 35 36 } 37 set 38 { 39 if (this.ActiveXInstance == null) 40 { 41 throw new AxHost.InvalidActiveXStateException("RegisterAsBrowser", AxHost.ActiveXInvokeKind.PropertySet); 42 } 43 this.ActiveXInstance.GetType().InvokeMember("RegisterAsBrowser", System.Reflection.BindingFlags.SetProperty, null, this.ActiveXInstance, new object[] { value }); 44 } 45 } 46 47 [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")] 48 protected override void CreateSink() 49 { 50 base.CreateSink(); 51 helper = new WebBrowser2EventHelper(this); 52 cookie = new AxHost.ConnectionPointCookie(this.ActiveXInstance, helper, typeof(DWebBrowserEvents2)); 53 } 54 55 [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")] 56 protected override void DetachSink() 57 { 58 if (cookie != null) 59 { 60 cookie.Disconnect(); 61 cookie = null; 62 } 63 base.DetachSink(); 64 } 65 66 public event WebBrowserNewWindow2EventHandler NewWindow2 = (o, e) => { }; 67 68 protected virtual void OnNewWindow2(WebBrowserNewWindow2EventArgs e) 69 { 70 NewWindow2(this, e); 71 } 72 73 private class WebBrowser2EventHelper : StandardOleMarshalObject, DWebBrowserEvents2 74 { 75 private ExtendedWebBrowser parent; 76 77 public WebBrowser2EventHelper(ExtendedWebBrowser parent) 78 { 79 this.parent = parent; 80 } 81 82 public void NewWindow2(ref object ppDisp, ref bool cancel) 83 { 84 var e = new WebBrowserNewWindow2EventArgs(ppDisp); 85 this.parent.OnNewWindow2(e); 86 ppDisp = e.ppDisp; 87 cancel = e.Cancel; 88 } 89 } 90 } 91 92 public delegate void WebBrowserNewWindow2EventHandler(object sender, WebBrowserNewWindow2EventArgs e); 93 94 public class WebBrowserNewWindow2EventArgs : CancelEventArgs 95 { 96 public object ppDisp { get; set; } 97 98 public WebBrowserNewWindow2EventArgs(object ppDisp) 99 { 100 this.ppDisp = ppDisp; 101 } 102 } 103 104 [ComImport, Guid("34A715A0-6587-11D0-924A-0020AFC7AC4D")] 105 [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] 106 [TypeLibType(TypeLibTypeFlags.FHidden)] 107 public interface DWebBrowserEvents2 108 { 109 [DispId(251)] 110 void NewWindow2([InAttribute(), OutAttribute(), MarshalAs(UnmanagedType.IDispatch)] ref object ppDisp, [InAttribute(), OutAttribute()] ref bool cancel); 111 }

・これを使用するクラスは下記のWebBrowserを管理するクラス(抜粋)です。

lang

1private void WebBrowser_NewWindow2(object sender, WebBrowserNewWindow2EventArgs e) 2{ 3 // 新しい WebBrowser の初期化 4 WebBrowser = new ExtendedWebBrowser(); 5 WebBrowser.Dock = DockStyle.Fill; 6 7 8 WebBrowser.NewWindow2 += WebBrowser_NewWindow2; 9 // this.TabPage1 = new TabPage(); 10 // this.TabPage1.Controls.Add(WebBrowser); 11 // this.TabControl.Controls.Add(TabPage1); 12 // this.TabControl.SelectedTab = TabPage1; 13 14 // 新しい WebBrowser に表示させる設定 15 e.ppDisp = this.WebBrowser.Application; 16 this.WebBrowser.RegisterAsBrowser = true; 17 } 18 19public async Task WaitNextPage() 20 { 21 await this.WaitDocumentLoad(); 22 this.SwitchToRootFrame(); 23 WebBrowser.NewWindow2 += new WebBrowserNewWindow2EventHandler(WebBrowser_NewWindow2); 24 this.SavePage(); 25} 26

・実行時にExtendedWebBrowserクラスの

lang

1return this.ActiveXInstance.GetType().InvokeMember("Application", System.Reflection.BindingFlags.GetProperty, null, this.ActiveXInstance, null);

で 'System.Windows.Forms.AxHost.InvalidActiveXStateException' の例外が発生してしまいます。

動作環境

・.NET Frame Work 4.5
・Visual Studio2013

補足

・サイト遷移の様子はアプリ利用者に表示しないため、WebBrowserコントロールはFormに紐づけていません。

よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

WebBrowser_NewWindow2に

lang

1Controls.Add(WebBrowser);

を追記することで解消しました。

投稿2015/09/27 08:59

編集2015/09/27 09:01
toshi0607

総合スコア56

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問