简体   繁体   中英

DLL not found when running outside debug folder

Application names, paths and urls have been renamed to 'MyApp' and 'example' just for easier reading.

Hello, I currently use 1 dll file for my application and that is log4net in c#. Now I include my dll in references from

C:\Users\ashle\AppData\Roaming\MyApp

Simply because I will be publicly releasing my application. Now it works fine outside debug mode and inside, but when I run the exe outside the /bin/debug folder it throws an error..

Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'log4net, Version=1.2.15.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a' or one of its dependencies. The system cannot find the file specified. at MyApp.Program.Main(String[] args)

I have also put this code in which I thought would stop it happening.. but what am I doing wrong? this code should cover my a**

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();

But when running the exe solo outside /bin/debug it doesn't even display the "Please wait while we download some files..." line

Before publishing your project, delete the dll file from your reference. Add the same dll through Add Reference. Then try to publish it.

It worked for me.

When I ran into this issue, I deployed the .dll to the running location of the executable. Add the dll to the project Resources and set its Build Action to 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("{0}{1}", 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...
}

In my situation, my DLL was called "Microsoft.Win32.TaskScheduler.dll" If this is the case, with your application, the periods will be replaced with an underscore when your DLL is added as a resource. Make sure that you reflect this when calling FindResourceByName or your lookup will fail:

File.WriteAllBytes(string.Format("{0}{1}", Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "\\Microsoft.Win32.TaskScheduler.dll"), FindResourceByName("Microsoft_Win32_TaskScheduler"));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM