问题:
我使用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 =
我尝试了几种可能性,但没有一种可行。
答案 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