11

デスクトップ環境と Web 環境の両方で使用されるユーティリティのライブラリを作成しています。

これには、ファイルのコンテンツ (拡張子ではなく) によってファイルの MIME タイプを取得するユーティリティなど、私のアプリケーションで頻繁に繰り返されると思われるいくつかの機能が含まれています。

チェックする必要があるファイルは最も一般的なもの (jpg、png、pdf、txt) であるため、外部メソッドFindMimeFromData(上記のリンク)を使用することにしました。

.NET を使用して、拡張子ではなくファイル署名に基づいてファイルの MIME タイプを見つける方法

この方法はうまく機能しますが、JPG ( image/pjpg) と PNG ( image/x-png) の 2 つの不適切な MIME タイプを除いては、return ステートメントの前にチェックを行うことで簡単に解決できます。

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

デスクトップ環境でテストした時点では、x86 および x64 用にコンパイルされたアプリケーションの両方ですべて正常に動作しました。

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

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

プールは 32 ビット アプリケーションを許可する必要があります (上の画像を参照)。

IisAllow32BitApplication

なんで?

urlmon.dll現在の 64 ビット システムの dll をロードするべきではありませんか?

FindMimeFromDataこのライブラリのどこからでもメソッドを呼び出すことができるため、これは大きな問題です。

その結果、別のユーティリティ メソッドによってこのメソッドを呼び出すと、この例外がスローされる可能性があり、デバッグによっても問題を追跡することが困難になります。

アイデア/経験はありますか?

テストに使用したオペレーティング システム

デスクトップ:

  1. Windows 8 x64 -動作
  2. Windows 7 x64 -動作
  3. Windows Server 2008 Standard R2 x64 -動作
  4. Windows Server 2008 Standard x86 -動作
  5. Windows Server 2003 Standard x86 -動作
  6. Windows XP Professional SP3 -動作します

ウェブ:

  1. Windows 8 x64 -最初のエラーが見つかりました。32 ビット アプリケーションが有効になっている場合にのみ動作します
  2. Windows Server 2008 Standard R2 x64 -エラーが確認されました。32 ビット アプリケーションが有効になっている場合にのみ動作します
  3. Windows Server 2008 Standard x86 -動作

EDIT 2(質問は解決しました)

Noseratioによって解決:

パラメータの正しいタイプは、ではなく である必要がありppwzMimeOutます。pBCSystem.IntPtrSystem.UInt32

System.UInt32完全な 64 ビット Web アプリで問題が発生することはわかっていますが、その理由はわかりません。

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

前もって感謝します

4

1 に答える 1

17

リンクされた回答の 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.UInt3264 ビット プラットフォームでの 64 ビット ポインターの正しい型ではありません。の場合pBC、これはおそらく問題ではありませんが (NULL である限り) ppwzMimeOut、.

正しいと思われるこの実装を参照してください。

于 2013-09-01T00:59:59.970 に答える