2013-08-21 12 views
8

私は、両方のWeb環境でデスクトップ環境で使用できるユーティリティライブラリを作成しています。urlmon.dll FindMimeFromData()は64bitデスクトップ/コンソールではうまく動作しますが、ASP.NETでエラーが発生します

これは、ファイルのMIMEタイプを(拡張子ではなく)ファイルを取得するユーティリティを含む、私のアプリケーションでよく繰り返されると思われるいくつかの機能が含まれています。私がチェックする必要があります

ファイルが最も一般的である(JPG、PNG、PDF、TXT)ので、私は外部の方法(上記のリンク)

Using .NET, how can you find the mime type of a file based on the file signature not the extension

方法を使用することにしましたreturn文の前にチェックをするだけで簡単に解決できるJPG(image/pjpg)とPNG(image/x-png)の2つの誤ったMIMEタイプを除いてうまくいきます。

ライブラリは32ビットと64ビットの両方のサーバー/クライアントにインストールする必要があるため、プラットフォームAnyCPU用にコンパイルされます。

x86およびx64向けにコンパイルされたアプリケーションのデスクトップ環境でのテストがすべて正しく動作しています。

ASP.NETアプリケーション(テスト用のHTTPハンドラを持つ空のサイト)のテスト時に、HRESULT型のエラーが発生し、デバッガがそれ以上の情報を提供できないことを通知します。

(NO結果)ローカルシステムにプールのIDを変更するなど、いくつかのテスト構成の後、私はこの問題を特定した:

プールは、32ビットのアプリケーション(上記画像参照)を可能にすべきです。

IisAllow32BitApplication

なぜ?

私たちは現在64ビットシステムのurlmon.dllをロードしてはいけませんか?

方法は、このライブラリにどこでも呼び出すことができので、これは、大きな問題である:

結果は、別のユーティリティメソッドにより、このメソッドの呼び出しは、この例外をスローし、トレースにそれが困難かもしれないということですデバッグによっても問題が発生します。

アイデア/経験ありですか?

されているオペレーティングシステムは

デスクトップのテストに使用:

  • のWindows Server 2008の標準R2 x64のを作品- -
  • のWindows 7のx64で動作します

    1. のWindows 8のx64を - 作品
    2. Windows 8の

      1. Windows Server 2008の標準のx86 -

      Webの作品から

    3. のWindows XP ProfessionalのSP3で動作します -
    4. のWindows Server 2003の標準のx86の作品x64 - 最初にエラーが見つかりました.32ビットアプリケーションのみが有効です
    5. のWindows Server 2008の標準R2 x64の -

    EDIT 2(質問解決)

    に動作します - エラーは32ビットアプリケーションでのみ動作しますが、
  • のWindows Server 2008の標準のx86が有効になって、確認しました

    解決済みNoseratio

    正しいパラメータppwzMimeOutpBCのタイプは、System.UInt32ではなく、System.IntPtrでなければなりません。

    私は、System.UInt32が完全な64ビットWebアプリケーションに問題を引き起こしていることを知っていますが、理由はわかりません。

    誰かがこれらの問題の原因を知っている場合は、コメントでそれをよりよく説明できますか?事前に

    おかげで

  • +1

    これは、[this](http://stackoverflow.com/a/15595571/495455)のような 'URLMon.dll'のフォールバックメソッドを持つのが良い理由です。または、あなたのケースでは、ウィリアムのためにウルモンを全部捨てる。 –

    答えて

    10

    があなたのリンクanswerからのPInvoke署名を使用した場合、次のようにそこに定義されています:

    [DllImport(@"urlmon.dll", CharSet = CharSet.Auto)] 
    private extern static System.UInt32 FindMimeFromData(
        System.UInt32 pBC, 
        [MarshalAs(UnmanagedType.LPStr)] System.String pwzUrl, 
        [MarshalAs(UnmanagedType.LPArray)] byte[] pBuffer, 
        System.UInt32 cbSize, 
        [MarshalAs(UnmanagedType.LPStr)] System.String pwzMimeProposed, 
        System.UInt32 dwMimeFlags, 
        out System.UInt32 ppwzMimeOut, 
        System.UInt32 dwReserverd 
    ); 
    

    私はむしろpinvoke.netから定義のそれぞれで独立し使用します。

    [DllImport("urlmon.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = false)] 
    static extern int FindMimeFromData(IntPtr pBC, 
        [MarshalAs(UnmanagedType.LPWStr)] string pwzUrl, 
        [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I1, SizeParamIndex=3)] 
        byte[] pBuffer, 
        int cbSize, 
        [MarshalAs(UnmanagedType.LPWStr)] string pwzMimeProposed, 
        int dwMimeFlags, 
        out IntPtr ppwzMimeOut, 
        int dwReserved); 
    

    ppwzMimeOutpBCパラメータの型の違いに注意してください。前者の場合、System.UInt32は、64ビットプラットフォームの64ビットポインタには正しいタイプではありません。 pBCの場合、これは問題ではない(NULLである限り)が、ppwzMimeOutの場合は重要です。

    正しいと思われるthis implementationを参照してください。

    +1

    ちょっと男...パラメータpBCとppwzMimeOutのタイプを変更した後は、どこでも使えます!どうもありがとう! –

    +1

    問題なく、うれしいことです:] BTW、 'ppwzMimeOut'(' [here](http://stackoverflow.com/a/2826884/1768303))で 'Marshal.FreeCoTaskMem'を呼び出すことを忘れないでください。それは漏れるでしょう。 – Noseratio

    +1

    もちろん);ありがとう –

    関連する問題