none
Azure Web アプリで Metafile イメージの生成で GDI+ エラーが発生。 RRS feed

  • 質問

  • お世話になります。

    Visual Studio 2013 で実装した ASP.NET Web アプリケーションを Microsoft
    Azure Web アプリに発行した際、Metafile イメージの生成で GDI+ エラーが
    発生します。なお、同様の処理を Azure クラウド サービスで実装した場合は
    問題なく動作します。Azure Web アプリの制限事項に該当するのでしょうか。

    回避方法や Azure Web アプリの制限事項等が記載されたドキュメントなどが
    ありましたら、お教えください。

      ○実装コード(C#)
      public partial class MainPage : System.Web.UI.Page
      {
          protected void Page_Load(object sender, EventArgs e)
          {
              System.Drawing.Graphics g = System.Drawing.Graphics.FromHwnd(IntPtr.Zero);
              RectangleF rc = new RectangleF(0, 0, 10, 10);
              IntPtr hdc = g.GetHdc();
              MemoryStream mem = new MemoryStream();
              Metafile emf = new Metafile(mem, hdc, rc, MetafileFrameUnit.Pixel); // ここで GDI+ エラー発生
          }

      ○エラー内容
      A generic error occurred in GDI+.

      [ExternalException (0x80004005): A generic error occurred in GDI+.]
         System.Drawing.Imaging.Metafile..ctor(Stream stream, IntPtr referenceHdc, RectangleF frameRect, MetafileFrameUnit frameUnit, EmfType type, String description) +249189
         System.Drawing.Imaging.Metafile..ctor(Stream stream, IntPtr referenceHdc, RectangleF frameRect, MetafileFrameUnit frameUnit) +53
         出力サンプル.Export.Page_Load(Object sender, EventArgs e) +103
         System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +51
         System.Web.UI.Control.OnLoad(EventArgs e) +92
         System.Web.UI.Control.LoadRecursive() +54
         System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +772

    2015年4月28日 6:25

回答

  • 上のレスで紹介した Full trust web site のスレッドの一番最後に MSFT の人が "They run in full trust, but they also run in a sandbox where certain APIs are not allowed." と述べていますね(見落としてました・・・sandbox というのは何だか分かりませんが、関係ないですか?)。

    この Sandbox はおそらく、ON/OFF できる類いではなく、全員に共通して適用される仕組みを指していると予想します。
    (いわゆる Sandbox でしょうから…)

    MS のサイトではありませんが、こういった情報がありました。
    Restriction に GDI は使えない(一部除く)と明言されています。
    https://github.com/projectkudu/kudu/wiki/Azure-runtime-environment

    このドキュメントの筆者として示されている David Ebbo 氏は MSFT のメンバー のようなので、それなりに信用できるのではないかと思います。

    2015年4月30日 7:36

すべての返信

  • Azure は触ったこともないのでハズレかもしれませんが・・・

    Session 0 分離の影響ではないでしょうか?

    > ASP.NET Web アプリケーションを Microsoft Azure Web アプリに発行した際、

    ということは、Web アプリは Windows Server 2008 以降の Session 0 分離がされたサーバー上で Session 0 上で動いているということではないですか?

    とすると、以下のページからダウンロードできる Word ドキュメントに書いてありますが、"any attempt that a service makes to render graphics fails." とのことです。

    Impact of Session 0 Isolation on Services and Drivers in Windows
    https://msdn.microsoft.com/ja-jp/library/windows/hardware/dn653293(v=vs.85).aspx

    ハズレだったら失礼しました。

    2015年4月28日 7:03
  • すみません、Session 0 の影響というのはハズレだったようです。

    アップされたコードのように、MetaFile のコンストラクタでそのエラーが出るのであれば、"render graphics" ということにはならず、Session 0 でも "fail" することはないですね。

    自分の環境(Vista SP2 の IIS 7)で同じコードを動かして検証しましたがエラーは再現できませんでした。 

    ただし、Metafile のコンストラクタで同じエラー [ExternalException (0x80004005): GDI+ で汎用エラーが発生しました。] が再現できたケースがあって、それは、以下のようなコードで指定したパスが存在しない(testfolder というフォルダが存在しない)場合でした。

    Bitmap bmp = new Bitmap(300, 300, PixelFormat.Format32bppArgb);
    Graphics g = Graphics.FromImage(bmp);
    IntPtr hdc = g.GetHdc();
    MetaFile mf = new Metafile(Server.MapPath("~/testfolder/test.emf"), hdc);

    質問者さんのコードでは MemoryStream のあたりが怪しいのではないでしょうか? (自分の環境ではエラーを再現できないのですが)

    他に、ググって調べた限りで、質問者さんのケースとは関係ないようですが、Save するときに指定したパスが存在しない等々の場合も同様なエラーが出るそうです。

    ご参考まで・・・


    【追伸】

    自分が試した環境の詳細を書くのを忘れていました。

    Vista SP2 32-bit, .NET 4, Visual Studio 2010 Professional, Web Forms アプリ, Web サイトプロジェクトを IIS7 上でサイトに設定し実行・デバッグしています。

    • 編集済み SurferOnWww 2015年4月29日 8:50 追伸追加
    2015年4月29日 7:39
  • すみません、Session 0 の影響というのはハズレだったようです。

    アップされたコードのように、MetaFile のコンストラクタでそのエラーが出るのであれば、"render graphics" ということにはならず、Session 0 でも "fail" することはないですね。

    自分の環境(Vista SP2 の IIS 7)で同じコードを動かして検証しましたがエラーは再現できませんでした。 

    ただし、Metafile のコンストラクタで同じエラー [ExternalException (0x80004005): GDI+ で汎用エラーが発生しました。] が再現できたケースがあって、それは、以下のようなコードで指定したパスが存在しない(testfolder というフォルダが存在しない)場合でした。

    Bitmap bmp = new Bitmap(300, 300, PixelFormat.Format32bppArgb);
    Graphics g = Graphics.FromImage(bmp);
    IntPtr hdc = g.GetHdc();
    MetaFile mf = new Metafile(Server.MapPath("~/testfolder/test.emf"), hdc);

    質問者さんのコードでは MemoryStream のあたりが怪しいのではないでしょうか? (自分の環境ではエラーを再現できないのですが)

    他に、ググって調べた限りで、質問者さんのケースとは関係ないようですが、Save するときに指定したパスが存在しない等々の場合も同様なエラーが出るそうです。

    ご参考まで・・・


    【追伸】

    自分が試した環境の詳細を書くのを忘れていました。

    Vista SP2 32-bit, .NET 4, Visual Studio 2010 Professional, Web Forms アプリ, Web サイトプロジェクトを IIS7 上でサイトに設定し実行・デバッグしています。


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

    質問投稿の際、詳細情報の記載が無く申し訳ございません。
    こちらでは以下の状況にて GDI+ 汎用エラーの発生を確認しております。

      ○開発環境
      ・Windows 7 SP1 (x64)
      ・Visual Studio 2013 Premium
      ・.NET Framework 4
      ・ASP.NET Web フォームアプリケーション

      ○エラー確認状況
      上記の環境で ASP.NET Web フォームアプリケーションを新規に作成後、
      Page_Load イベント内で質問のコードを実装。

      作成したアプリケーションを開発サーバー(Visual Studio)上でデバッグ実
      行したり、IIS 上に配置して実行してもエラーは発生せず、問題なし。

      Visual Studio メニュー - [ビルド] - [WebApplication1 の発行] より
      「Microsoft Azure Web Apps」を選択、Azure ポータル上に予め作成してお
      いた Web アプリに対して発行。

      ※Web アプリ概要
      ・サブスクリプション:従量課金
      ・場所:日本(西)
      ・価格レベル:問わず(無料、共有、BASIC、STANDARD 全てで発生)

      発行後の URL にアクセスすると質問の GDI+ 汎用エラー発生。

      また、同様の処理を Azure クラウド サービスアプリケーションで実装、
      Azure 上に発行しても正常動作、問題なし。

    以上の状況から、Azure Web アプリの動作環境に依存した内容であると考えて
    おりますが、Web の情報のみでは参考となる資料や Azure Web アプリの制限
    事項に関して把握することができておりません。

    その他、お気づきの点や関連情報がございましたらご指摘ください。

    2015年4月30日 2:01
  • Azure Web Apps の 前身と言える(参照)、Azure Websites では以下のようなやりとりが海外でありました。

    https://social.msdn.microsoft.com/Forums/azure/en-US/dbef6b28-9321-4c57-9b9b-848dba37ae52/creating-a-windows-metafile-in-an-azure-web-service

    > Sorry, what I mean is it is currently what cannot do for your requirement in Azure WebSites based on my research.

    (推測)Metafile は脆弱性の話が目立つものなので、Websites では制限されていたのかもしれません。


    // 正確な情報が欲しいなら Azure のサポートに聞いてみるのが正しいかと。
    2015年4月30日 2:30
  • Azulean さんのレスを見てちょっと調べてみました。

    Azure Web アプリの trust レベルは Full ではないのですか?(Medium 相当ですか?)

    そうだとするとそれが問題(の一つ?)であることは間違いなさそうです。

    自分の環境で trust レベルを High にして(ルートの web.config に <trust level="High"/> を追加して)試してもみましたが、質問者さんのコードではこれ ↓

    Graphics g = Graphics.FromHwnd(IntPtr.Zero);

    自分がアップしたコードではこれ ↓

    IntPtr hdc = g.GetHdc();

    があると、「System.Security.SecurityException: 型 'System.Security.Permissions.SecurityPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' のアクセス許可の要求に失敗しました。」という例外がスローされてサーバーエラーになりました。

    エラーメッセージが「GDI+ で汎用エラーが発生しました。」ではないですが、そこまで行く前にダメになるのは間違いなさそうです。

    ちなみに、以下のページに書いてありますが、High では次の処理を行うことができないそうです。Medium ではさらに制約が増えます。

    ・アンマネージ コードの呼び出し
    ・サービス コンポーネントの呼び出し
    ・イベント ログへの書き込み
    ・Microsoft Message Queuing キューへのアクセス
    ・ODBC、OleDb、または Oracle データ ソースへのアクセス

    trust 要素 (ASP.NET 設定スキーマ)
    https://msdn.microsoft.com/ja-jp/library/vstudio/tkscy493(v=vs.100).aspx

    Azure は全く知らないのでまたハズレかもしれませんが、以下のページの対策は参考になりませんか?

    Full trust web site
    https://social.msdn.microsoft.com/forums/azure/en-US/0b72a8bb-965f-435b-b096-7ed72fb47853/full-trust-web-site

    2015年4月30日 4:01
  • ご回答ありがとうございます。

    公式の情報については確認が取れておりませが、ご指摘のとおり Metafile の
    扱いについて制限があるかもしれないのですね。

    もう少し情報を探った上で Azure サポートの利用についても検討したいと思
    います。貴重な情報、ありがとうございます。

    2015年4月30日 6:55
  • ご回答ありがとうございます。

    trust レベルについては前身の Azure WebSites で "Full" であったかと思わ
    れますが、Azure ポータル内の Web アプリ管理画面では詳細を確認すること
    ができず、現状のセキュリティについては不明です。

    なお、Web.Config に直接 <trust level="Full"/> を追加して確認を行いまし
    たが、同様のエラーが発生することを確認致しました。

    Azulean 様からのご指摘のとおり、Metafile の扱い自体に何かしらの制限が
    ある可能性が考えられますが、こちらでも引き続き確認を行いたいと思います。

    ご返信、ありがとうございます。

    2015年4月30日 6:59
  • > trust レベルについては前身の Azure WebSites で "Full" であったかと思われますが、

    上のレスで紹介した Full trust web site のスレッドの一番最後に MSFT の人が "They run in full trust, but they also run in a sandbox where certain APIs are not allowed." と述べていますね(見落としてました・・・sandbox というのは何だか分かりませんが、関係ないですか?)。

    そのスレッドの Top realted threads の中にある以下のスレッドを見ると、もっとはっきり trust レベルは Full だと書いてありました。

    Azure Website - Full-Trust
    https://social.msdn.microsoft.com/Forums/azure/en-US/608aca31-f398-4ef5-99cd-8184b782e4e5/azure-website-fulltrust?forum=windowsazurewebsitespreview

    質問者さんと同じ環境なのかどうかは分かりませんが、同じだとすると trust レベルは原因ではなかったようです。


    ググっても同じ問題に遭遇したという記事はまったくヒットしませんし、質問者さん固有の問題がありそうな気もします。Azulean さんが言われるようにサポートに聞くのがよさそうですね。

    2015年4月30日 7:25
  • 上のレスで紹介した Full trust web site のスレッドの一番最後に MSFT の人が "They run in full trust, but they also run in a sandbox where certain APIs are not allowed." と述べていますね(見落としてました・・・sandbox というのは何だか分かりませんが、関係ないですか?)。

    この Sandbox はおそらく、ON/OFF できる類いではなく、全員に共通して適用される仕組みを指していると予想します。
    (いわゆる Sandbox でしょうから…)

    MS のサイトではありませんが、こういった情報がありました。
    Restriction に GDI は使えない(一部除く)と明言されています。
    https://github.com/projectkudu/kudu/wiki/Azure-runtime-environment

    このドキュメントの筆者として示されている David Ebbo 氏は MSFT のメンバー のようなので、それなりに信用できるのではないかと思います。

    2015年4月30日 7:36
  • > 上のレスで紹介した Full trust web site のスレッドの一番最後に MSFT の人が "They run in full trust,
    > but they also run in a sandbox where certain APIs are not allowed." と述べていますね(見落としてました・・・
    > sandbox というのは何だか分かりませんが、関係ないですか?)。

    発行した Web アプリの動作がシステムに対して悪影響を及ぼさないよう、保
    護領域上(sandbox)で動作する、という解釈で間違いないかと思われますが、
    もしかすると、後述の「一定の API の操作ができない」が該当するのかもし
    れません。

    > ググっても同じ問題に遭遇したという記事はまったくヒットしませんし、質問者さん固有の問題がありそうな
    >気もします。Azulean さんが言われるようにサポートに聞くのがよさそうですね。

    また進展がありましたらこちらから改めてご報告させて頂きたいと思いますが、
    Metafile イメージの使用制限など、Azure Web アプリに依存した情報やドキ
    ュメント類がありましたら、その旨ご返信頂けますと幸いです。

    2015年4月30日 7:54
  • MS のサイトではありませんが、こういった情報がありました。
    Restriction に GDI は使えない(一部除く)と明言されています。

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

    ご指摘のサイトにて詳細を確認致しました。
    現在までに確認できている情報から、やはり Metafile(GDI+)の操作に関して
    何かしらの制限が設けられている可能性が考えられますね。

    貴重な情報を頂き、ありがとうございます。

    なお、Azure サポートの問い合わせについては今後確認できれば改めてこの場
    でご報告させて頂きたいと思います。

    2015年4月30日 8:36
  • > もしかすると、後述の「一定の API の操作ができない」が該当するのかもしれません。

    Azulean さんが紹介された Github の記事に書いてあるように、"certain APIs are not allowed" の APIs に GDI API が含まれているということのようですね。

    MetaFile のコンストラクタが sandbox の制約に含まれるかどうかは、自分がググって調べた限りでは、Microsoft の公式文書等は見つかりませんでしたが・・・

    もし、Microsoft のサポートに確認するなどで何か情報が得られましたら、教えていただけると幸いです。

    2015年4月30日 8:36
  • > もしかすると、後述の「一定の API の操作ができない」が該当するのかもしれません。

    Azulean さんが紹介された Github の記事に書いてあるように、"certain APIs are not allowed" の APIs に GDI API が含まれているということのようですね。

    MetaFile のコンストラクタが sandbox の制約に含まれるかどうかは、自分がググって調べた限りでは、Microsoft の公式文書等は見つかりませんでしたが・・・

    もし、Microsoft のサポートに確認するなどで何か情報が得られましたら、教えていただけると幸いです。

    Azure サポートの問い合わせについては今後確認できれば改めてこの場でご報
    告させて頂きたいと思います。

    現時点で原因の特定には至っておりません(恐らく GDI API の制限)が、様々
    な情報のご提供を頂き、誠にありがとうございます。

    2015年4月30日 8:45