Как узнать местонахождение исполняемой библиотеки DLL?

94

У меня есть файл конфигурации, который мне нужно загрузить как часть выполнения библиотеки DLL, которую я пишу.

Проблема, с которой я столкнулся, заключается в том, что место, куда я помещаю dll и файл конфигурации, не является «текущим местоположением», когда приложение работает.

Например, я поместил сюда файлы dll и xml:

D: \ Program Files \ Microsoft Team Foundation Server 2010 \ Уровень приложений \ Веб-службы \ bin \ Plugins

Но если я попытаюсь сослаться на файл xml (в моей dll) следующим образом:

XDocument doc = XDocument.Load(@".\AggregatorItems.xml")

тогда . \ AggregatorItems.xml преобразуется в:

C: \ windows \ system32 \ inetsrv \ AggregatorItems.xml

Итак, мне нужно найти способ (я надеюсь) узнать, где находится DLL, которая выполняется в данный момент. В основном я ищу это:

XDocument doc = XDocument.Load(CoolDLLClass.CurrentDirectory+@"\AggregatorItems.xml")
Vaccano
источник

Ответы:

140

Ты ищешь System.Reflection.Assembly.GetExecutingAssembly()

string assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string xmlFileName = Path.Combine(assemblyFolder,"AggregatorItems.xml");

Заметка:

.LocationСвойство возвращает расположение запущенного файла DLL.

При некоторых условиях перед выполнением DLL копируется в теневое копирование, и .Locationсвойство возвращает путь к копии. Если вам нужен путь к исходной DLL, используйте Assembly.GetExecutingAssembly().CodeBaseвместо этого свойство.

.CodeBaseсодержит префикс ( file:\), который вам может потребоваться удалить.

Разбитое стекло
источник
8
Увы! Это возвращаетсяC:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\Temporary ASP.NET Files\\tfs\\de3c0c8e\\c1bdf790\\assembly\\dl3\\20b156cb\\22331f24_bfb9cb01\\AggregatorItems.xml
Vaccano
23
Ах! Но Assembly.GetExecutingAssembly().CodeBaseесть!
Vaccano
2
CodeBase предоставила мне файл: \\ c: \ myassemblypath, что странно
Мэтт
10
@Matt использует новый Uri (Assembly.GetExecutingAssembly (). CodeBase) .LocalPath, чтобы получить настоящее имя
Ларри
2
string curAssemblyFolder = new System.Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase).LocalPath;
Мартин Коннелл
37

Как уже отмечалось, отражение - ваш друг. Но вам нужно использовать правильный метод;

Assembly.GetEntryAssembly()     //gives you the entrypoint assembly for the process.
Assembly.GetCallingAssembly()   // gives you the assembly from which the current method was called.
Assembly.GetExecutingAssembly() // gives you the assembly in which the currently executing code is defined
Assembly.GetAssembly( Type t )  // gives you the assembly in which the specified type is defined.
Николас Кэри
источник
16

В моем случае (при работе с моими сборками, загруженными [как файл] в Outlook):

typeof(OneOfMyTypes).Assembly.CodeBase

Обратите внимание на использование CodeBase(не Location) в Assembly. Другие указали на альтернативные методы размещения сборки.


источник
5
System.Reflection.Assembly.GetExecutingAssembly().Location
Hawxby
источник
1

Если вы работаете с приложением asp.net и хотите найти сборки при использовании отладчика, они обычно помещаются в какой-то временный каталог. Я написал этот метод, чтобы помочь в этом сценарии.

private string[] GetAssembly(string[] assemblyNames)
{
    string [] locations = new string[assemblyNames.Length];


    for (int loop = 0; loop <= assemblyNames.Length - 1; loop++)       
    {
         locations[loop] = AppDomain.CurrentDomain.GetAssemblies().Where(a => !a.IsDynamic && a.ManifestModule.Name == assemblyNames[loop]).Select(a => a.Location).FirstOrDefault();
    }
    return locations;
}

Дополнительные сведения см. В этом сообщении в блоге http://nodogmablog.bryanhogan.net/2015/05/finding-the-location-of-a-running-assembly-in-net/

Если вы не можете изменить исходный код или выполнить повторное развертывание, но можете проверить запущенные процессы на компьютере, используйте Process Explorer. Я написал подробное описание здесь .

В нем будут перечислены все исполняемые библиотеки DLL в системе, вам может потребоваться определить идентификатор процесса вашего запущенного приложения, но обычно это не слишком сложно.

Я написал полное описание того, как это сделать для dll внутри IIS - http://nodogmablog.bryanhogan.net/2016/09/locating-and-checking-an-executing-dll-on-a-running-web -сервер /

Брайан
источник