C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: COMオブジェクト参照で表示される警告メッセージについて


(過去ログ 122 を表示中)

[トピック内 3 記事 (1 - 3 表示)]  << 0 >>

■72994 / inTopicNo.1)  COMオブジェクト参照で表示される警告メッセージについて
  
□投稿者/ ぽっくる (1回)-(2014/08/08(Fri) 11:16:29)

分類:[VB.NET/VB2005 以降] 

使用ソフト
Microsoft Visual Studio 2010
.net framework 4

定期的にブラウザからURLを取得するモジュールを作成したのですが、
デバッグモードで起動してフォーム画面にてクリックボタンを何度か押していると
以下のメッセージが表示されてしまいます。

「Reentrancyが検出されました。
  最初に移行しないでマネージ コードを呼び出そうとしています。ベクトル化例外ハンドラーのような、下層レベルのネイティブ機能拡張ポイント内でマネージ コードを実行しないでください。
  この動作により、破損およびデータの損失を発生させる可能性があります。」

メッセージの表示後はエラーで落ちることもなく、コンパイルをしてもエラーで落ちることはありません。
どなたか解決策を教えていただけないでしょうか。

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

        Dim urlA As String = ""
        Dim ie As Object = Nothing
        Dim sh As Object = Nothing
        Dim shw As Object = Nothing

        Try
            sh = CreateObject("Shell.Application")
            Try
                shw = sh.windows()
                Try
                    ie = CreateObject("InternetExplorer.Application")
                    For Each ie In shw
                            urlA = ie.LocationURL
                            Me.TextBox1.Text = urlA
                         ie.Quit()
                    Next ie
                Finally
                    If Not ie Is Nothing Then
                        If System.Runtime.InteropServices.Marshal.IsComObject(ie) Then
                            'COMオブジェクトの参照カウントをデクリメント
                            System.Runtime.InteropServices.Marshal.ReleaseComObject(ie)
                        End If
                        ie = Nothing
                    End If
                End Try
            Finally
                If Not shw Is Nothing Then
                    If System.Runtime.InteropServices.Marshal.IsComObject(shw) Then
                        'COMオブジェクトの参照カウントをデクリメント
                        System.Runtime.InteropServices.Marshal.ReleaseComObject(shw)
                    End If
                    shw = Nothing
                End If
            End Try
        Finally
            If Not sh Is Nothing Then
                If System.Runtime.InteropServices.Marshal.IsComObject(sh) Then
                    'COMオブジェクトの参照カウントをデクリメント
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(sh)
                End If
                sh = Nothing
            End If
        End Try
    End Sub

引用返信 編集キー/
■72995 / inTopicNo.2)  Re[1]: COMオブジェクト参照で表示される警告メッセージについて
□投稿者/ ぽぴ王子 (6回)-(2014/08/08(Fri) 13:44:27)
ぽぴ王子 さんの Web サイト
No72994 (ぽっくる さん) に返信

「Reentrancyが検出されました」で検索してみたところ、以下の過去ログが見つかりました。
http://dobon.net/vb/bbs/log3-46/27525.html

こちらによれば、インスタンス解放が不十分なのではないかと語られていますね。
そこでぽっくるさんの示してくださったコードを見てみると、このあたりが怪しいです。

>                     ie = CreateObject("InternetExplorer.Application")
>                     For Each ie In shw
>                             urlA = ie.LocationURL
>                             Me.TextBox1.Text = urlA
>                          ie.Quit()
>                     Next ie

CreateObject の結果を ie に代入していますが、その直後に shw に対するループ変数として
ie が使いまわされているようです。
(もしかしたら記載間違いかな?とも思えますが)

他にも見えていないところでインスタンス解放されていない部分があるかもしれないので、一度
じっくり見てみるのがよいのではないかと思います。

引用返信 編集キー/
■72999 / inTopicNo.3)  Re[2]: COMオブジェクト参照で表示される警告メッセージについて
□投稿者/ ぽっくる (2回)-(2014/08/08(Fri) 17:40:38)
中の動きはあまりかえず、事前バインディングとなるよう参照にMicrosoft Internet Controlを追加して
以下のようにソースを修正したところ、正常に動作するようになりました。

インスタンスの解放というよりもインスタンスの生成自体に問題があったのでしょうか。
なぜかが理解できずもやもやしますが、ひとまずは解決できてよかったです。
ぽぴ王子さんありがとうございます。

        Dim ie As SHDocVw.InternetExplorer
        Dim shw As New SHDocVw.ShellWindows
-----------------------------------------------------------------------
            For Each ie In shw
                Try
                    urlA = ie.LocationURL
                    Me.TextBox1.Text = urlA
                Finally
                    If Not urlA Is Nothing Then
                        If System.Runtime.InteropServices.Marshal.IsComObject(urlA) Then
                            'COMオブジェクトの参照カウントをデクリメント
                            System.Runtime.InteropServices.Marshal.ReleaseComObject(urlA)
                        End If
                        urlA = Nothing
                    End If
                End Try
                ie.Quit()
            Next ie
-----------------------------------------------------------------------

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -