質問

この質問は、元はVS 2005で、現在はVS 2008で開発されたASP.NET Webサイトに関するものです。

このWebサイトは、.NETではない2つのアンマネージ外部DLLを使用しており、それらをコンパイルするソースコードがなく、そのまま使用する必要があります。

このWebサイトはVisual Studio内から正常に実行され、これらの外部DLLを正しく見つけてアクセスします。ただし、Webサイトが開発PCではなくWebサーバー(IIS6およびASP.NET 2.0を実行)で公開されると、これらの外部DLLを見つけてアクセスできず、次のエラーが表示されます。

Unable to load DLL 'XYZ.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)

外部DLLは、それらをラップするマネージDLLおよびWebサイトの他のすべてのDLLとともに、Webサイトのbinディレクトリにあります。

この問題を検索すると、他の多くの人がASP.NET Webサイトから外部の非.NET DLLにアクセスする際に同じ問題を抱えているように見えますが、有効なソリューションは見つかりませんでした。

次のことを試しました:

  • 依存関係をチェックしてDEPENDSを実行し、最初の3つが パスのSystem32ディレクトリにあり、最後は.NET 2にあります フレームワーク。
  • 2つのDLLとその依存関係を System32とサーバーを再起動しましたが、ウェブサイトはまだ これらの外部DLLをロードできませんでした。
  • ASPNET、IIS_WPG、およびIUSR(そのサーバーの)に対する完全な権利を Webサイトのbinディレクトリを再起動しましたが、Webサイトはまだできませんでした これらの外部DLLをロードします。
  • 外部DLLを既存のアイテムとしてプロジェクトに追加し、設定します <!> quot;出力にコピー<!> quot;プロパティを<!> quot; Copy Always <!> quot;およびwebsite それでもDLLが見つかりません。
  • また、<!> quot; Build Action <!> quot;を設定します。 <!> quot; Embedded resource <!> quot;のプロパティそして ウェブサイトはまだDLLを見つけることができません。

この問題に関する支援は大歓迎です!

役に立ちましたか?

解決

dllを\ System32 \ Inetsrvディレクトリに入れてみてください。これは、Windows Server上のIISの作業ディレクトリです。

これが機能しない場合は、dllをSystem32ディレクトリに、依存関係ファイルをInetsrvディレクトリに入れてみてください。

他のヒント

これは、マネージdllが.NET Frameworkディレクトリの下の一時的な場所にシャドウコピーされるために発生します。 http://msdn.microsoft.com/en-us/library/ms366723を参照してください。詳細については、aspx

残念ながら、アンマネージdllはコピーされず、ASP.NETプロセスはそれらをロードする必要があるときにそれらを見つけることができません。

簡単な解決策の1つは、管理されていないdllをシステムパス(<!> quot; path <!> quotと入力して、コマンドラインでマシンのパスを表示)に配置することです。 ASP.NETプロセスによって検出されます。 System32ディレクトリはパス内に常にあるので常にですので、そこにアンマネージdllを置くことは常に機能しますが、System32ディレクトリの汚染を防ぐために他のフォルダーをパスに追加し、そこにdllを追加することをお勧めします。この方法の大きな欠点の1つは、アプリケーションのすべてのバージョンのアンマネージdllの名前を変更する必要があることです。また、独自のdllヘルルをすばやく作成できます。

dllを既にパスにあるフォルダー(system32など)に配置する代わりに、次のコードを使用してプロセスのパス値を変更できます

System.Environment.SetEnvironmentVariable("Path", searchPath + ";" + oldPath)

次に、LoadLibraryがアンマネージDLLを見つけようとすると、searchPathもスキャンされます。これは、System32または他のフォルダーで混乱を起こすよりも望ましい場合があります。

Mattの答えに加えて、これが最終的に64ビットサーバー2003 / IIS 6で私にとってうまくいったことです:

  1. dll / asp.netが同じバージョン(32/64ビット)であることを確認してください
  2. 管理されていないdllをinetsrv dirに配置します(64ビットウィンドウでは、sys32 / inetsrvディレクトリが作成されているにもかかわらず、これはsyswow64の下にあることに注意してください)
  3. マネージDLLを/ binに残す
  4. dllの両方のセットに読み取り/実行権限があることを確認してください

FileMon または ProcMon を使用して、問題のあるDLLの名前をフィルタリングします。これにより、DLLの検索でスキャンされるディレクトリと、発生する可能性のあるアクセス許可の問題が表示されます。

別のオプションは、ネイティブDLLをマネージDLLのリソースとして埋め込みます。これは、実行時に一時フォルダーに書き込む必要があるため、ASP.NETではより複雑です。 この手法については、別のSOの回答で説明されています。

常に価値があるチェック環境設定のパス変数。

XYZ.dllを展開した場所で、直接DEPENDSを実行します。それでも見つからない場合は、プラットフォームSDKのfuslogvwツールを使用してローダーエラーをトレースします。また、イベントログにはDLLのロードの失敗に関する情報が含まれることがあります。

同じ問題に遭遇しました。そして、上記のすべてのオプションを試してみましたが、system32、inetpubへのコピー、パス環境の設定など何も機能しませんでした。 この問題は、アンマネージdllをWebアプリケーションまたはWebサービスのbinディレクトリにコピーすることで最終的に解決されます。

<!>#1040;この問題で終日苦労し、ようやく自分に合った解決策を見つけました。これは単なるテストですが、メソッドは機能しています。

namespace TestDetNet
{
    static class NativeMethods
    {
        [DllImport("kernel32.dll")]
        public static extern IntPtr LoadLibrary(string dllToLoad);

        [DllImport("kernel32.dll")]
        public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);


        [DllImport("kernel32.dll")]
        public static extern bool FreeLibrary(IntPtr hModule);
    }

    public partial class _Default : System.Web.UI.Page
    {
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        private delegate int GetRandom();

        protected System.Web.UI.WebControls.Label Label1;
        protected void Page_Load(object sender, EventArgs e)
        {
            Label1.Text = "Hell'ou";
            Label1.Font.Italic = true;
        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            if (File.Exists(System.Web.HttpContext.Current.Server.MapPath("html/bin")+"\\DelphiLibrary.dll")) {
                IntPtr pDll = NativeMethods.LoadLibrary(System.Web.HttpContext.Current.Server.MapPath("html/bin")+"\\DelphiLibrary.dll");
                if (pDll == IntPtr.Zero) { Label1.Text =  "pDll is zero"; }
                else
                {
                  IntPtr pAddressOfFunctionToCall = NativeMethods.GetProcAddress(pDll, "GetRandom");
                  if (pAddressOfFunctionToCall == IntPtr.Zero) { Label1.Text += "IntPtr is zero";   }
                  else
                  {
                    GetRandom _getRandom = (GetRandom)Marshal.GetDelegateForFunctionPointer(pAddressOfFunctionToCall,typeof(GetRandom));

                    int theResult = _getRandom();

                    bool result = NativeMethods.FreeLibrary(pDll);
                    Label1.Text = theResult.ToString();
                  }
                }
          }
        }
    }
}

Application_startでこれを使用します。 (必要に応じて/ bin / x64およびbin / dll / x64フォルダーをカスタマイズします)

String _path = String.Concat(System.Environment.GetEnvironmentVariable("PATH")
                ,";"
                , System.Web.Hosting.HostingEnvironment.MapPath("~/bin/x64")
                ,";"
                , System.Web.Hosting.HostingEnvironment.MapPath("~/bin/dll/x64")
                ,";"
                );
            System.Environment.SetEnvironmentVariable("PATH", _path, EnvironmentVariableTarget.Process);
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top