Jak uzyskać ścieżkę złożeń, w którym znajduje się kod?

Czy istnieje sposób na uzyskanie ścieżki dla złożenia, w którym znajduje się bieżący kod? Nie chcę, aby ścieżka wywołującego assembly, tylko ta, która zawiera kod.

Zasadniczo mój test jednostkowy musi odczytać niektóre pliki testowe XML, które znajdują się w stosunku do dll. Chcę, aby ścieżka zawsze rozwiązywała się poprawnie niezależnie od tego, czy testowa biblioteka dll jest uruchamiana z TestDriven.NET, MBUNIT GUI czy coś innego.

Edit : ludzie chyba nie rozumieją co Pytam.

Moja biblioteka testów znajduje się w say

C:\projects\myapplication\daotests\bin\Debug\daotests.dll

I chciałbym dostać tę ścieżkę:

C:\projects\myapplication\daotests\bin\Debug\

Trzy sugestie do tej pory mnie zawodzą, gdy uruchamiam z Gui MbUnit:

  • Environment.CurrentDirectory daje c:\Program Files\MbUnit

  • System.Reflection.Assembly.GetAssembly(typeof(DaoTests)).Location daje C:\Documents oraz Ustawienia\george\Local Ustawienia\Temp\ ....\ DaoTests.dll

  • System.Reflection.Assembly.GetExecutingAssembly().Location daje to samo co poprzednie.

Author: bluish, 2008-09-10

26 answers

Zdefiniowałem następującą właściwość, ponieważ używamy jej często w testach jednostkowych.

public static string AssemblyDirectory
{
    get
    {
        string codeBase = Assembly.GetExecutingAssembly().CodeBase;
        UriBuilder uri = new UriBuilder(codeBase);
        string path = Uri.UnescapeDataString(uri.Path);
        return Path.GetDirectoryName(path);
    }
}

Właściwość Assembly.Location czasami daje zabawne wyniki Podczas używania NUnit( gdzie zespoły uruchamiane są z folderu tymczasowego), więc wolę użyć CodeBase, która daje ścieżkę w formacie URI, a następnie UriBuild.UnescapeDataString usuwa File:// na początku i GetDirectoryName zmienia ją na normalny format windows.

 906
Author: John Sibly,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-27 20:00:49

Czy to pomaga?

//get the full location of the assembly with DaoTests in it
string fullPath = System.Reflection.Assembly.GetAssembly(typeof(DaoTests)).Location;

//get the folder that's in
string theDirectory = Path.GetDirectoryName( fullPath );
 287
Author: Keith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-20 06:54:55

To takie proste:

var dir = AppDomain.CurrentDomain.BaseDirectory;
 276
Author: Jalal El-Shaer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-03 13:01:06

Taka sama jak odpowiedź Jana, ale nieco mniej rozbudowana metoda.

public static string GetDirectoryPath(this Assembly assembly)
{
    string filePath = new Uri(assembly.CodeBase).LocalPath;
    return Path.GetDirectoryName(filePath);            
}

Teraz możesz zrobić:

var localDir = Assembly.GetExecutingAssembly().GetDirectoryPath();

Lub jeśli wolisz:

var localDir = typeof(DaoTests).Assembly.GetDirectoryPath();
 63
Author: Sneal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-07 15:57:29

Jedynym rozwiązaniem, które działało dla mnie przy użyciu CodeBase i akcji sieciowych UNC było:

System.IO.Path.GetDirectoryName(new System.Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase).LocalPath);

Działa również z normalnymi Uri.

 43
Author: Ignacio Soler Garcia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-22 09:58:19

To powinno działać, chyba że skład jest skopiowany cieniem :

string path = System.Reflection.Assembly.GetExecutingAssembly().Location
 31
Author: jodonnell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-22 08:37:58

Podejrzewam, że prawdziwym problemem jest to, że twój test runner kopiuje Twój zespół w inne miejsce. Nie ma sposobu, aby w czasie wykonywania powiedzieć, skąd assembly został skopiowany, ale prawdopodobnie możesz przełączyć przełącznik, aby powiedzieć runner test, aby uruchomić assembly z miejsca, w którym jest, a nie skopiować go do katalogu shadow.

Taki przełącznik może być oczywiście inny dla każdego biegacza testowego.

Czy rozważałeś osadzenie danych XML jako zasobów wewnątrz testu Zgromadzenie?

 11
Author: Curt Hagenlocher,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-09 21:36:04

A co z tym:

System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
 11
Author: huseyint,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-09 21:40:06
AppDomain.CurrentDomain.BaseDirectory

Działa z interfejsem graficznym MbUnit.

 9
Author: user368021,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-16 13:02:58
var assembly = System.Reflection.Assembly.GetExecutingAssembly();
var assemblyPath = assembly.GetFiles()[0].Name;
var assemblyDir = System.IO.Path.GetDirectoryName(assemblyPath);
 7
Author: Mark Cidade,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-22 08:42:25

Oto VB.NET port kodu Johna Sibly ' ego. Visual Basic nie rozróżnia wielkości liter, więc kilka jego nazw zmiennych kolidowało z nazwami typów.

Public Shared ReadOnly Property AssemblyDirectory() As String
    Get
        Dim codeBase As String = Assembly.GetExecutingAssembly().CodeBase
        Dim uriBuilder As New UriBuilder(codeBase)
        Dim assemblyPath As String = Uri.UnescapeDataString(uriBuilder.Path)
        Return Path.GetDirectoryName(assemblyPath)
    End Get
End Property
 7
Author: Mike Schall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-19 12:33:51

Używam Assembly.Kod zamiast Lokalizacji:

Assembly a;
a = Assembly.GetAssembly(typeof(DaoTests));
string s = a.CodeBase.ToUpper(); // file:///c:/path/name.dll
Assert.AreEqual(true, s.StartsWith("FILE://"), "CodeBase is " + s);
s = s.Substring(7, s.LastIndexOf('/') - 7); // 7 = "file://"
while (s.StartsWith("/")) {
    s = s.Substring(1, s.Length - 1);
}
s = s.Replace("/", "\\");
Działa, ale nie jestem już pewien, czy jest w 100% poprawny. Strona w http://blogs.msdn.com/suzcook/archive/2003/06/26/assembly-codebase-vs-assembly-location.aspx{[5]says:

"baza kodowa jest adresem URL do miejsca, w którym plik został znaleziony, podczas gdy lokalizacja jest ścieżką, do której został faktycznie załadowany. Na przykład, jeśli zespół został pobrany z internetu, jego kod może zaczynać się od "http://", ale jego lokalizacja może zaczynać się od"C:\". Jeśli plik był kopiowany w cieniu, lokalizacja byłaby ścieżką do kopii pliku w katalogu kopiowanie cienia. Dobrze jest również wiedzieć, że baza kodowa nie jest gwarantowana dla zestawów w GAC. Lokalizacja zawsze będzie ustawiona dla zestawów załadowanych z dysku."

You may want to use CodeBase zamiast Location.

 6
Author: dan gibson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-09 21:50:49

Przez te wszystkie lata nikt o tym nie wspominał. Sztuczka, której nauczyłem się z niesamowitego ApprovalTests project. Sztuczka polega na tym, że używasz informacji o debugowaniu w złożeniu, aby znaleźć oryginalny katalog.

Nie będzie to działać w trybie RELEASE, ani z włączonymi optymalizacjami, ani na komputerze innym niż ten, na którym został skompilowany.

Ale dzięki temu uzyskasz ścieżki, które są względem lokalizacji pliku kodu źródłowego, który nazywasz od

public static class PathUtilities
{
    public static string GetAdjacentFile(string relativePath)
    {
        return GetDirectoryForCaller(1) + relativePath;
    }
    public static string GetDirectoryForCaller()
    {
        return GetDirectoryForCaller(1);
    }


    public static string GetDirectoryForCaller(int callerStackDepth)
    {
        var stackFrame = new StackTrace(true).GetFrame(callerStackDepth + 1);
        return GetDirectoryForStackFrame(stackFrame);
    }

    public static string GetDirectoryForStackFrame(StackFrame stackFrame)
    {
        return new FileInfo(stackFrame.GetFileName()).Directory.FullName + Path.DirectorySeparatorChar;
    }
}
 6
Author: George Mauer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-30 15:27:55

Bieżący katalog, w którym istniejesz.

Environment.CurrentDirectory;  // This is the current directory of your application

Jeśli skopiujeszplik xml z build powinieneś go znaleźć.

Lub

System.Reflection.Assembly assembly = System.Reflection.Assembly.GetAssembly(typeof(SomeObject));

// The location of the Assembly
assembly.Location;
 5
Author: David Basarab,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-09 20:16:04

Z tego co wiem, większość innych odpowiedzi ma kilka problemów.

Poprawnym sposobem, aby to zrobić dla dyskowego (w przeciwieństwie do webowego), nie-GACed assembly jest Użycie aktualnie wykonującego assembly właściwości CodeBase.

Zwraca adres URL (file://). Zamiast bawić się manipulacją strunami lub UnescapeDataString, można to przekształcić przy minimalnym zamieszaniu, wykorzystując właściwość LocalPath Uri.

var codeBaseUrl = Assembly.GetExecutingAssembly().CodeBase;
var filePathToCodeBase = new Uri(codeBaseUrl).LocalPath;
var directoryPath = Path.GetDirectoryName(filePathToCodeBase);
 5
Author: spender,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:31

Co ty na to?..

string ThisdllDirectory = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);

Następnie po prostu siekać to, czego nie trzeba

 5
Author: David C Fuchs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-29 22:37:14

Możesz uzyskać ścieżkę binową przez AppDomain.CurrentDomain.RelativeSearchPath

 2
Author: sumitup,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-22 13:19:47

Wszystkie proponowane odpowiedzi działają, gdy programista może zmienić kod, aby zawierał wymagany fragment, ale jeśli chcesz to zrobić bez zmiany kodu, możesz użyć Process Explorer.

Wyświetli listę wszystkich uruchomionych bibliotek DLL w systemie, może być konieczne określenie id procesu uruchomionej aplikacji, ale zwykle nie jest to zbyt trudne.

Napisałem pełny opis jak to zrobić dla dll inside II - http://nodogmablog.bryanhogan.net/2016/09/locating-and-checking-an-executing-dll-on-a-running-web-server/

 2
Author: Bryan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-19 12:36:26

W aplikacji windows form można po prostu użyć Application.StartupPath

Ale w bibliotekach DLL i aplikacjach konsolowych kod jest znacznie trudniejszy do zapamiętania...

string slash = Path.DirectorySeparatorChar.ToString();
string root = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);

root += slash;
string settingsIni = root + "settings.ini"
 2
Author: Shane J,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-11 19:39:54
string path = Path.GetDirectoryName(typeof(DaoTests).Module.FullyQualifiedName);
 1
Author: Jesse C. Slicer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-09 21:46:48

To właśnie wymyśliłem. pomiędzy projektami sieciowymi, testami jednostkowymi (nunit i ReSharper Test runner) ; okazało się, że to działa dla mnie.

Szukałem kodu do wykrycia, w jakiej konfiguracji znajduje się build, Debug/Release/CustomName. Niestety, #if DEBUG. więc jeśli ktoś może to poprawić !

Zapraszam do edycji i poprawy.

Pobieranie folderu aplikacji . Przydatne dla web roots, unittests, aby uzyskać folder plików testowych.

public static string AppPath
{
    get
    {
        DirectoryInfo appPath = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory);

        while (appPath.FullName.Contains(@"\bin\", StringComparison.CurrentCultureIgnoreCase)
                || appPath.FullName.EndsWith(@"\bin", StringComparison.CurrentCultureIgnoreCase))
        {
            appPath = appPath.Parent;
        }
        return appPath.FullName;
    }
}

Getting bin folder : Przydatne do wykonywania złożeń przy użyciu reflection. Jeśli pliki są tam kopiowane ze względu na właściwości budowania.

public static string BinPath
{
    get
    {
        string binPath = AppDomain.CurrentDomain.BaseDirectory;

        if (!binPath.Contains(@"\bin\", StringComparison.CurrentCultureIgnoreCase)
            && !binPath.EndsWith(@"\bin", StringComparison.CurrentCultureIgnoreCase))
        {
            binPath = Path.Combine(binPath, "bin");
            //-- Please improve this if there is a better way
            //-- Also note that apps like webapps do not have a debug or release folder. So we would just return bin.
#if DEBUG
            if (Directory.Exists(Path.Combine(binPath, "Debug"))) 
                        binPath = Path.Combine(binPath, "Debug");
#else
            if (Directory.Exists(Path.Combine(binPath, "Release"))) 
                        binPath = Path.Combine(binPath, "Release");
#endif
        }
            return binPath;
    }
}
 0
Author: Valamas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-03 23:34:11

To powinno zadziałać:

ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
Assembly asm = Assembly.GetCallingAssembly();
String path = Path.GetDirectoryName(new Uri(asm.EscapedCodeBase).LocalPath);

string strLog4NetConfigPath = System.IO.Path.Combine(path, "log4net.config");

Używam tego do wdrożenia bibliotek plików DLL wraz z jakimś plikiem konfiguracyjnym(jest to użycie log4net z pliku DLL).

 0
Author: mmmmmm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-19 12:37:25

Uważam, że moje rozwiązanie jest odpowiednie do odzyskania lokalizacji.

var executingAssembly = new FileInfo((Assembly.GetExecutingAssembly().Location)).Directory.FullName;
 0
Author: Tez Wingfield,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-23 11:54:32

Miałem to samo zachowanie w NUnit w przeszłości. Domyślnie NUnit kopiuje twój zestaw do katalogu temp. Możesz zmienić to zachowanie w Ustawieniach NUnit:

Tutaj wpisz opis obrazka

Może TestDriven.NET i MbUnit GUI mają te same ustawienia.

 0
Author: Andrey Bushman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-30 09:55:13

Używam tego, aby uzyskać ścieżkę do katalogu Bin:

var i = Environment.CurrentDirectory.LastIndexOf(@"\");
var path = Environment.CurrentDirectory.Substring(0,i); 

Otrzymujesz ten wynik:

"c:\users\ricooley\documents\visual studio 2010 \ Projects\Windows_Test_Project\Windows_Test_Project \ bin"

 -2
Author: rcooley56,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-21 18:44:53

Aplikacja internetowa?

Server.MapPath("~/MyDir/MyFile.ext")
 -3
Author: user2009677,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-18 10:34:01