Pergunta

Esta questão relaciona-se com um site ASP.NET, originalmente desenvolvido no VS 2005 e agora em VS 2008.

Este site usa dois DLLs externos não gerenciados que não .NET são e eu não tenho o código fonte para compilá-los e ter de usá-los como é.

Este site funciona muito bem de dentro do Visual Studio, localizar e acessar essas DLLs externas corretamente. No entanto, quando o site é publicado em um servidor web (runnning IIS6 e ASP.NET 2.0) em vez do PC desenvolvimento não pode localizar e acessar essas DLLs externas, e eu recebo o seguinte erro:

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

As DLLs externos estão localizados no diretório bin do site, juntamente com as DLLs gerenciadas que envolvê-los e todas as outras DLLs para o site.

Como pesquisar este problema revela que muitas outras pessoas parecem ter o mesmo problema ao acessar non.NET DLLs a partir de sites externos ASP.NET, mas eu não encontrei uma solução que funciona.

Eu tentei o seguinte:

  • Running DEPENDE para verificar as dependências para estabelecer que os três primeiros estão no diretório System32 no caminho, o último é no .NET 2 quadro.
  • Eu coloquei as duas DLLs e suas dependências em System32 e reiniciado o servidor, mas o site ainda não poderia carregar essas DLLs externas.
  • Deu plenos direitos para ASPNET, IIS_WPG e IUSR (para esse servidor) para o site diretório bin e reiniciado, mas o site ainda não podia carregar essas DLLs externas.
  • Adicionado as DLLs externas como itens existentes para os projetos e conjunto sua "Copy to Output" propriedade para "Copy Always", e website ainda não conseguiu encontrar as DLLs.
  • Também definir sua propriedade "Build Action" para "recurso incorporado" e website ainda não conseguiu encontrar as DLLs.

Qualquer ajuda com este problema seria muito apreciada!

Foi útil?

Solução

Tente colocar as DLLs no diretório \ System32 \ Inetsrv. Este é o diretório de trabalho para o IIS no Windows Server.

Se isso não funcionar, tente colocar as DLLs no diretório System32 e os arquivos de dependência no diretório Inetsrv.

Outras dicas

Isso acontece porque as DLLs geridos se sombra copiados para um local temporário no diretório .NET Framework. Consulte http://msdn.microsoft.com/en-us/library/ms366723. aspx para mais detalhes.

Infelizmente, as DLLs não gerenciados não obter copiado e o processo ASP.NET não será capaz de encontrá-los quando ele precisa carregá-los.

Uma solução fácil é colocar as DLLs não gerenciados em um diretório que está no caminho do sistema (tipo "caminho" na linha de comando para ver o caminho em sua máquina) para que eles possam ser encontrados pelo processo ASP.NET . O diretório System32 é sempre no caminho, assim, colocar as DLLs não gerenciados há sempre funciona, mas eu recomendaria adicionar alguma outra pasta para o caminho e, em seguida, adicionar as DLLs lá para evitar poluir o diretório System32. Uma grande desvantagem deste método é que você tem que renomear as DLLs não gerenciadas para cada versão do seu aplicativo e você pode rapidamente ter seu próprio inferno dll.

Como uma alternativa para colocar a dll em uma pasta que já está no caminho (como system32) você pode alterar o valor do caminho em seu processo usando o seguinte código

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

Então, quando LoadLibrary tenta encontrar a DLL não gerenciado que também irá searchPath digitalização. Isso pode ser preferível fazer uma bagunça em System32 ou outras pastas.

Somando-se a resposta de Matt, isso é o que finalmente funcionou para mim para servidor de 64 bits 2003 / IIS 6:

  1. Verifique se seu dlls / asp.net são a mesma versão (32/64 bit)
  2. Coloque as DLLs não gerenciados no dir inetsrv (note que em 64 bits do Windows, este é sob syswow64, embora o diretório sys32 / inetsrv é criado)
  3. Deixe as DLLs geridos em / bin
  4. Certifique-se de ambos os conjuntos de dll leram / executar permissões

Dê uma olhada com FileMon ou ProcMon e filtro sobre os nomes das DLLs problemáticas. Isto irá mostrar o que os diretórios são varridos em busca das DLLs, e quaisquer problemas de permissão que você pode ter.

Outra opção é incorporar a DLL nativa como um recurso na DLL gerenciado. Isso é mais complicado em ASP.NET, uma vez que requer a escrita para a pasta temporária em tempo de execução. A técnica é explicada em outra resposta SO .

verificar o caminho variável em suas configurações de ambiente também.

Executar depende XYZ.dll diretamente, no local que você tenha sido implantado. Se isso não revelar nada faltando, use a ferramenta fuslogvw na plataforma SDK a erros carregador traço. Além disso, os logs de eventos, por vezes, contêm informações sobre as falhas para DLLs de carga.

Eu vim através de uma mesma questão. E eu tentei todas as opções acima, copiar para system32, inetpub, a criação de ambiente do caminho, etc nada funcionou. Esta questão está resolvida, copiando dll não gerenciada para o diretório bin de aplicação web ou serviço web.

?fter lutando durante todo o dia sobre este problema e, finalmente, eu encontrei uma solução que se adapte-me. É apenas um teste, mas o método está funcionando.

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();
                  }
                }
          }
        }
    }
}

No Application_Start usar este: (Personalize / bin / x64 e bin / DLL / x64 pastas conforme necessário)

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);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top