在调试文件夹外运行时找不到 DLL
Posted
技术标签:
【中文标题】在调试文件夹外运行时找不到 DLL【英文标题】:DLL not found when running outside debug folder 【发布时间】:2016-03-10 11:58:26 【问题描述】:应用程序名称、路径和 url 已重命名为“MyApp”和“example”,以便于阅读。
您好,我目前为我的应用程序使用 1 个 dll 文件,即 c# 中的 log4net。现在我将我的 dll 包含在来自
的引用中C:\Users\ashle\AppData\Roaming\MyApp
仅仅是因为我将公开发布我的申请。现在它在调试模式之外和内部都可以正常工作,但是当我在 /bin/debug 文件夹之外运行 exe 时,它会引发错误..
未处理的异常:System.IO.FileNotFoundException:无法加载 文件或程序集'log4net,版本=1.2.15.0,文化=中性, PublicKeyToken=669e0ddf0bb1aa2a' 或其依赖项之一。这 系统找不到指定的文件。 在 MyApp.Program.Main(String[] args)
我也将这段代码放入了我认为可以阻止它发生的地方。但我做错了什么?这段代码应该涵盖我的**
if (!Directory.Exists(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "/MyApp"))
Console.WriteLine("Created directory: " + Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "/MyApp");
Directory.CreateDirectory(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "/MyApp");
if (!File.Exists(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "/MyApp/log4net.dll"))
Console.WriteLine("Please wait while we download some files...");
string downloadUrl = "http://example.com";
if (checkWebsiteAvalibility(downloadUrl))
WebClient webClient = new WebClient();
webClient.DownloadFileAsync(new Uri(downloadUrl + "/downloads/log4net.dll"),
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "/MyApp/log4net.dll");
Console.Clear();
但是在 /bin/debug 之外单独运行 exe 时,它甚至不会显示“请稍候,我们正在下载一些文件...”行
【问题讨论】:
发布.exe时,必须将所有相关的.dll文件也发布到同一目录中 我猜您甚至在到达打印出“请稍候,我们正在下载一些文件...”的行之前就使用了日志记录 【参考方案1】:在发布您的项目之前,请从您的参考中删除 dll 文件。通过添加引用添加相同的 dll。然后尝试发布它。
它对我有用。
【讨论】:
【参考方案2】:当我遇到这个问题时,我将 .dll 部署到了可执行文件的运行位置。将 dll 添加到项目 Resources 并将其 Build Action 设置为 Content。
class Program
//Programmatically, the Program() method is called prior to Main() and before any registrations are made.
//This is where we write the dll to the disk.
static Program()
//Path.GetDirectoryName() returns the folder path to a particular file.
//Assembly.GetExecutingAssembly().Location returns the path to the current running location of the compiled executable, with the name. E.G. C:\MyProject\MyProgram.exe
//We combine this with Path.GetDirectoryName to get the folder, and then write the dll into this folder. That way, when this method finishes and main is called, it will find the dll in the folder.
File.WriteAllBytes(string.Format("01", Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "\\log4net.dll"), FindResourceByName("log4net"));
/// <summary>
/// Returns a byte array of the object searched for
/// </summary>
/// <param name="objectName">Name of the resource object</param>
/// <returns>Byte array of the specified resource object</returns>
private static byte[] FindResourceByName(string objectName)
object obj = Properties.Resources.ResourceManager.GetObject(objectName);
return ((byte[])(obj));
//Rest of your code goes here...
在我的情况下,我的 DLL 被称为“Microsoft.Win32.TaskScheduler.dll”如果是这种情况,对于您的应用程序,当您的 DLL 作为资源添加时,句点将被替换为下划线。请确保在调用 FindResourceByName 时反映这一点,否则您的查找将失败:
File.WriteAllBytes(string.Format("01", Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "\\Microsoft.Win32.TaskScheduler.dll"), FindResourceByName("Microsoft_Win32_TaskScheduler"));
【讨论】:
以上是关于在调试文件夹外运行时找不到 DLL的主要内容,如果未能解决你的问题,请参考以下文章