Как использовать нативные библиотеки DLL в ASP.NET? - PullRequest
2 голосов
/ 07 января 2012

Вопрос:

Я использую System.Data.OracleClient.

System.Data.OracleClient требует OracleInstantClient, которые являются родными DLL. Поэтому, чтобы использовать System.Data.OracleClient, мне нужно установить нативный dll или в папку в переменной окружения path.

Теперь основная проблема в том, что у меня нет прав администратора (корпоративный ноутбук - корпоративная глупость - не изменится) ...
Поэтому я ничего не могу ни установить, ни скопировать в папку в PATH, ни добавить папку в переменную окружения path, ни перезапустить / администрировать IIS или любую другую службу ...

Итак, в качестве теста я просто скопировал oci.dll и oraociei11.dll в ту же папку, что и WinForms .exe.
Это работало нормально. Мне удалось без проблем получить доступ к базе данных Oracle (SELECT * FROM COUNTRIES).

Но теперь мне нужно выполнить тот же запрос в решении ASP.NET. Проблема заключается в том, что при выполнении ASP.NET библиотеки dll копируются во временную папку.

Теперь, чтобы получить DLL в корзину для веб-приложений,
в Global.asax в

public class MvcApplication : System.Web.HttpApplication

Я переписал Init с этим:

public override void Init()
{
    int iBitNess = IntPtr.Size;
    //System.Windows.Forms.MessageBox.Show(iBitNess.ToString());
    // iBitNess = 4, so 32 bit dll's are right



    string strTargetDirectory = System.Reflection.Assembly.GetExecutingAssembly().Location;
    strTargetDirectory = typeof(DB.Abstraction.cDAL).Assembly.Location;
    strTargetDirectory = typeof(MvcApplication).Assembly.Location;
    strTargetDirectory = System.IO.Path.GetDirectoryName(strTargetDirectory);

    string strSourcePath = Server.MapPath("~/bin/dependencies/InstantClient");
    string[] astrAllFiles = System.IO.Directory.GetFiles(strSourcePath, "*.dll");

    foreach (string strSourceFile in astrAllFiles)
    {
        string strTargetFile = System.IO.Path.GetFileName(strSourceFile);
        strTargetFile = System.IO.Path.Combine(strTargetDirectory, strTargetFile);
        System.IO.File.Copy(strSourceFile, strTargetFile);
    }

    base.Init();
} // End Sub Init

для того, чтобы скопировать нативные DLL в предположительно правильное местоположение. Но я все еще получаю DllNotFound Exception ...

Где или как мне поставить собственную dll в приложении ASP.NET?

Я снова говорю: я не могу установить переменные окружения и не могу скопировать dll-файлы в папку, которая находится в пути. (которая обычно решает проблему).

Как вы видите с множественными вхождениями

strTargetDirectory =

Я пробовал несколько вариантов, ни один из которых не работал.

1 Ответ

3 голосов
/ 07 января 2012

решаемая.Очевидно, все еще нужно загрузить собственные библиотеки DLL после копирования их в целевую папку.OnInit был неверным, он для модулей HTTP.Нам нужно сделать это только один раз, поэтому мы переместились в Application_Start.

Вот мой код, на случай, если он кому-нибудь понадобится:

   // Hinweis: Anweisungen zum Aktivieren des klassischen Modus von IIS6 oder IIS7 
    // finden Sie unter "http://go.microsoft.com/?LinkId=9394801".
    public class MvcApplication : System.Web.HttpApplication
    {

        [System.Runtime.InteropServices.DllImport("kernel32", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
        static extern IntPtr LoadLibrary(string lpFileName);

        [System.Runtime.InteropServices.DllImport("kernel32", CharSet = System.Runtime.InteropServices.CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
        static extern UIntPtr GetProcAddress(IntPtr hModule, string procName);

        [System.Runtime.InteropServices.DllImport("kernel32", SetLastError = true)]
        [return: System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.Bool)]
        static extern bool FreeLibrary(IntPtr hModule);


        // See http://mpi4py.googlecode.com/svn/trunk/src/dynload.h
        const int RTLD_LAZY = 1; // for dlopen's flags
        const int RTLD_NOW = 2; // for dlopen's flags

        [System.Runtime.InteropServices.DllImport("libdl")]
        static extern IntPtr dlopen(string filename, int flags);

        [System.Runtime.InteropServices.DllImport("libdl")]
        static extern IntPtr dlsym(IntPtr handle, string symbol);

        [System.Runtime.InteropServices.DllImport("libdl")]
        static extern int dlclose(IntPtr handle);

        [System.Runtime.InteropServices.DllImport("libdl")]
        static extern string dlerror();


        public void LoadSharedObject(string strFileName)
        {
            IntPtr hSO = IntPtr.Zero;

            try
            {

                if (Environment.OSVersion.Platform == PlatformID.Unix)
                {
                    hSO = dlopen(strFileName, RTLD_NOW);
                }
                else
                {
                    hSO = LoadLibrary(strFileName);

                } // End if (Environment.OSVersion.Platform == PlatformID.Unix)

            } // End Try
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
            } // End Catch

            if (hSO == IntPtr.Zero)
            {
                throw new ApplicationException("Cannot open " + strFileName);
            } // End if (hExe == IntPtr.Zero)

        } // End Sub LoadSharedObject


        // /158839/asp-net-hostingenvironment-shadowcopybinassemblies
        public void EnsureOracleDllsLoaded()
        {
            int iBitNess = IntPtr.Size * 8;

            string strTargetDirectory = System.Reflection.Assembly.GetExecutingAssembly().Location;
            strTargetDirectory = System.IO.Path.GetDirectoryName(strTargetDirectory);

            string strSourcePath = "~/bin/dependencies/InstantClient/";

            if (Environment.OSVersion.Platform == PlatformID.Unix)
            {
                strSourcePath += "Linux" + iBitNess.ToString();
            }
            else
            {
                strSourcePath += "Win" + iBitNess.ToString();
            }

            strSourcePath = Server.MapPath(strSourcePath);

            string[] astrAllFiles = System.IO.Directory.GetFiles(strSourcePath, "*.dll");


            foreach (string strSourceFile in astrAllFiles)
            {
                string strTargetFile = System.IO.Path.GetFileName(strSourceFile);
                strTargetFile = System.IO.Path.Combine(strTargetDirectory, strTargetFile);
                System.IO.File.Copy(strSourceFile, strTargetFile, true);

                //if(strTargetFile.EndsWith("orannzsbb11.dll", StringComparison.OrdinalIgnoreCase))
                if (System.Text.RegularExpressions.Regex.IsMatch(strTargetFile, @"^(.*" + RegexDirSeparator + @")?orannzsbb11\.(dll|so|dylib)$", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                    continue; // Unneeded exception thrower

                try
                {
                    LoadSharedObject(strTargetFile);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }

            } // Next strSourceFile

        } // End Sub EnsureOracleDllsLoaded


        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
        } // End Sub RegisterGlobalFilters


        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                "Default", // Routenname
                "{controller}/{action}/{id}", // URL mit Parametern
                //new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameterstandardwerte
                new { controller = "Home", action = "Test", id = UrlParameter.Optional } // Parameterstandardwerte
            );

        } // End Sub RegisterRoutes


        protected void Application_Start()
        {
            EnsureOracleDllsLoaded();
            AreaRegistration.RegisterAllAreas();

            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);
        } // End Sub Application_Start


    } // End Class MvcApplication : System.Web.HttpApplication
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...