Problemi con gli assembly di ASP.NET

di Cristian Civera, in .NET,

Può capitare di voler utilizzare le classi inerenti ad ASP.NET e che in generale fanno parte dell'assembly System.Web.dll anche in applicazioni console o winforms. Io volevo usare la classe System.Web.UI.LosFormatter (di cui parlo in questo articolo). Nell'istanziare la classe però, mi ritrovo con un TypeInitializationException e più dettagliatamente il CLR non trova la dll aspnet_isapi.dll.

Si tratta di una dll unmanaged che la classe usa con il metodo SafeNativeMethods.CurProcInitialize. Per utilizzare una dll esterna, il Framework mette a disposizione l'attributo DllImport per marcare la dichiarazione di un metodo. Per chi non lo conoscesse, c'è questa introduzione di MS.

Quest'attributo per caricare la dll unmanaged usa il metodo LoadLibrary (kernel32.dll, altra dll unmanaged). Questo permette di caricare una dll e restituisce un handle al modulo caricato. E' possibile indicare solo il nome del file o dare il percorso completo. La funzione utilizzata da LosFormatter indica solo il nome della dll, perciò la dll verrà cercata:

  • nella directory nella quale l'applicazione è stata avviata
  • la directory attuale
  • la directory c:\windows\system32
  • la directory c:\windows
  • le directory presenti nella variabile d'ambiente PATH

La dll aspnet_isapi.dll si trova nella directory del framework. Di conseguenza se non lanciamo il nostro exe da questa cartella non troverà mai la dll. LoadLibrary ha una caratteristica: una volta caricata la dll, ulteriori load verranno ignorati. Questo vuol dire che se noi carichiamo la dll (dandogli il percorso completo) prima che lo faccia LosFormatter aggireremo il problema. Guarda caso, HttpRuntime.Initialize (la classe HttpRuntime è il motore di ASP.NET) utilizza proprio questo metodo per caricare in fase di inizializzazione la dll aspnet_isapi.dll. Lo fa cercando la chiave di registro HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET\1.1.4322.0\Path per ottenere il path del Framework, o cercando la dll nella directory temporanea creata dallo shadow copy per contenere la copia degli assemblies.

Detto tutto questo casino alla quale ho perso parecchio tempo :-D, nella nostra applicazione faremo:

using System;
using System.IO;
using System.Web.UI;
using System.Runtime.InteropServices;

public class p
{

 [DllImport("Kernel32.dll")]
public extern static IntPtr LoadLibrary(string fileName);

 static void Main()
{
string s = System.Web.HttpRuntime.ClrInstallDirectory;
IntPtr h = LoadLibrary(Path.Combine(s, "aspnet_isapi.dll"));
if (h > IntPtr.Zero)
LosFormatter l = new LosFormatter();
}

}

Spero possa essere utile a qualcuno ;-)

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Nella stessa categoria
I più letti del mese