Jak uzyskać lokalizację aktualnie wykonywanej biblioteki DLL?

94

Mam plik konfiguracyjny, który muszę załadować w ramach wykonywania biblioteki DLL, którą piszę.

Problem polega na tym, że miejsce, w którym umieściłem dll i plik konfiguracyjny, nie jest „bieżącą lokalizacją”, gdy aplikacja jest uruchomiona.

Na przykład umieściłem tutaj plik dll i xml:

D: \ Program Files \ Microsoft Team Foundation Server 2010 \ Application Tier \ Web Services \ bin \ Plugins

Ale jeśli spróbuję odwołać się do pliku xml (w mojej dll) w następujący sposób:

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

następnie . \ AggregatorItems.xml tłumaczy się na:

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

Muszę więc znaleźć sposób (mam nadzieję), aby dowiedzieć się, gdzie znajduje się aktualnie wykonywana biblioteka dll. Zasadniczo szukam tego:

XDocument doc = XDocument.Load(CoolDLLClass.CurrentDirectory+@"\AggregatorItems.xml")
Vaccano
źródło

Odpowiedzi:

140

Szukasz System.Reflection.Assembly.GetExecutingAssembly()

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

Uwaga:

.LocationWłaściwość zwraca lokalizację aktualnie uruchomionego pliku DLL.

W pewnych warunkach biblioteka DLL jest kopiowana w tle przed wykonaniem, a .Locationwłaściwość zwróci ścieżkę do kopii. Jeśli chcesz ścieżkę do oryginalnej biblioteki DLL, użyj Assembly.GetExecutingAssembly().CodeBasezamiast tego właściwości.

.CodeBasezawiera przedrostek ( file:\), który być może trzeba będzie usunąć.

Rozbite szkło
źródło
8
Niestety! To powracaC:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\Temporary ASP.NET Files\\tfs\\de3c0c8e\\c1bdf790\\assembly\\dl3\\20b156cb\\22331f24_bfb9cb01\\AggregatorItems.xml
Vaccano,
23
Ach! Ale Assembly.GetExecutingAssembly().CodeBasema to!
Vaccano
2
CodeBase dał mi plik: \\ c: \ myassemblypath, co jest dziwne
Matt
10
@Matt używa nowego Uri (Assembly.GetExecutingAssembly (). CodeBase) .LocalPath, aby uzyskać prawdziwe imię
Larry
2
string curAssemblyFolder = new System.Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase).LocalPath;
Martin Connell
37

Odbicie jest twoim przyjacielem, jak już wspomniano. Ale musisz użyć właściwej metody;

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.
Nicholas Carey
źródło
16

W moim przypadku (dotyczy moich zestawów załadowanych [jako plik] do Outlooka):

typeof(OneOfMyTypes).Assembly.CodeBase

Zwróć uwagę na użycie CodeBase(nie Location) w Assembly. Inni wskazywali alternatywne metody lokalizacji zestawu.


źródło
5
System.Reflection.Assembly.GetExecutingAssembly().Location
Hawxby
źródło
1

Jeśli pracujesz z aplikacją asp.net i chcesz zlokalizować zestawy podczas korzystania z debugera, zwykle są one umieszczane w jakimś katalogu tymczasowym. Napisałem tę metodę, aby pomóc w tym scenariuszu.

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;
}

Więcej szczegółów można znaleźć w tym poście na blogu http://nodogmablog.bryanhogan.net/2015/05/finding-the-location-of-a-running-assembly-in-net/

Jeśli nie możesz zmienić kodu źródłowego lub ponownie wdrożyć, ale możesz sprawdzić uruchomione procesy na komputerze, użyj Process Explorer. Szczegółowy opis napisałem tutaj .

Wyświetli listę wszystkich wykonujących się bibliotek dll w systemie, może być konieczne określenie identyfikatora procesu uruchomionej aplikacji, ale zwykle nie jest to zbyt trudne.

Napisałem pełny opis, jak to zrobić dla biblioteki DLL w usługach IIS - http://nodogmablog.bryanhogan.net/2016/09/locating-and-checking-an-executing-dll-on-a-running-web -serwer/

Bryan
źródło