MVC4应用程序“无法加载DLL'libmp3lame.32.dll'”

7

我正在尝试在MVC4应用程序中使用NAudio.Lame库,但是遇到了以下错误:

Unable to load DLL 'libmp3lame.32.dll': The specified module could not be found.

我通过NuGet添加了这个库。我能够在Windows Forms应用程序中成功地使用这个库,所以我认为问题是特定于MVC4的。

我尝试了库作者在这里给出的建议: https://dev59.com/GnnZa4cB1Zd3GeqPoUxD#20065606


啊,你来了 :) 答案马上就来... - Corey
4个回答

16
问题是本地的DLL文件(libmp3lame.32.dlllibmp3lame.64.dll)无法找到,因为Web服务器进程执行的当前目录不是网站的bin文件夹(DLL文件所在的位置),并且搜索路径不包括bin文件夹。
你需要做的是将bin文件夹添加到PATH环境变量中,这将使LoadLibrary API调用能够定位到DLL文件。
以下是一个可供调用的方法,可以为您完成此操作:
public static void CheckAddBinPath()
{
    // find path to 'bin' folder
    var binPath = Path.Combine(new string[] { AppDomain.CurrentDomain.BaseDirectory, "bin" });
    // get current search path from environment
    var path = Environment.GetEnvironmentVariable("PATH") ?? "";

    // add 'bin' folder to search path if not already present
    if (!path.Split(Path.PathSeparator).Contains(binPath, StringComparer.CurrentCultureIgnoreCase))
    {
        path = string.Join(Path.PathSeparator.ToString(), new string[] { path, binPath });
        Environment.SetEnvironmentVariable("PATH", path);
    }
}

在创建LameMP3FileWriter实例之前,在您的控制器中调用此函数。如果将其放在Global.asax.cs中并从Application_Start()中调用,则可能有效。尝试一下,然后告诉我那里是否有效。

我已经在项目网站这里放了一个维基文章。


2
当您在mediumTrust中运行应用程序时,此操作会导致SecurityException失败。是否有更好的方法? - MorioBoncz
@llapinski,我没有处理过中等信任执行,所以不确定它会产生什么影响。上面的代码在哪里出现了问题?您能否编辑PATH环境变量或将相关本机DLL复制到PATH的某个位置? - Corey
1
如果您无法读取路径,系统会抛出SecurityException异常,并显示“请求类型为'System.Security.Permissions.EnvironmentPermission, mscorlib, Version=4.0.0.0'的权限。我还不确定客户端是否能够在其托管上编辑路径。是否有解决方法?手动将bin位置添加到路径中?IIS是否不会将其复制到某个临时位置? - MorioBoncz
@llapinski 是的,您可以手动编辑路径以添加项目的bin文件夹,或将本地DLL移动到路径上的文件夹中。 任何一种方法都应该有效。不幸的是,您无法像使用.NET程序集那样从内存加载它们。 - Corey
这对我的Azure部署有所帮助。 - Auri Rahimzadeh

2

将以下一行添加到您网站的web.config文件中。这将防止IIS从临时文件夹复制文件并执行您的站点(显然,本地dll不会被复制)。缺点是每次将更改推送到bin文件夹时,您都必须重新启动应用程序池,因为IIS将锁定那里的文件。

<system.web>
    <hostingEnvironment shadowCopyBinAssemblies="false" />
    ...
</system.web>

给这个答案点赞,但它也有自己的问题。如果禁用阴影副本,VS将锁定那些dll文件,构建项目将会很麻烦,因为它不会获取锁定,而是在构建时会出现访问被拒绝的异常。 - yakya

1

0

我通过将LameDLLWrap程序集作为独立程序集而不是嵌入到主要程序集中来使其工作。由于我知道我的目标系统是32位的,我可以承受只有一个程序集--这对我来说比在主机商的机器上玩弄路径更简单。

以下是我所做的:

  1. 克隆源代码
  2. 检出Experimental分支
  3. 从主项目中删除嵌入的程序集
  4. 将引用设置为Copy Local
  5. 重新编译所有内容

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接