如何在ASP.NET中使用原生dll?

时间:2012-01-07 08:55:08

标签: c# asp.net .net asp.net-mvc asp.net-mvc-3

问题:

我使用System.Data.OracleClient。

System.Data.OracleClient需要OracleInstantClient,它们是本机dll。 因此,为了使用System.Data.OracleClient,我需要安装本机dll,或者在路径环境变量中的文件夹中。

现在,基本问题是,我没有管理员权限(公司笔记本电脑 - 公司愚蠢 - 不会改变)...
所以我既不能安装任何东西,也不能复制PATH文件夹中的任何内容,也不能在路径环境变量中添加文件夹,也不能重新启动/管理IIS或任何其他服务......

因此,作为测试,我只是将oci.dll和oraociei11.dll复制到与WinForms .exe相同的文件夹中。
这很好。我能够毫无问题地访问Oracle数据库(SELECT * FROM COUNTRIES)。

但是现在,我需要在ASP.NET解决方案中执行相同的查询。 问题是,ASP.NET dll在执行时会将阴影复制到临时文件夹中。

现在让dll成为非常少的webapp bin,
在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 个答案:

答案 0 :(得分:3)

解决。
显然,在将它们复制到目标文件夹后仍然需要加载本机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


        // http://stackoverflow.com/questions/281145/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