none
WebBrowserコントロールでPDFを表示させると、表示させたファイルが使用中となって解放されません RRS feed

  • 質問

  • Vista で OpenFileDialogで選択されたPDFファイルをWebBrowserコントロールでPDFを表示しています。
    表示したいPDFを以下のように順に表示します。
    A.pdf
    B.pdf
    C.pdf
    これらのPDFをWebBrowserで表示した場合、この処理を行っているFormをDisposeしても
    A.pdf,B.pdf,C.pdfがオープンされた状態となって、エクスプローラなどでこれらのファイルを削除できません。
    アプリケーションを終了すると、これらのファイルのオープンは解放されます。
    A.pdfを表示後、B.pdfを表示させた場合、A.pdfのオープンはどうすれば解放されるのでしょうか?
    同様な処理をXPで行った場合、A.pdfからB.pdfに表示が切り替わった時点で
    A.pdfのオープンは解放されます。
    ちなみにAcrobat Readerは、Vista XP 共にバージョン 9.1.1です。
    開発環境は Visual Studio 2008 Standard  VB.Net 3.5です。
    よろしくお願いいたします。



    2009年5月21日 22:37

回答

  • OpenDialogが原因かもしれません。
    FileDialog.RestoreDirectoryプロパティ というものがあり、このプロパティをtrueに設定することで削除が可能になる可能性があります。

    私はフォルダを削除しようとしていましたが、このせいでできませんでした。

    佐祐理さんが教えてくれましたが、ファイルの場合もその可能性があるかもしれません。
    上記プロパティのほかにRestoreDirectoryではなくてRestoreFileというものがあるかもしれません。
    このあたりは試していませんが OpenDialogが原因の可能性が高いです。
    2009年5月22日 0:09
  • それでだめなら、これもだめかもしれませんが、
    WebBrowser1.Document.Src="NUL"
    を試してみてください。

    あと、"about:blank"の場合はCoFreeUnusedLibrariesを併用する必要があるのかも。
    2009年5月26日 8:29
  • 一度、ブラウザに表示すると、WebBrowswrをDisposeしても、
    ExplolerでA.PDFを削除しようとすると
    「別のプログラムがこのファイルを開いているので、操作を完了できません。
    ファイルを閉じてから再実行してください」と表示されてしまいます。
    何か、原因に心当たりはありませんでしょうか?
    Adobe Readerがファイルを閉じていないのかな?(閉じ忘れ or インスタンスが実は残っている or IEがAdobe Readerを解放していない)
    そうであれば、プログラムを終了するまで解放されませんね。

    Adobe Readerの不具合か、ブラウザの不具合になります。
    別の問題で、CoFreeUnusedLibrariesを使うと言ったアプローチがあると最近提案がありました。
    効果の程は分かりませんが、試してみてはいかがでしょうか?
    http://social.msdn.microsoft.com/Forums/ja-JP/netfxgeneralja/thread/4d268e9e-e123-465e-9816-893022b11d61

    ※CoFreeUnusedLibrariesはAPIです。必要に応じてDeclare文を宣言して下さい。

    OpenDialogが原因かもしれません。
    FileDialog.RestoreDirectoryプロパティ というものがあり、このプロパティをtrueに設定することで削除が可能になる可能性があります。

    私はフォルダを削除しようとしていましたが、このせいでできませんでした。
    そのケースはあくまで、カレントフォルダが切り替わるというものです。
    カレントフォルダと設定されているフォルダ自体は消せなくなりますが、ファイル自体は消せます。
    このため、残念ながら今回のケースとは異なります。
    解決した場合は、参考になった返信に「回答としてマーク」のボタンを利用して、回答に設定しましょう(複数に設定できます)。
    2009年5月22日 23:39
    モデレータ
  • 回答にはなっていませんが…。

    すでにAzuleanさんからも指摘されていますが、OpenDialogはファイル削除に関係ありません。
    Form→WebBrowser(ActiveX)→PDF Reader(ActiveX)という遠回りな表示方法はどうかと思いました。とはいえ、試しにFormに直接PDF Readerを配置してみたところエラーになって動作しませんでした。原因がどちらにあるのかはわかりませんが。
    ところでIEの設定で、PDF Readerを無効化していると、Form内に表示されるのではなくダウンロードダイアログが出るだけのアプリになってしまうと思いますが、それでもいいのでしょうか?
    最後に、AdobeのPDF ReaderやFlashはセキュリティホールが多く、そこを攻撃するウィルスが現在蔓延しています。個人的にはもうPDFを扱いたくないぐらいです。ウィルスの温床とならないようお気をつけを。
    2009年5月22日 23:53
  • ところでIEの設定で、PDF Readerを無効化していると、Form内に表示されるのではなくダウンロードダイアログが出るだけのアプリになってしまうと思いますが、それでもいいのでしょうか?
    補足です。
    ブラウザのActiveXを動作させる・させないの設定の他、Adobe Reader側にもブラウザで表示するかどうかの設定があります。


    あと希かもしれませんが、PDFを別のPDFビューアに関連づけていて、Adobe Readerがインストールされていないケースもありますね。


    解決した場合は、参考になった返信に「回答としてマーク」のボタンを利用して、回答に設定しましょう(複数に設定できます)。
    2009年5月23日 5:11
    モデレータ
  • IEのverはどうなってます?

    別件でIE8がページを閉じてもオブジェクトを解放してないのではないかと疑っているもので。

    試しに、IE8でPDFファイルを2つ順に開いてみました。前のファイルはリネームできたので、再現しないと思いましたが、戻って進むと、どちらもリネームできなくなりました。別のタブを残して、そのタブを閉じても、リネームできません。adobe readerのプロセスはしばらくして自然に終了しましたが、その後もリネームできません。IEを終了するとリネームできるようになりました。どうもIEがファイルをオープンしたままになっているようです。次に、A,B,Cの順に開いたときも、A,BではAがリネームできましたが、A,B,CでBがリネームできなくなりました。また、そのIEを終了しても駄目で、ほかのIEも終了してやっと解放されました。IEはなんかむずかしいことをやっているのではないでしょうか。
    2009年5月23日 10:16
  • Adobe Reader 8.1.5 でですが、Vista SP1 + .NET 3.5 SP1 + IE7 がインストールされている
    PC で試した後、同じ PC の IE を 8 にアップデートして違いを調べてみました。

    結果はやはり影響ありで、影響を受けないようになっているであろうと考えたのは過大な期待だっ
    たようです。(汗)

    Adobe Reader のバージョンが違うせいか、質問者さんがレポートされていたのとは様子が異なり
    ましたが、IE のバージョンによって動作が違うのは間違いなさそうです。

    なお、自分が試した限りでは、CoFreeUnusedLibraries は効果なしで、ポイントは pdf を開く前
    に about:blank に Navigate することでした。

    IE7 の場合はその必要はありませんでしたが、IE8 の場合は、いきなり  pdf を開くと、その後
    about:blank に Navigate しても pdf ファイルは開放されないという結果になりました。

    何故そうなるかは調べ切れていません(というより、これ以上調べる気力がないです(笑))。

    2009年5月31日 6:06

すべての返信

  • OpenDialogが原因かもしれません。
    FileDialog.RestoreDirectoryプロパティ というものがあり、このプロパティをtrueに設定することで削除が可能になる可能性があります。

    私はフォルダを削除しようとしていましたが、このせいでできませんでした。

    佐祐理さんが教えてくれましたが、ファイルの場合もその可能性があるかもしれません。
    上記プロパティのほかにRestoreDirectoryではなくてRestoreFileというものがあるかもしれません。
    このあたりは試していませんが OpenDialogが原因の可能性が高いです。
    2009年5月22日 0:09
  • ご回答ありがとうございます。

    ご指摘のofd.RestoreDirectory = True でやってみましたがダメでした。

    openfileDaialogで選択したファイル(PDF)を、WebBrowser1.Navigate("A.PDF")のように
    ブラウザに表示しなかれば、問題なくA.PDFは削除できます。
    一度、ブラウザに表示すると、WebBrowswrをDisposeしても、
    ExplolerでA.PDFを削除しようとすると
    「別のプログラムがこのファイルを開いているので、操作を完了できません。
    ファイルを閉じてから再実行してください」と表示されてしまいます。
    何か、原因に心当たりはありませんでしょうか?


    2009年5月22日 5:29
  • 一度、ブラウザに表示すると、WebBrowswrをDisposeしても、
    ExplolerでA.PDFを削除しようとすると
    「別のプログラムがこのファイルを開いているので、操作を完了できません。
    ファイルを閉じてから再実行してください」と表示されてしまいます。
    何か、原因に心当たりはありませんでしょうか?
    Adobe Readerがファイルを閉じていないのかな?(閉じ忘れ or インスタンスが実は残っている or IEがAdobe Readerを解放していない)
    そうであれば、プログラムを終了するまで解放されませんね。

    Adobe Readerの不具合か、ブラウザの不具合になります。
    別の問題で、CoFreeUnusedLibrariesを使うと言ったアプローチがあると最近提案がありました。
    効果の程は分かりませんが、試してみてはいかがでしょうか?
    http://social.msdn.microsoft.com/Forums/ja-JP/netfxgeneralja/thread/4d268e9e-e123-465e-9816-893022b11d61

    ※CoFreeUnusedLibrariesはAPIです。必要に応じてDeclare文を宣言して下さい。

    OpenDialogが原因かもしれません。
    FileDialog.RestoreDirectoryプロパティ というものがあり、このプロパティをtrueに設定することで削除が可能になる可能性があります。

    私はフォルダを削除しようとしていましたが、このせいでできませんでした。
    そのケースはあくまで、カレントフォルダが切り替わるというものです。
    カレントフォルダと設定されているフォルダ自体は消せなくなりますが、ファイル自体は消せます。
    このため、残念ながら今回のケースとは異なります。
    解決した場合は、参考になった返信に「回答としてマーク」のボタンを利用して、回答に設定しましょう(複数に設定できます)。
    2009年5月22日 23:39
    モデレータ
  • 回答にはなっていませんが…。

    すでにAzuleanさんからも指摘されていますが、OpenDialogはファイル削除に関係ありません。
    Form→WebBrowser(ActiveX)→PDF Reader(ActiveX)という遠回りな表示方法はどうかと思いました。とはいえ、試しにFormに直接PDF Readerを配置してみたところエラーになって動作しませんでした。原因がどちらにあるのかはわかりませんが。
    ところでIEの設定で、PDF Readerを無効化していると、Form内に表示されるのではなくダウンロードダイアログが出るだけのアプリになってしまうと思いますが、それでもいいのでしょうか?
    最後に、AdobeのPDF ReaderやFlashはセキュリティホールが多く、そこを攻撃するウィルスが現在蔓延しています。個人的にはもうPDFを扱いたくないぐらいです。ウィルスの温床とならないようお気をつけを。
    2009年5月22日 23:53
  • ところでIEの設定で、PDF Readerを無効化していると、Form内に表示されるのではなくダウンロードダイアログが出るだけのアプリになってしまうと思いますが、それでもいいのでしょうか?
    補足です。
    ブラウザのActiveXを動作させる・させないの設定の他、Adobe Reader側にもブラウザで表示するかどうかの設定があります。


    あと希かもしれませんが、PDFを別のPDFビューアに関連づけていて、Adobe Readerがインストールされていないケースもありますね。


    解決した場合は、参考になった返信に「回答としてマーク」のボタンを利用して、回答に設定しましょう(複数に設定できます)。
    2009年5月23日 5:11
    モデレータ
  • IEのverはどうなってます?

    別件でIE8がページを閉じてもオブジェクトを解放してないのではないかと疑っているもので。

    試しに、IE8でPDFファイルを2つ順に開いてみました。前のファイルはリネームできたので、再現しないと思いましたが、戻って進むと、どちらもリネームできなくなりました。別のタブを残して、そのタブを閉じても、リネームできません。adobe readerのプロセスはしばらくして自然に終了しましたが、その後もリネームできません。IEを終了するとリネームできるようになりました。どうもIEがファイルをオープンしたままになっているようです。次に、A,B,Cの順に開いたときも、A,BではAがリネームできましたが、A,B,CでBがリネームできなくなりました。また、そのIEを終了しても駄目で、ほかのIEも終了してやっと解放されました。IEはなんかむずかしいことをやっているのではないでしょうか。
    2009年5月23日 10:16
  • > IEのverはどうなってます?

    Web サーバーからダウンロードして IE で表示するのではなくて、WebBrowser を使ってすべて
    ローカルの PC で行うということのようです。

    ちょっと試してみましたが、どうも Adobe Reader の問題のようです。CoFreeUnusedLibraries
    も試してみましたがダメで、解決策は見つかりませんでした。

    2009年5月23日 10:49
  • 以下の回避法を試してみてください。IEでは回避できるようです。
    A.pdf
    about:blank
    B.pdf
    about:blank
    C.pdf
    about:blank

    IE8でナビゲーション性能を上げるために、アンロードとロードを並列処理化したのでは?
    普通のWebページでは問題なくても、PDFやMHTMLでは資源解放がIE終了まで遅延するのでは?
    と想像してます。
    2009年5月23日 12:35
  • いろいろアドバイスをありがとうございます。
    IEのバージョンは8.0です。
    VistaでもXPでもIE7では、資源を解放し正しく動作することを確認しました。

    ウィンドウスクリプトプログラマさんのご指摘のabout:blankをしていますが
    IE8ではアプリケーションを終了させないと資源を解放しないようです。
    参考のためサンプルプログラムを掲載します。


    'Textbox1:WebBrowser1に表示するドキュメントのファイル名
    'Button1:OpenFileDailog1の参照ボタン

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Me.OpenFileDialog1.ShowDialog()
            If Me.OpenFileDialog1.FileName = "" Then Exit Sub

            TextBox1.Text = OpenFileDialog1.FileName
            Try
                WebBrowser1.Url = New Uri(TextBox1.Text)
            Catch ex As Exception
                MessageBox.Show(ex.Message)
            End Try

            MessageBox.Show("PDFドキュメントが表示された")

            If System.IO.File.Exists(TextBox1.Text) Then
                WebBrowser1.Navigate("about:blank")
            End If

            MessageBox.Show("ブランクページを表示")
            'ここでエクスプローラで選択されたファイルを削除しようとしても
            '”別のプログラムがこのファイルを開いているので、操作を完了できません”と表示される
        End Sub

    2009年5月26日 3:17
  • それでだめなら、これもだめかもしれませんが、
    WebBrowser1.Document.Src="NUL"
    を試してみてください。

    あと、"about:blank"の場合はCoFreeUnusedLibrariesを併用する必要があるのかも。
    2009年5月26日 8:29
  • ウィンドウズプログラマさま

    解決できました!! ありがとうございました。
    IE7では問題なくうごいていたのがIE8では前述の現象が発生し
    1週間苦しんでいましたが解決できました。
    本当にありがとうございました。

    以下、ご指摘いただいたように正常動作するサンプルプログラムを掲載させていただきます。
    本当にありがとうございました。感謝!感謝です。

    Public Class Form1
        'Textbox1:WebBrowser1に表示するドキュメントのファイル名
        'Button1:OpenFileDailog1の参照ボタン
        Declare Sub CoFreeUnusedLibraries Lib "ole32.dll" ()
        Private Sub Form3_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Me.WebBrowser1.Navigate("about:blank")
            Application.DoEvents()
            CoFreeUnusedLibraries()
        End Sub
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Me.OpenFileDialog1.ShowDialog()
            If Me.OpenFileDialog1.FileName = "" Then Exit Sub

            TextBox1.Text = OpenFileDialog1.FileName
            Try
                WebBrowser1.Url = New Uri(TextBox1.Text)
            Catch ex As Exception
                MessageBox.Show(ex.Message)
            End Try

            MessageBox.Show("PDFドキュメントが表示された")

            If System.IO.File.Exists(TextBox1.Text) Then
                Me.WebBrowser1.Navigate("about:blank")
                Application.DoEvents()       '##### この行を挿入することで解決
                CoFreeUnusedLibraries()    '##### この行を挿入することで解決!
            End If

            MessageBox.Show("ブランクページを表示")

            'ここでエクスプローラで選択されたファイルを削除しようとしても
           '上記の##### この行がないと
            '”別のプログラムがこのファイルを開いているので、操作を完了できません”と表示される
        End Sub

        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            Dispose()
        End Sub
    End Class

    2009年5月26日 10:03
  • > IE7では問題なくうごいていたのがIE8では前述の現象が発生し
    > 1週間苦しんでいましたが解決できました。

    使用しているコントロールの WebBrowser というのは System.Windows.Forms.WebBrowser クラスのこと
    ですよね(SHDocVw ライブラリで IE を操作するのではなくて)?

    System.Windows.Forms.WebBrowser がその PC にインストールされている IE のバージョンの影響を受
    けるのでしょうか? よろしければ教えてください。

    2009年5月27日 13:57
  • System.Windows.Forms.WebBrowser がその PC にインストールされている IE のバージョンの影響を受
    けるのでしょうか? よろしければ教えてください。
    逆に私が疑問を感じたのは、なぜIEの影響を受けないとお考えになったのかという点です。


    System.Windows.Forms.WebBrowserはActiveXコントロールのラッパーに過ぎません。
    .NET Frameworkのクラスライブラリのソースコードを見ると分かりますが、WebBrowserクラスはCLSID"8856f961-340a-11d0-a96b-00c04fd705a2"のCOMを利用します。
    "8856f961-340a-11d0-a96b-00c04fd705a2"は"Microsoft Web Browser"として登録されており、"C:\WINDOWS\system32\ieframe.dll"で実装されています。
    ファイル名からIEの影響を受けると予想されます。

    (WebBrowserクラスを通じた場合UserAgentがIE8.0にならないように見受けられますが、内部のエンジンはIE8.0と共通なのかなと予想しています。こちらは裏付けがありません)
    解決した場合は、参考になった返信に「回答としてマーク」のボタンを利用して、回答に設定しましょう(複数に設定できます)。
    2009年5月27日 15:35
    モデレータ
  • > なぜIEの影響を受けないとお考えになったのかという点です。

    考えというよりは、想像にすぎないといわれるかもしれませんが・・・

    IE は Windows Update の自動更新でユーザーの知らないうちにバージョンアップさ
    れてしまいますが、その結果 WebBrowser を使ったアプリが期待の動作をしなくなる
    のは影響が大きい → それゆえ影響を受けないようになっているであろう・・・という
    考え(過大な期待?)です。

    影響があるということらしいので、実際に自分で試してみようと思っていますが、そ
    の前に念のため質問させていただきました。

    2009年5月28日 13:19
  • IE は Windows Update の自動更新でユーザーの知らないうちにバージョンアップさ
    れてしまいますが、その結果 WebBrowser を使ったアプリが期待の動作をしなくなる
    のは影響が大きい → それゆえ影響を受けないようになっているであろう・・・という
    考え(過大な期待?)です。
    内部がどのように実装されているかを外見から想像することは、確かに難しいです。
    ドキュメントからは、何となく想像できそうです。

    WebBrowserクラス
    http://msdn.microsoft.com/ja-jp/library/system.windows.forms.webbrowser.aspx
    → WebBrowser.Documentプロパティ
    http://msdn.microsoft.com/ja-jp/library/system.windows.forms.webbrowser.document.aspx
    → HtmlDocumentクラス
    http://msdn.microsoft.com/ja-jp/library/system.windows.forms.htmldocument.aspx

    > HtmlDocument は、HTML DOM (Document Object Model) とも呼ばれる Internet Explorer のドキュメント オブジェクトのマネージ ラッパーを提供します。

    何らかの関係を持つことは疑えるかと思います。
    ただ、こういった内容はクラスについての部分で語るべき内容かもしれません。

    解決した場合は、参考になった返信に「回答としてマーク」のボタンを利用して、回答に設定しましょう(複数に設定できます)。
    2009年5月28日 15:10
    モデレータ
  • Adobe Reader 8.1.5 でですが、Vista SP1 + .NET 3.5 SP1 + IE7 がインストールされている
    PC で試した後、同じ PC の IE を 8 にアップデートして違いを調べてみました。

    結果はやはり影響ありで、影響を受けないようになっているであろうと考えたのは過大な期待だっ
    たようです。(汗)

    Adobe Reader のバージョンが違うせいか、質問者さんがレポートされていたのとは様子が異なり
    ましたが、IE のバージョンによって動作が違うのは間違いなさそうです。

    なお、自分が試した限りでは、CoFreeUnusedLibraries は効果なしで、ポイントは pdf を開く前
    に about:blank に Navigate することでした。

    IE7 の場合はその必要はありませんでしたが、IE8 の場合は、いきなり  pdf を開くと、その後
    about:blank に Navigate しても pdf ファイルは開放されないという結果になりました。

    何故そうなるかは調べ切れていません(というより、これ以上調べる気力がないです(笑))。

    2009年5月31日 6:06
  • こんにちは、フォーラムオペレータの高橋春樹です。

    VB136さん、Azuleanさん、佐祐理さん、ウィンドウズスクリプトプログラマさん、SurferOnWwwさん
    いつもお世話になっております。
    アドバイスありがとうございました。
    回避策が見つかってよかったです(^-^;)

    SurferOnWwwさん
    環境によってはCoFreeUnusedLibrariesは効果ないのですね。
    調べて頂き、ありがとうございます。
    沢山の情報があると、より多くの方の参考になるので助かります。

    東京都のりきまるですさん、はじめまして。
    MSDNフォーラムのご利用ありがとうございます。
    回避策の具体的なサンプルコードを投稿して頂き、ありがとうございます。

    問題が解決したので、大丈夫と思いますが、皆様から頂いたアドバイスに
    回答マークを付けさせてもらいました。

    今後ともMSDNフォーラムをよろしくお願いします。


    マイクロソフト株式会社 フォーラム オペレータ 高橋春樹
    2009年6月5日 8:18