4

Say I have an app: C:\MyPrograms\App.exe

This app does NOT reference library.dll. App.exe can dynamically load assemblies.

And let's say that the path to the DLL is C:\MyPrograms\DLLs\library.dll

I can get the path of the executing assembly (App.exe), no matter what I've tried.

GetExecutingAssembly()

GetEntryAssembly()

AppDomain.CurrentDomain.BaseDirectory

Is there a way to get the location of a DLL that is dynamically loaded? Everything just returns, for the example, the location of App.exe

EDIT 1: Rephrasing OP...

MyApp.exe can call any DLL, via passing in the path to the DLL. This DLL can be anywhere a user drops it. Ruling out hard-coding paths or something like that.

What I would like to do is to be able to get the current location of the dynamically loaded DLL. i.e. To handle errors, I'd like to be able to write an error log to the same directory the DLL is in.

I've found and tried a handful of ways to get where the loaded DLL lives, however this either returns the directory of the CALLING assembly (MyApp.exe) or nothing at all.

Vasyl Zvarydchuk
  • 3,789
  • 26
  • 37
  • can get or cannnot get the path?? – Muhammad Saqlain Jan 19 '17 at 18:41
  • Sounds like you want to handle the [`AssemblyResolve`](https://msdn.microsoft.com/en-us/library/system.appdomain.assemblyresolve(v=vs.110).aspx) event... – Heretic Monkey Jan 19 '17 at 19:09
  • Lets say you are logging errors, how are you detecting which dll a error originated from? Can you write a code example of how it would work in your question, for the line where you would need the path just put a `var path = MagicFunctionThatGetsPath(sourceDll)`, I want to know how you are figuring out `sourceDll` and what the type of that object would be. – Scott Chamberlain Jan 19 '17 at 21:54
  • Inside the DLL that is called is where I'd handle errors. From the Calling application, there is a feature that lets a user put a path to an assembly. Wherever you've placed it. Then, sometime later, this calling application takes the path you entered and tries to load the DLL. Once the DLL is loaded up, I just want to be able to detect the directory it is in...because like I mentioned, it can be placed anywhere and I'm looking for a "self-aware" kind of functionality in terms of it's location. – CleverNameHere Jan 19 '17 at 21:59
  • I don't have the source code of the app that actually DOES the calling. – CleverNameHere Jan 19 '17 at 22:00

2 Answers2

4

System.Reflection.Assembly class has property Location which gets path or UNC location of the loaded file that contains the manifest. So, if for instance you load assembly in this way

var assembly = System.Reflection.Assembly.Load(@"<assembly name>");

assembly.Location will return what you ask.

Answer to Edit 1: In order to do this

to handle errors, I'd like to be able to write an error log to the same directory the DLL is in

you can

  1. Load an assembly to app domain and subscribe to AppDomain.UnhandledException where you can put error logging code. This code will know the current domain and its base directory.
  2. Pass some kind of context within assembly path while calling assembly methods and use it in logging logic. It can be thread context if you call assembly methods only in one thread.
Community
  • 1
  • 1
Vasyl Zvarydchuk
  • 3,789
  • 26
  • 37
  • The path the the DLL is unknown (naturally I know where I'm PUTTING it). However the calling application is designed to accept the path to a DLL, the user can put the DLL anywhere. I do not have the source for the calling app either. assembly.Location returns nothing when I try to use it within the DLL that will be dynamically called – CleverNameHere Jan 19 '17 at 21:23
  • In question we have "can dynamically load assemblies". There are a few ways how to do this https://msdn.microsoft.com/en-us/library/25y1ya39(v=vs.110).aspx. But anyway app should have reference to loaded assembly instance. Or maybe "can dynamically load assemblies" means something else? – Vasyl Zvarydchuk Jan 19 '17 at 21:31
  • The calling app does have some kind of reference. The issue is that no matter what I've tried so far, I can only get the directory of the calling app. I would like to find a way to, from within the dynamically loaded DLL, get the directory that it is currently in so I can do things like write a log to the same place or look for config files. No matter where the DLL would be placed in Windows, I'm looking for a way to get it's current location. Like when it's loaded up, store the current directory in a string or something. – CleverNameHere Jan 19 '17 at 21:38
  • Add to the question part of your code which loads assemblies in order to understand your situation more clear – Vasyl Zvarydchuk Jan 19 '17 at 21:41
  • I've rephrased my question a little - however I do not have the source code of the app that CALLS these DLLs. If that's what you were asking. – CleverNameHere Jan 19 '17 at 21:50
  • Oh, it changes the matter. Of course you can not get location of assembly. I will correct my answer too. – Vasyl Zvarydchuk Jan 19 '17 at 21:56
0

If you are inside the dynamically loaded assembly itself where you have defined a class called MyDynLoadObject you can do this:

Assembly assem = Assembly.GetAssembly(typeof(MyDynLoadObject));

Edit: Another way to go:

public class MyDynLoadObject
{
    public MyDynLoadObject()
    {

      Assembly assem = this.GetType().Assembly;

    }
}