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

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

新規登録して質問してみよう
ただいま回答率
85.37%
Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

解決済

2回答

7670閲覧

VB2015でのCOMオブジェクトの扱いについて

ynakano

総合スコア1894

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

1クリップ

投稿2016/06/30 01:57

初めて質問をさせていただきます。
現在VB.Net(VS2015)でWindowsフォームアプリケーションを作成しています。
フォーム上のボタンをクリックするとIEを起動させ、フォームにユーザ名とパスワードを入力して特定のサイトに自動ログインさせるものです。

当該処理部分のコードは下記の通りとなります。

1: Private Sub cmdOpenBrowser_Click(ByVal sender As Object, ByVal e As EventArgs)
2: Dim ObjIE As SHDocVw.InternetExplorer
3:
4: ObjIE = New SHDocVw.InternetExplorer
5: ObjIE.Visible = True
6: ObjIE.Navigate("http://hogehoge.com/")
7:
8: While ObjIE.ReadyState <> 4 Or ObjIE.Busy = True
9: System.Windows.Forms.Application.DoEvents()
10: System.Threading.Thread.Sleep(1000)
11: End While
12:
13: If ObjIE.Document.getElementsByTagName("input").length > 0 Then
14: For Each ObjTag In ObjIE.Document.getElementsByTagName("input")
15: If ObjTag.Type.ToString() = "text" Or ObjTag.Type.ToString() = "email" Then
16: ObjTag.value = "myID"
17: ElseIf ObjTag.Type.ToString() = "password" Then
18: ObjTag.value = "myPassword"
19: End If
20: Next
21:
22: ObjIE.Document.Forms(0).Submit()
23:
24: System.Runtime.InteropServices.Marshal.ReleaseComObject(ObjIE)
25: ObjIE = Nothing
26:
27: GC.Collect()
28: GC.WaitForPendingFinalizers()
29: GC.Collect()
30: End If
31: End Sub

アプリケーションを起動して上記処理を実行すると1回目は必ず成功します。
しかし同じボタンをクリックして2度目以降に実行すると、必ず13行目で例外が発生します。

その際発生する例外は1種類ではなく、今まで試した限りでは下記4種類です。

System.Runtime.InteropServices.COMException
System.NullReferenceException
System.NotSupportedException
System.MissingMemberException

いくつかのサイトで調べてみて以下の事をしてみたのですが、いずれも効果がありませんでした。

・上記処理をスレッド化する
・IEの保護モードを無効にする

また、上記コードの24行目から29行目も調査の結果追記してみたのですが効果なしです。

COMオブジェクトの解放に問題があるのではないかと推測しているのですが、具体的にどのような実装をすればよいのか分からず困っております。

環境は以下の通りです。

・Windows7 Pro(64bit)
・Visual Studio 2015(Community)
・IE11(64bit)

どなたか知見のある方にご教授いただければと思います。
よろしくお願いします。

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

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

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

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

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

guest

回答2

0

間違えていただいた回答へのコメントに記載してしまいました。
失礼しました。

投稿2016/06/30 08:36

ynakano

総合スコア1894

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

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

0

ベストアンサー

検索ワードとしては、
VB.NET marshal release com object
C# marshal release com object
Relase COM 参照カウント
辺りからでしょうか。
【VB.NET】COMオブジェクトの解放
http://blog.livedoor.jp/akf0/archives/51331948.html
上記の様にEXCEL の例が多かったりしますが、探せばIE事例もあります。

投稿2016/06/30 02:14

daive

総合スコア2030

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

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

ynakano

2016/06/30 08:27

コメントいただきありがとうございました。 まず結論として解決しました! コードは以下の通りです。(冗長な部分はありますでしょうが) 1: Private Sub cmdOpenBrowser_Click(ByVal sender As Object, ByVal e As EventArgs) 2: Dim ObjIE As SHDocVw.InternetExplorer = CType(CreateObject("InternetExplorer.application"), SHDocVw.InternetExplorer) 3: 4: ObjIE.Visible = True 5: ObjIE.Navigate("http://hogehoge.com/") 6: 7: While ObjIE.ReadyState <> 4 Or ObjIE.Busy = True 8: System.Windows.Forms.Application.DoEvents() 9: System.Threading.Thread.Sleep(1000) 10: End While 11: 12: Dim ObjIEDocument As mshtml.HTMLDocument = CType(ObjIE.Document, mshtml.HTMLDocument) 13: Dim ObjIEDocumentInputTag As mshtml.IHTMLElementCollection = CType(ObjIEDocument.getElementsByTagName("input"), mshtml.IHTMLElementCollection) 14: Dim ObjIEForm As mshtml.HTMLFormElement = CType(ObjIEDocument.forms(0), mshtml.HTMLFormElement) 15: Dim ObjTag As mshtml.HTMLInputElement 16: 17: If ObjIEDocumentInputTag.length > 0 Then 18: For Each ObjTag In ObjIEDocumentInputTag 19: If ObjTag.Type.ToString() = "text" Or ObjTag.Type.ToString() = "email" Then 20: ObjTag.value = "myID" 21: ElseIf ObjTag.Type.ToString() = "password" Then 22: ObjTag.value = "myPassword" 23: End If 24: Next 25: 26: ObjIEForms.Submit() 27: 28: System.Runtime.InteropServices.Marshal.ReleaseComObject(ObjTag) 29: System.Runtime.InteropServices.Marshal.ReleaseComObject(ObjIEForm) 30: System.Runtime.InteropServices.Marshal.ReleaseComObject(ObjIEDocumentInputTag) 31: System.Runtime.InteropServices.Marshal.ReleaseComObject(ObjIEDocument) 32: System.Runtime.InteropServices.Marshal.ReleaseComObject(ObjIE) 33: 34: ObjTag = Nothing 35: ObjIEForm = Nothing 36: ObjIEDocumentInputTag = Nothing 37: ObjIEDocument = Nothing 38: ObjIE = Nothing 39: 40: GC.Collect() 41: GC.WaitForPendingFinalizers() 42: GC.Collect() 43: End If 44: End Sub ポイントはコメントいただいたサイトにあった「COMオブジェクトを利用する場合、参照したものを全て変数に格納しておく必要がある。」という部分でした。 各階層(?)ごとに逐一変数に収める必要があるんですね… あと一つ役に立ったのは以下のサイトです。 http://www.mztools.com/articles/2006/mz2006013.aspx 各階層のオブジェクトを変数宣言しようとしても、「System.__ComObject」にされてしまってちょっと辟易してしまいました。 これでリリースに向けて大きく前進しました。 daive様の回答をベストアンサーとさせていただきます。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問