문제

이 질문은 원래 vs 2005와 현재 vs 2008에서 개발 된 ASP.NET 웹 사이트와 관련이 있습니다.

이 웹 사이트는 .NET가 아닌 두 개의 관리되지 않은 외부 DLL을 사용하며 소스 코드가없고 컴파일을 사용해야합니다.

이 웹 사이트는 Visual Studio 내에서 잘 작동하여 이러한 외부 DLL을 올바르게 찾아서 액세스합니다. 그러나 웹 사이트가 개발 PC가 아닌 웹 서버 (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을 감싸는 관리 DLL과 함께 있습니다.

이 문제를 검색하면 다른 많은 사람들이 ASP.NET 웹 사이트에서 외부 Non.net DLL에 액세스하는 것과 동일한 문제가있는 것처럼 보이지만 작동하는 솔루션을 찾지 못했습니다.

다음을 시도했습니다.

  • 실행은 종속성을 확인하여 처음 세 가지가 경로의 System32 디렉토리에 있고 마지막 32 개가 .NET 2 프레임 워크에 있는지 확인합니다.
  • 두 개의 DLL과 그 종속성을 System32에 넣고 서버를 재부팅했지만 웹 사이트는 여전히 이러한 외부 DLL을로드 할 수 없었습니다.
  • ASPNET, IIS_WPG 및 IUSR (해당 서버의 경우)에 웹 사이트 빈 디렉토리에 대한 모든 권한을 부여하고 웹 사이트는 여전히 이러한 외부 DLL을로드 할 수 없었습니다.
  • 외부 DLL을 프로젝트에 기존 항목으로 추가하고 "복사 출력"속성을 "복사"로 설정했으며 웹 사이트는 여전히 DLL을 찾을 수 없습니다.
  • 또한 "빌드 액션"속성을 "임베디드 리소스"로 설정하고 웹 사이트는 여전히 DLL을 찾을 수 없습니다.

이 문제에 대한 도움은 크게 감사하겠습니다!

도움이 되었습니까?

해결책

dlls를 system32 inetsrv 디렉토리에 넣으십시오. Windows Server의 IIS 용 작업 디렉토리입니다.

이것이 작동하지 않으면 System32 디렉토리에 dlls를 넣고 InetSrv 디렉토리에 종속성 파일을 넣으십시오.

다른 팁

관리되는 DLL이 그림자가 .NET Framework 디렉토리의 임시 위치로 그림자를 복사하기 때문에 발생합니다. 보다 http://msdn.microsoft.com/en-us/library/ms366723.aspx 자세한 내용은.

불행히도, 관리되지 않는 DLL은 복사되지 않으며 ASP.NET 프로세스는로드해야 할 때 찾을 수 없습니다.

쉬운 솔루션 중 하나는 관리되지 않은 DLL을 시스템 경로에있는 디렉토리에 넣는 것입니다 (컴퓨터의 경로를보기 위해 명령 줄에서 "경로"를 입력) ASP.NET 프로세스에서 찾을 수 있도록하는 것입니다. System32 디렉토리는입니다 언제나 경로에서 관리되지 않는 DLL을 넣는 것은 항상 작동하지만 경로에 다른 폴더를 추가 한 다음 System32 디렉토리 오염을 방지하기 위해 DLL을 추가하는 것이 좋습니다. 이 방법의 큰 단점 중 하나는 응용 프로그램의 모든 버전에 대해 관리되지 않은 DLL의 이름을 바꿔야하며 자신의 DLL 지옥을 신속하게 가질 수 있다는 것입니다.

DLL을 이미 경로에있는 폴더에 넣는 대안으로 (System32와 같은) 다음 코드를 사용하여 프로세스의 경로 값을 변경할 수 있습니다.

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

그런 다음 LoadLibrary가 관리되지 않는 DLL을 찾으려고 시도하면 SearchPath도 스캔합니다. 이것은 System32 또는 다른 폴더에서 엉망이 될 수 있습니다.

Matt의 답변에 추가하여 이것은 마침내 64 비트 서버 2003 / IIS 6에서 나에게 효과가있었습니다.

  1. DLLS / ASP.NET이 동일한 버전인지 확인하십시오 (32 / 64 비트)
  2. 관리되지 않은 DLL을 inetsrv dir에 넣습니다 (64 비트 Windows에서는 Sys32/inetsrv 디렉토리가 생성 되더라도 Syswow64에 있습니다).
  3. 관리되는 DLL을 /빈에 두십시오
  4. DLL 세트 모두 읽기/실행 권한이 있는지 확인하십시오.

살펴보세요 필라몬 또는 Procmon 번거로운 DLL의 이름을 필터링합니다. 이것은 DLL을 검색 할 때 어떤 디렉토리가 스캔되는지, 그리고 당신이 가질 수있는 모든 권한 문제를 보여줍니다.

또 다른 옵션은 기본 DLL을 관리되는 DLL의 리소스로 포함시키는 것입니다. 이는 런타임에 임시 폴더에 쓰기가 필요하기 때문에 ASP.NET에서 더 복잡합니다. 이 기술은 또 다른 답변으로 설명됩니다.

항상 가치가 있습니다 경로 확인 환경 설정에서도 변수.

런은 배치 한 위치에서 xyz.dll에 직접 의존합니다. 누락 된 내용이 밝혀지지 않으면 플랫폼 SDK의 FuslogVW 도구를 사용하여 로더 오류를 추적하십시오. 또한 이벤트 로그에는 때때로 DLL로드 실패에 대한 정보가 포함되어 있습니다.

나는 같은 문제를 발견했다. 또한 System32, Inetpub, 경로 환경 설정 등에 복사하는 위의 모든 옵션을 시도했습니다. 이 문제는 마침내 관리되지 않은 DLL을 웹 응용 프로그램 또는 웹 서비스의 빈 디렉토리에 복사하여 해결됩니다.

이 문제에 대해 하루 종일 어려움을 겪고 마침내 나에게 적합한 해결책을 찾았습니다. 단지 테스트 일뿐 만 아니라 방법이 작동합니다.

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에서 this : (필요에 따라 사용자 정의/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