none
WebBrowserコントロール上で PDFを表示させた後、そのまま終了させると「アプリケーション エラー」が発生。 RRS feed

  • 質問

  • ■ ハードウェア・ソフトウェア環境
    ・CPU   :Intel(R) Pentium(R) M 1.20GHz
    ・RAM   :1 GB
    ・OS    :Microsoft Windows XP Professional Version 2002 Service Pack 3
    ・その他:Adobe Acrobat Reader 9 (バージョン9.0.0)
                Microsoft Visual Studio 2005 (.Net Framework 2.0)

     

    ■ コードサンプル
    using System;
    using System.Collections.Generic;
    using System.Windows.Forms;

    namespace SimpleWebBrowser
    {
        static class Program
        {
            [STAThread]
            static void Main()
            {
                Application.Run(new BrowserForm());
            }
        }

        public partial class BrowserForm : Form
        {
            System.Windows.Forms.WebBrowser webBrowser;
            public BrowserForm()
            {
                this.webBrowser = new WebBrowser();
                this.webBrowser.Dock = DockStyle.Fill;
                this.Controls.Add(this.webBrowser);
                this.Load += new EventHandler(BrowserForm_Load);
            }
            void BrowserForm_Load(object sender, EventArgs e)
            {
                this.webBrowser.Url = new Uri("{PDFのパスを指定しています。}");
            }
        }
    }

    ■ 背景&現状
     ドキュメントファイル(PDF,Word,Excelなど)や、画像を一つのツールで開きたいという要望を受け
     .NET Framework 2.0から提供されたWebBrowserコントロールで、その代用をする事を考えています。
     現在、実装してみたものの、WebBrowser上で PDFを表示させた後、
     そのまま終了させるとアプリケーションが終了した後に、「アプリケーション エラー」が
     必ず表示されてしまいます。
      ※ Debugではでませんが、Release起動で次のようなメッセージが表示されます。
        「 "0x05331a8f" の命令が "0x00000004" のメモリを参照しました。メモリが"read"になることはできませんでした。
          プログラムを終了するには[OK]をクリックしてください 」
      
     今の所分かっている原因として、WebBrowserコントロール内で参照されている
     Acrobat Reader の ActiveXコントロールが終了する前に
     アプリケーションが終了すると発生する事です。
      ※ Acrobat Readerで提供されている次の2つのモジュールとなります。
        AcroRd32.dll, AcroPDF.dll

     WebBrowserコントロールのリソースを解放し、
     この2つのDLLを使用しているスレッドが終了するまで待てば、正常に終了する事が出来ます。
     また、Acrobat Reader 8 では問題なく表示/終了する事ができました。
     

      プログラムの方で、何か、対応策がありましたら、ご教授頂けたらと思います。
     よろしくお願い致します。

     

    2009年1月16日 9:57

回答

  • 本筋ではないところですみません。

     

     ほうじ茶 さんからの引用

     ・Office系 については、必ず関連付けが設定されているという条件になっています。

       ただし、Office2007については、検討が必要になりそうです。

    誤解させたかもしれません。

    関連付けはされているのですが、ユーザが少し設定を変えるだけで、IEの中で開かず、単体のアプリケーション(Word/Excel等)として必ず開くようにするという風に変更ができるのです。

    http://www.atmarkit.co.jp/fwin2k/win2ktips/541officeweb/officeweb.html

     

    関連付けされていない状態にするわけではないのでご留意ください。

     

     ほうじ茶 さんからの引用

     ・Acrobat Reader についても、8.0 以上がインストールされている事 が前提なのですが、

       Acrobat Reader 9.0が今回問題になってしまいました。 この際、9.0は駄目という制限をかけたいとろこですが。

    少なくとも、7.0でブラウザで開かないという設定が存在することを確認しています。

    手法は下記のページを参照して下さい。

    http://www.atmarkit.co.jp/fwin2k/win2ktips/545adobeweb/adobeweb.html

     

     

    ユーザによっては、ブラウザの中でExcelやWordを開いたときに、別途起動しているExcel等に影響するのが嫌で、オプションを変更している可能性があります。

    (現に私がそうなので…)

     

    もちろん、それらを考慮して、今回の要件で「ユーザは絶対にそのように設定していない」であれば、私の指摘は杞憂となります。

     

     

     ほうじ茶 さんからの引用

     PDFをアプリケーションの内部で表示せず、新しいウィンドウで表示する。や

     Acrobat SDK を使用して試すなどでしょうか。 

    そんなに難しく考えなくても、下記のようにProcess.Startを使えば関連付けを利用して、Adobe Readerが立ち上がると思います。

    (Adobe Readerがインストール済みであることは必要条件です)

     

    Code Snippet

    Process.Start(@"c:\foo\bar.pdf");

     

     

    2009年1月19日 14:32
    モデレータ

すべての返信

  •  ほうじ茶 さんからの引用

     ドキュメントファイル(PDF,Word,Excelなど)や、画像を一つのツールで開きたいという要望を受け
     .NET Framework 2.0から提供されたWebBrowserコントロールで、その代用をする事を考えています。

    そもそも論なのですが、デフォルトでWord/Excel 2007はWebBrowserコントロールの中では開きませんよね?

    その辺は問題ないのですか?

     

    # 問題があったところで、どうしようもないのですけれども。

     

     ほうじ茶 さんからの引用

      プログラムの方で、何か、対応策がありましたら、ご教授頂けたらと思います。
     よろしくお願い致します。

    WebBrowserでabout:blankあたりに一旦移動させて、読み込み完了イベントを受けてから終了するとか?

     

    試してないので、適当です。できなかったらすみません。

    2009年1月16日 14:24
    モデレータ
  • Azulean様

    ご回答ありがとう御座います。

     

     Azulean さんからの引用

    そもそも論なのですが、デフォルトでWord/Excel 2007はWebBrowserコントロールの中では開きませんよね?

    その辺は問題ないのですか?

     現在、私の身近にWord/Excel 2007 の環境がなかったので、試しておりませんでした。

     顧客の方で、まずはPDFが見たいという事で、対応しております。

     Word/Excel はバージョンによって開けないのであれば、方法を考えねばなりませんね・・・。ご指摘ありがとう御座います。

     

     逆に質問してしまいますが、Word/Excel 2007は、WebBrowserコントロール内で開けずに

     単独のアプリケーションとして開くように動作するのでしょうか?

     

     Azulean さんからの引用

    WebBrowserでabout:blankあたりに一旦移動させて、読み込み完了イベントを受けてから終了するとか?

     

    試してないので、適当です。できなかったらすみません。

     ご意見を頂けるだけで幸いです。有難う御座います。

     早速ですが、プログラムを作成して見ました。 下記にあるSample Source をご参照下さい。

     

      動作としては、終了時にページをabout:blankに移動させ、DocumentCompleted イベントが発生した後、

     終了するようにしました。

     残念ながら、以前と同様のアプリケーションエラーが発生しました。 私のプログラムが悪いのかもしれませんが・・・。

     

     

    Sample Source

    using System;
    using System.Collections.Generic;
    using System.Windows.Forms;
    namespace SimpleWebBrowser
    {
        static class Program
        {
            [STAThread]
            static void Main()
            {
                Application.Run(new BrowserForm());
            }
        }

        public partial class BrowserForm : Form
        {
            bool closed = false;
            System.Windows.Forms.WebBrowser webBrowser;
            public BrowserForm()
            {
                this.webBrowser = new WebBrowser();
                this.webBrowser.Dock = DockStyle.Fill;
                this.Controls.Add(this.webBrowser);
                this.Load += new EventHandler(BrowserForm_Load);
                this.FormClosed += new FormClosedEventHandler(BrowserForm_FormClosed);
                this.FormClosing += new FormClosingEventHandler(BrowserForm_FormClosing);
            }
            void BrowserForm_FormClosing(object sender, FormClosingEventArgs e)
            {
                if (!closed)
                {
                    e.Cancel = true;
                    this.webBrowser.DocumentCompleted +=

                        new WebBrowserDocumentCompletedEventHandler

                            (webBrowser_DocumentCompleted);
                    this.webBrowser.Url = new Uri("about:blank");
                }
            }

            void webBrowser_DocumentCompleted(

                 object sender, WebBrowserDocumentCompletedEventArgs e)
            {
                closed = true;
                this.Close();
            }
            void BrowserForm_FormClosed(object sender, FormClosedEventArgs e)
            {

            }
            void BrowserForm_Load(object sender, EventArgs e)
            {
                this.webBrowser.Url = new Uri("{PDFのパスを指定しています。}");
            }
        }
    }

     

     

     

    2009年1月17日 4:19
  •  ほうじ茶 さんからの引用

     逆に質問してしまいますが、Word/Excel 2007は、WebBrowserコントロール内で開けずに

     単独のアプリケーションとして開くように動作するのでしょうか?

    デフォルトではそうなります。

    レジストリ等を編集すれば動作を変えられるそうですが、試していません。

    http://support.microsoft.com/kb/927009/ja

     

    逆に言うと、Office 2003以前であっても、関連付けの設定を変更していると、ブラウザの中で開きません。

    # 少なくとも、Excel 2003ではフォルダオプションから関連付けの設定を変更してブラウザ内で開かないように設定できます。

     

    そのほか、Acrobat Readerのバージョンによってはブラウザの中で開かないとか設定できたはずです。

     

    これらの事実から、全てのユーザ環境で、WebBrowserコントロールの中で動くということを期待できません。

    特定顧客しか使用しない、操作・運用方法の制限をユーザに対して課すことができるといった限定的な環境でのみ、今回の要件を満たすことができます。

     

     ほうじ茶 さんからの引用

    ※ Debugではでませんが、Release起動で次のようなメッセージが表示されます。
        「 "0x05331a8f" の命令が "0x00000004" のメモリを参照しました。メモリが"read"になることはできませんでした。
          プログラムを終了するには[OK]をクリックしてください 」

    これを試してみましたが、デバッグ版でも「デバッグなしで実行」あるいはexeを叩けば再現しました。

    多分、Debugで起きないとされるのは、Visual Studioからデバッグ開始を選択したからでしょうね。

    (この場合、Visual Studioホスティングプロセスとして、ずっとプロセスは残っているので落ちないとか)

     ほうじ茶 さんからの引用

      動作としては、終了時にページをabout:blankに移動させ、DocumentCompleted イベントが発生した後、

     終了するようにしました。

     残念ながら、以前と同様のアプリケーションエラーが発生しました。 私のプログラムが悪いのかもしれませんが・・・。

    イベントベースではありませんが、クリックで手作業でabout:blankに遷移させ、画面で確認した後、フォームを閉じてアプリを終了すると再現しました。

    WebBrowserかAdobe Readerかは分かりませんが、不具合でしょうね。

    # Adobe Reader 9.0のプラグイン関連でGoogleで検索すると、色々と出てきますが、何とも言えません。

     

    いくつか考えたり、手を出してみましたが、回避策を提案できる状態にはありません。

    2009年1月17日 12:15
    モデレータ
  • Azulean 様

     

    ご回答、ありがとう御座います。

     Azulean さんからの引用

     ほうじ茶 さんからの引用

     逆に質問してしまいますが、Word/Excel 2007は、WebBrowserコントロール内で開けずに

     単独のアプリケーションとして開くように動作するのでしょうか?

    デフォルトではそうなります。

    レジストリ等を編集すれば動作を変えられるそうですが、試していません。

    http://support.microsoft.com/kb/927009/ja

     

    逆に言うと、Office 2003以前であっても、関連付けの設定を変更していると、ブラウザの中で開きません。

    # 少なくとも、Excel 2003ではフォルダオプションから関連付けの設定を変更してブラウザ内で開かないように設定できます。

     

    そのほか、Acrobat Readerのバージョンによってはブラウザの中で開かないとか設定できたはずです。

    これらの事実から、全てのユーザ環境で、WebBrowserコントロールの中で動くということを期待できません。

    特定顧客しか使用しない、操作・運用方法の制限をユーザに対して課すことができるといった限定的な環境でのみ、今回の要件を満たすことができます。

       

     ・Office系 については、必ず関連付けが設定されているという条件になっています。

       ただし、Office2007については、検討が必要になりそうです。

     ・Acrobat Reader についても、8.0 以上がインストールされている事 が前提なのですが、

       Acrobat Reader 9.0が今回問題になってしまいました。 この際、9.0は駄目という制限をかけたいとろこですが。

     

     Azulean さんからの引用

     ほうじ茶 さんからの引用

    ※ Debugではでませんが、Release起動で次のようなメッセージが表示されます。
        「 "0x05331a8f" の命令が "0x00000004" のメモリを参照しました。メモリが"read"になることはできませんでした。
          プログラムを終了するには[OK]をクリックしてください 」

    これを試してみましたが、デバッグ版でも「デバッグなしで実行」あるいはexeを叩けば再現しました。

    多分、Debugで起きないとされるのは、Visual Studioからデバッグ開始を選択したからでしょうね。

    (この場合、Visual Studioホスティングプロセスとして、ずっとプロセスは残っているので落ちないとか)

     ほうじ茶 さんからの引用

      動作としては、終了時にページをabout:blankに移動させ、DocumentCompleted イベントが発生した後、

     終了するようにしました。

     残念ながら、以前と同様のアプリケーションエラーが発生しました。 私のプログラムが悪いのかもしれませんが・・・。

    イベントベースではありませんが、クリックで手作業でabout:blankに遷移させ、画面で確認した後、フォームを閉じてアプリを終了すると再現しました。

    WebBrowserかAdobe Readerかは分かりませんが、不具合でしょうね。

    # Adobe Reader 9.0のプラグイン関連でGoogleで検索すると、色々と出てきますが、何とも言えません。

     

    いくつか考えたり、手を出してみましたが、回避策を提案できる状態にはありません。

     貴重なお時間を割いて頂き有難うございます。

     やはり、別の方法で対策を練らねばなりませんね・・・。

     PDFをアプリケーションの内部で表示せず、新しいウィンドウで表示する。や

     Acrobat SDK を使用して試すなどでしょうか。 

     現在、デモのため、簡易対応をとらせてもらっている形ですが、

     こちらでも、検討する必要がありそうです。

     

     また、この問題について自己解決した場合には、結果の報告を致します。

     また、引き続き、ご意見を募集したいと思います。

     

     ご協力ありがとう御座います。

     

    2009年1月19日 1:38
  • 本筋ではないところですみません。

     

     ほうじ茶 さんからの引用

     ・Office系 については、必ず関連付けが設定されているという条件になっています。

       ただし、Office2007については、検討が必要になりそうです。

    誤解させたかもしれません。

    関連付けはされているのですが、ユーザが少し設定を変えるだけで、IEの中で開かず、単体のアプリケーション(Word/Excel等)として必ず開くようにするという風に変更ができるのです。

    http://www.atmarkit.co.jp/fwin2k/win2ktips/541officeweb/officeweb.html

     

    関連付けされていない状態にするわけではないのでご留意ください。

     

     ほうじ茶 さんからの引用

     ・Acrobat Reader についても、8.0 以上がインストールされている事 が前提なのですが、

       Acrobat Reader 9.0が今回問題になってしまいました。 この際、9.0は駄目という制限をかけたいとろこですが。

    少なくとも、7.0でブラウザで開かないという設定が存在することを確認しています。

    手法は下記のページを参照して下さい。

    http://www.atmarkit.co.jp/fwin2k/win2ktips/545adobeweb/adobeweb.html

     

     

    ユーザによっては、ブラウザの中でExcelやWordを開いたときに、別途起動しているExcel等に影響するのが嫌で、オプションを変更している可能性があります。

    (現に私がそうなので…)

     

    もちろん、それらを考慮して、今回の要件で「ユーザは絶対にそのように設定していない」であれば、私の指摘は杞憂となります。

     

     

     ほうじ茶 さんからの引用

     PDFをアプリケーションの内部で表示せず、新しいウィンドウで表示する。や

     Acrobat SDK を使用して試すなどでしょうか。 

    そんなに難しく考えなくても、下記のようにProcess.Startを使えば関連付けを利用して、Adobe Readerが立ち上がると思います。

    (Adobe Readerがインストール済みであることは必要条件です)

     

    Code Snippet

    Process.Start(@"c:\foo\bar.pdf");

     

     

    2009年1月19日 14:32
    モデレータ
  •  Azulean さんからの引用

    本筋ではないところですみません。

     

     ほうじ茶 さんからの引用

     ・Office系 については、必ず関連付けが設定されているという条件になっています。

       ただし、Office2007については、検討が必要になりそうです。

    誤解させたかもしれません。

    関連付けはされているのですが、ユーザが少し設定を変えるだけで、IEの中で開かず、単体のアプリケーション(Word/Excel等)として必ず開くようにするという風に変更ができるのです。

    http://www.atmarkit.co.jp/fwin2k/win2ktips/541officeweb/officeweb.html

     

    関連付けされていない状態にするわけではないのでご留意ください。

     設定によるものであれば、Word/Excel等の設定を変更して下さいと指示できそうです。

     WebBrowser上で開くための設定マニュアルを掲示し、各自設定してもらう事になると思われます。

     

     Azulean さんからの引用

     ほうじ茶 さんからの引用

     ・Acrobat Reader についても、8.0 以上がインストールされている事 が前提なのですが、

       Acrobat Reader 9.0が今回問題になってしまいました。 この際、9.0は駄目という制限をかけたいとろこですが。

    少なくとも、7.0でブラウザで開かないという設定が存在することを確認しています。

    手法は下記のページを参照して下さい。

    http://www.atmarkit.co.jp/fwin2k/win2ktips/545adobeweb/adobeweb.html

     

     

    ユーザによっては、ブラウザの中でExcelやWordを開いたときに、別途起動しているExcel等に影響するのが嫌で、オプションを変更している可能性があります。

    (現に私がそうなので…)

     

    もちろん、それらを考慮して、今回の要件で「ユーザは絶対にそのように設定していない」であれば、私の指摘は杞憂となります。

     

     

     ほうじ茶 さんからの引用

     PDFをアプリケーションの内部で表示せず、新しいウィンドウで表示する。や

     Acrobat SDK を使用して試すなどでしょうか。 

    そんなに難しく考えなくても、下記のようにProcess.Startを使えば関連付けを利用して、Adobe Readerが立ち上がると思います。

    (Adobe Readerがインストール済みであることは必要条件です)

     

    Code Snippet

    Process.Start(@"c:\foo\bar.pdf");

     

     

     

     今後の方向性が決まりました。 現行では、Acrobat Reader 8 版をインストールするという事になりました。

     今後、Acrobat Reader のバージョンアップにより、今回の問題が起きないようであれば、随時

     必須環境を更新していく形となります。

     

     また、デモでも、PDF、Word、Excel ・・・ などが、1つのアプリケーションとして表示されるのは、

     とても評判がいいようです。 新しいウィンドウで表示するのは、駄目そうです・・・。

     

     以上持ちまして、解決とさせて頂きます。

     

     Azulean様には、いろいろとご回答頂き、感謝しております。

     大変、有難う御座います。

    2009年1月23日 7:30
  • ・OS :Microsoft Windows XP Professional Version 2002 Service Pack 2
    ・ソフト:Adobe Acrobat Reader 9 (バージョン9.1.0)、
         Adobe Acrobat Reader 8 (バージョン8.1.3)、
         Microsoft Visual Studio 2005 (.Net Framework 2.0)

    どうも、はじめまして。

    私もほうじ茶 さんと同じ事象が発生し、ネット上で検索していたら
    ここにたどり着きました。

    私の場合は、Windowsアプリケーションにて、
    「WebBrowserコントロール上にPDFファイルを表示する」ことを
    実現したかったのですが、
    私が作成したWindowsアプリケーションを終了する(×ボタンクリック)と
    以下のエラーが表示されました。
    「"0x047f1dff" の命令が "0x00000004" のメモリを参照しました。
    メモリが "read" になることはできませんでした。」

    試しにAdobe Acrobat Reader の複数のバージョン
    で試してみた結果
    「バージョン9.1.0」だと発生し
    「バージョン8.1.3」だと発生しませんでした。
    上記の結果から、私はAdobe Acrobat Reader 9 の不具合だと
    考えますが、いかがですか?

    2009年5月11日 8:38
  • 上記の結果から、私はAdobe Acrobat Reader 9 の不具合だと
    考えますが、いかがですか?
    可能性は高いでしょう。
    ただ、それをここで論じても状況は変わりません。

    Adobe Readerの不具合と判断されたのであればAdobeに問い合わせて下さい。
    解決した場合は、参考になった返信に「回答としてマーク」のボタンを利用して、回答に設定しましょう(複数に設定できます)。
    2009年5月11日 14:26
    モデレータ
  • 確かにその通りですね。すいませんでした。
    Adobeに問い合わせます。
    2009年5月11日 23:51
  • 確かにAdobe Readerの不具合だと思いますが、
    私の場合は下記の方法で解決しました。

    フォームの終了でPDFコンポーネントが使っていたメモリを解放しようとすると、Adobe(AcroRd32.dll)
    がクラッシュされてうまく解放できなさそうで、正しく解放するために、COMのCoFreeUnusedLibraries関数
    を使います。

    VB.NETのソースですが、ご参照になればと思います。

    Public Class Form1
        Declare Sub CoFreeUnusedLibraries Lib "ole32.dll" ()

        Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
            Me.WebBrowser1.Navigate("about:blank")
            Application.DoEvents()

            'Adobe Readerのごみメモリを解放する。
            CoFreeUnusedLibraries()
        End Sub

        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Me.WebBrowser1.Navigate("D:\Buffer\m.pdf")
        End Sub
    End Class

    • 回答の候補に設定 totoso 2010年1月25日 3:24
    2009年5月22日 15:33