13

注:この質問の主な目的は、CLR のアセンブリ バインド動作を理解/説明することです。原因が突き止められると、解決策が明らかになるはずです。私のセットアップが最適ではないことは理解していますが(nativedllが署名されておらず、バージョン管理されていないなど)、CLRのバインディング動作を調査したいだけです。

asp.net ソリューションにネイティブ (非 COM、C++) dll を使用しようとしています。トピックを間違った方向にそらしてしまうと思うので、dll に名前を付けることは控えます。

ネイティブ dll はブログ サイトからのもので、あまり情報がありません。コンパイルされたアーキテクチャ、カルチャ、バージョンなどのネイティブ dll に関する情報はありません。提供されたラッパーを使用して、コンソール アプリケーションで dll を適切に使用できます。バインディングに部分的なアセンブリ名を使用する必要がある場合でも、機能します。ネイティブ アセンブリのラッパーには、次のような DLL インポートがあります。[DllImport("nativedll.dll")] public static extern void someMethod([Out] BE_VERSION pbeVersion);

私は、次のような CLR アセンブリ バインディングに関する多くの情報を読みました。

ランタイムがアセンブリを検索する方法 アセンブリの
読み込みに関するベスト プラクティス

私の理解では、アセンブリをロードできるはずですが、できません。アセンブリ バインディング エラーが発生します。

セットアップ

ネイティブ dll を呼び出すヘルパー ライブラリ (MSIL (Any CPU) としてコンパイル) は厳密な名前が付けられており、GAC にあります。. Visual Studio 開発サーバーではなく、IIS の Win 7、x64 ビット マシンで asp.net アプリを実行しています。nativedll は署名されておらず、GAC 処理もされていません。

問題
要約すると、ネイティブ dll を Windows ディレクトリ (c:\Windows) に配置すると、ソリューションは正常に動作します。それ以外の場合は、アセンブリ バインディング エラーが発生します。

質問
1. アセンブリを Windows ディレクトリにドロップするとバインドされるのはなぜですか? 2. エラーの意味: ERR: ファイルからマニフェストのインポートを抽出中にエラーが発生しました (hr = 0x80131018)? (シナリオ 1、シナリオ 6 を参照)
3. Assembly.Load*() メソッドの呼び出しが失敗するのはなぜですか? (シナリオ 3、4、5)

テストの結果

シナリオ 1:

**Setup**
Calling Assembly: GACed.
Native Assembly: Included in project; Build Action: None; Copy To Output Directory: Copy Always.

**Description:** 
Logged into the site, home page open. Did not navigate to the page with native call.

**Result:** 
    Binding Error
    *** Assembly Binder Log Entry  (12/13/2012 @ 11:28:23 AM) ***

        The operation failed.
        Bind result: hr = 0x80131018. No description available.

        Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
        Running under executable  C:\Windows\SysWOW64\inetsrv\w3wp.exe
        --- A detailed error log follows. 

        === Pre-bind state information ===
        LOG: User = NT AUTHORITY\SYSTEM
        LOG: DisplayName = nativedll
         (Partial)
        WRN: Partial binding information was supplied for an assembly:
        WRN: Assembly Name: nativedll | Domain ID: 2
        WRN: A partial bind occurs when only part of the assembly display name is provided.
        WRN: This might result in the binder loading an incorrect assembly.
        WRN: It is recommended to provide a fully specified textual identity for the assembly,
        WRN: that consists of the simple name, version, culture, and public key token.
        WRN: See whitepaper http://go.microsoft.com/fwlink/?LinkId=109270 for more information and common solutions to this issue.
        LOG: Appbase = file:///C:/WebUI/
        LOG: Initial PrivatePath = C:\WebUI\bin
        LOG: Dynamic Base = C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\webui\69d9ded4
        LOG: Cache Base = C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\webui\69d9ded4
        LOG: AppName = ca4be085
        Calling assembly : (Unknown).
        ===
        LOG: This bind starts in default load context.
        LOG: Using application configuration file: C:\WebUI\web.config
        LOG: Using host configuration file: C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet.config
        LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
        LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
        LOG: Attempting download of new URL file:///C:/Windows/Microsoft.NET/Framework/v4.0.30319/Temporary ASP.NET Files/webui/69d9ded4/ca4be085/nativedll.DLL.
        LOG: Attempting download of new URL file:///C:/Windows/Microsoft.NET/Framework/v4.0.30319/Temporary ASP.NET Files/webui/69d9ded4/ca4be085/nativedll/nativedll.DLL.
        LOG: Attempting download of new URL file:///C:/WebUI/bin/nativedll.DLL.
        LOG: Assembly download was successful. Attempting setup of file: C:\WebUI\bin\nativedll.dll
        LOG: Entering download cache setup phase.
        ERR: Error extracting manifest import from file (hr = 0x80131018).
        ERR: Setup failed with hr = 0x80131018.
        ERR: Failed to complete setup of assembly (hr = 0x80131018). Probing terminated.    

シナリオ 2:

**Setup**
Scenario 1 + Just copy the nativedll to C:\Windows folder. No reset of anytype. 

**Description**
Navigate to the page calling native.

Result: 
Success. Native Functionality is invoked. No binding failure.

シナリオ 3:

**Setup**
Calling Assembly: GACed.
Native Assembly: Build Action: None; Copy To Output Directory: Copy Always.

Description: 
    Breakpoint at the point of native function call, use immediate window to execute the following code:

        var pat = pat = Path.Combine(AppDomain.CurrentDomain.RelativeSearchPath, "nativedll.dll");
        var a = Assembly.LoadFrom(pat);

    **Result**
    Exception raised:

    System.BadImageFormatException was unhandled
      HResult=-2146234344
      Message=Could not load file or assembly 'file:///C:\WebUI\bin\nativedll.dll' or one of its dependencies. The module was expected to contain an assembly manifest.
      Source=mscorlib
      FileName=file:///C:\WebUI\bin\nativedll.dll
      FusionLog=Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
        Running under executable  C:\Windows\SysWOW64\inetsrv\w3wp.exe
        --- A detailed error log follows. 

        === Pre-bind state information ===
        LOG: User = NT AUTHORITY\SYSTEM
        LOG: Where-ref bind. Location = C:\WebUI\bin\nativedll.dll
        LOG: Appbase = file:///C:/WebUI/
        LOG: Initial PrivatePath = C:\WebUI\bin
        Calling assembly : (Unknown).
        ===
        LOG: This bind starts in LoadFrom load context.
        WRN: Native image will not be probed in LoadFrom context. Native image will only be probed in default load context, like with Assembly.Load().
        LOG: Using application configuration file: C:\WebUI\web.config
        LOG: Using host configuration file: C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet.config
        LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
        LOG: Attempting download of new URL file:///C:/WebUI/bin/nativedll.dll.
        ERR: Failed to complete setup of assembly (hr = 0x80131018). Probing terminated.

          StackTrace:
               at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
               at System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
               at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
               at System.Reflection.RuntimeAssembly.InternalLoadFrom(String assemblyFile, Evidence securityEvidence, Byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm, Boolean forIntrospection, Boolean suppressSecurityChecks, StackCrawlMark& stackMark)
               at System.Reflection.Assembly.LoadFrom(String assemblyFile)
          InnerException: 

シナリオ 4:

**Setup**
    Calling Assembly: GACed.
    Native Assembly: Build Action: None; Copy To Output Directory: Copy Always.

**Description** 
    Breakpoint at the point of native function call, use immediate window to execute the following code:

    var pat = pat = Path.Combine(AppDomain.CurrentDomain.RelativeSearchPath, "nativedll.dll");
    var a = Assembly.Load(pat);

**Result**
    Exception raised:

        System.IO.FileLoadException was unhandled
          HResult=-2146234297
          Message=Could not load file or assembly 'C:\\WebUI\\bin\\nativedll.dll' or one of its dependencies. The given assembly name or codebase was invalid. (Exception from HRESULT: 0x80131047)
          Source=mscorlib
          FileName=C:\\WebUI\\bin\\nativedll.dll
          FusionLog=""
          StackTrace:
               at System.Reflection.AssemblyName.nInit(RuntimeAssembly& assembly, Boolean forIntrospection, Boolean raiseResolveEvent)
               at System.Reflection.RuntimeAssembly.CreateAssemblyName(String assemblyString, Boolean forIntrospection, RuntimeAssembly& assemblyFromResolveEvent)
               at System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean forIntrospection)
               at System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
               at System.Reflection.Assembly.Load(String assemblyString)
          InnerException: 

シナリオ 5:

**Setup**
Calling Assembly: GACed.
Native Assembly: Build Action: None; Copy To Output Directory: Copy Always.

**Description: **
    Breakpoint at the point of native function call, use immediate window to execute the following code:

    var pat = pat = Path.Combine(AppDomain.CurrentDomain.RelativeSearchPath, "nativedll.dll");
    var a = Assembly.LoadFile(pat);

    **Result**
    Exception raised:

        System.BadImageFormatException was unhandled
          HResult=-2146234344
          Message=The module was expected to contain an assembly manifest. (Exception from HRESULT: 0x80131018)
          Source=mscorlib
          StackTrace:
               at System.Reflection.RuntimeAssembly.nLoadFile(String path, Evidence evidence)
               at System.Reflection.Assembly.LoadFile(String path)
          InnerException: 

シナリオ 6:

**Setup**
Calling Assembly: GACed.
Native Assembly: Excluded from project. Manually copied into the bin folder prior to execution.

**Description: **
    Logged into the site, home page open. Did not navigate to the page with native call.

    **Result**
    Binding Error: (Output: Assembly Binding Log Viewer)

        Assembly Binder Log Entry  (12/13/2012 @ 2:19:13 PM)

        The operation failed.
        Bind result: hr = 0x80131018. No description available.

        Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
        Running under executable  C:\Windows\SysWOW64\inetsrv\w3wp.exe
        --- A detailed error log follows. 

        === Pre-bind state information ===
        LOG: User = NT AUTHORITY\SYSTEM
        LOG: DisplayName = nativedll
         (Partial)
        WRN: Partial binding information was supplied for an assembly:
        WRN: Assembly Name: nativedll | Domain ID: 2
        WRN: A partial bind occurs when only part of the assembly display name is provided.
        WRN: This might result in the binder loading an incorrect assembly.
        WRN: It is recommended to provide a fully specified textual identity for the assembly,
        WRN: that consists of the simple name, version, culture, and public key token.
        WRN: See whitepaper http://go.microsoft.com/fwlink/?LinkId=109270 for more information and common solutions to this issue.
        LOG: Appbase = file:///C:/Web/WebUI/
        LOG: Initial PrivatePath = C:\WebUI\bin
        LOG: Dynamic Base = C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\webui\69d9ded4
        LOG: Cache Base = C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\webui\69d9ded4
        LOG: AppName = ca4be085
        Calling assembly : (Unknown).
        ===
        LOG: This bind starts in default load context.
        LOG: Using application configuration file: C:\WebUI\web.config
        LOG: Using host configuration file: C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet.config
        LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
        LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
        LOG: Attempting download of new URL file:///C:/Windows/Microsoft.NET/Framework/v4.0.30319/Temporary ASP.NET Files/webui/69d9ded4/ca4be085/nativedll.DLL.
        LOG: Attempting download of new URL file:///C:/Windows/Microsoft.NET/Framework/v4.0.30319/Temporary ASP.NET Files/webui/69d9ded4/ca4be085/nativedll/nativedll.DLL.
        LOG: Attempting download of new URL file:///C:/WebUI/bin/nativedll.DLL.
        LOG: Assembly download was successful. Attempting setup of file: C:\\WebUI\bin\nativedll.dll
        LOG: Entering download cache setup phase.
        ERR: Error extracting manifest import from file (hr = 0x80131018).
        ERR: Setup failed with hr = 0x80131018.
        ERR: Failed to complete setup of assembly (hr = 0x80131018). Probing terminated.

シナリオ 7:

**Setup**
Scenario 6 + Just copy the nativedll to C:\Windows folder. No reset of anytype. 

**Description**
Navigate to the page calling native.

Result: 
Success. Native Functionality is invoked. No binding failure.
4

1 に答える 1

4

私が解決できる限り、かなりの量の仮定で...

/bin フォルダー内の .NET アセンブリは、Web サイトの起動時に ASP.NET によって自動的に読み込まれますが、ネイティブの win32 DLL は読み込まれません。

DllImport は Web サイト プロジェクトに対してではなく、w3wp.exe プロセスに対して相対的に実行されるため、DLLImport は失敗します。AppPool は多くの Web サイト間で共有できるため、セキュリティ上の問題がないと仮定しても、Web サイトの /bin フォルダーを w3wp.exe プロセスの CurrentDirectory にすることはできません。

そのため、DLL を見つけるために、IIS は最初に「w3wp.exe」が配置されているフォルダーを検索し、次に Windows システム フォルダーをチェックします。

理論的には、LoadLibrary() と GetProcAddress() を使用して、特定のフォルダーから DLL をロードできるはずです。

ちなみに、Web サイト プロジェクト内で定義されたクラスで DllImport() を使用している場合は、ASP.NET の既定のコンパイル モードを「安全」に変更する必要がある場合があります。安全でないコードの使用を許可するには、web.config ファイルを更新します。

<system.codedom>
    <compilers>
       <compiler ... compilerOptions="/unsafe" >
    </compilers>
</system.codedom>
于 2013-05-23T16:56:05.803 に答える