2

Adding a reference to a DLL in VS is no problem at all. However adding a reference via this method required the DLL to be in a specific path at compile and run time.

Now here is my problem: The DLL I want to reference is not guaranteed to be in the same spot on different machines. The location of the DLL depends on the user installing the program the DLL opens an API for. i.e. On machine A, the DLL is located at C:\SomeLocation\api.dll and on machine B, the DLL is located at F:\ThisAwesomeProgram\api.dll.

Can I add a reference to the DLL in VS to use it like any other DLL I added a reference to, and then (at runtime) change the path of the DLL and still use it? Or do I need to use something like Assembly.LoadFrom, and then call the methods via reflection and dynamic invocation?

Here is the workflow I intended to use:

  • Add a reference to the DLL at compile time in Visual studio.
  • Use the DLL as if the path would never change.
  • Compile the program as usual.
  • Start the program and then change the DLL location to the actual location (if different from the location known at compile time).
  • Use the program parts the use the DLL as usual.
Wandering Fool
  • 2,170
  • 3
  • 18
  • 48
Ruhrpottpatriot
  • 1,058
  • 3
  • 17
  • 31
  • I don't think you even can reference a DLL from an arbitrary location just like that. Yes, you can reference it *at compilation time*, but at runtime it has to be in one of the designated DLL load directories (system directories, the program's home directory, etc). If you want to load something at a path you don't know until your program is running, you'll have to load it by hand. – Matti Virkkunen Aug 10 '15 at 13:34
  • Basically I want to reference the DLL at compilation time, since I have the DLL on my system too. Then I want to point my program at runtime to the actual location of the DLL. I changed my question to better explain my situation – Ruhrpottpatriot Aug 10 '15 at 13:40

5 Answers5

1

I have programmed something like this, too. I used an API which was in a dll delivered with another program of mine. But if the user changed the installpath I couldn't find the dll. I solved it with creating a registryentry where I stored the path during the installation of the first program and then referenced it in my code. I don't know if your problem is the same as mine, but if you can modify the installroutine you can try this.

innuendomaximus
  • 353
  • 2
  • 3
  • 17
0

You may be looking for the Global Assembly Cache (GAC) which is a way to share your dll between multiple applications.

Phil-R
  • 2,193
  • 18
  • 21
0

You can reference an assembly from anywhere you want. The project file will contain the "hintpath", or where the compiler should look it up. So compile-time you're fine.

At runtime though you still need to load the assembly. If "Copy Local" is set to false, the runtime can't find the assembly. You can, using Assembly.LoadFrom(@"full\path"), load an assembly from a path.

That is, if you know the full path. It looks like you're trying to talk to the API of a third-party application. Perhaps they store their installation directory in the registry, so you can probe for that.

Community
  • 1
  • 1
CodeCaster
  • 147,647
  • 23
  • 218
  • 272
  • The path to the DLL will be known at runtime, so that will be no problem. If I understood you correctly I would reference the DLL at compile time as usual and set the "Copy Local" to `false`, before the first usage of the DLLs components, I load the DLL via `Assembly.LoadFrom`. But how am I going to tell my program that this is the correct assembly to use? Sadly your link does not specify that. – Ruhrpottpatriot Aug 10 '15 at 13:56
  • @Ruhrpott I don't understand your question. What is "the correct assembly"? – CodeCaster Aug 10 '15 at 14:03
  • My bad. With "correct assembly" I mean the assembly containing the API I want to call and whose path can change at run time – Ruhrpottpatriot Aug 10 '15 at 14:55
  • You say you know the path to the assembly. Pass that to Assembly.LoadFrom. – CodeCaster Aug 10 '15 at 14:57
  • And that does suffice? I'm pretty new to this dynamic assembly loading, so anything helps. – Ruhrpottpatriot Aug 10 '15 at 15:19
0

You can subscribe on AssymblyResolve event:

AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;

And load it from file.

Backs
  • 24,430
  • 5
  • 58
  • 85
-1

This video on YouTube has it. What you need to do is take the dll file and embed it in your program. From there, you will be able to load it with the code underneath.

    [STAThread]
    static void Main()
    {

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(Program.CurrentDomain_AssemblyResolve);
        Application.Run(new Form1());
    }

    private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("EmbedAssembly.WhateverDll.dll"))
        {
            byte[] assemblyData = new byte[stream.Length];
            stream.Read(assemblyData, 0, assemblyData.Length);
            return Assembly.Load(assemblyData);
        }
    }
Wandering Fool
  • 2,170
  • 3
  • 18
  • 48
John Thompson
  • 386
  • 3
  • 10