Jak uzyskać ścieżkę do zestawu, w którym znajduje się kod?


781

Czy istnieje sposób na uzyskanie ścieżki do zestawu, w którym znajduje się bieżący kod? Nie chcę ścieżki do wywołującego zestawu, tylko tego zawierającego kod.

Zasadniczo mój test jednostkowy musi odczytać niektóre pliki testowe xml, które znajdują się w stosunku do biblioteki dll. Chcę, aby ścieżka zawsze była poprawnie rozwiązywana bez względu na to, czy dll testujący jest uruchamiany z TestDriven.NET, interfejsu GUI MbUnit, czy czegoś innego.

Edycja : Ludzie wydają się nie rozumieć, o co pytam.

Moja biblioteka testów znajduje się w powiedzmy

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

i chciałbym uzyskać tę ścieżkę:

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

Jak dotąd trzy sugestie mnie zawiodły, gdy uruchamiam z MbUnit Gui:

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

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

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


102
Oto twoje rozwiązanie: var dir = AppDomain.CurrentDomain.BaseDirectory;
Jalal El-Shaer

7
To powinno być przyjęte rozwiązanie. AppDomain.CurrentDomain.BaseDirectory to prawidłowe podejście.
aBetterGamer


2
Przybyłem tutaj, szukając rozwiązania pakietu nuget do odczytu pliku JSON z katalogu pacakge. Wydaje się, że po uruchomieniu pakietu nuget „AppDomain.CurrentDomain.BaseDirectory” wskazuje katalog uruchomionych projektów, a nie katalog pakietu nuget. Wydaje się, że żaden z nich nie jest poprawnie kierowany do katalogu pakietu nuget.
Lucas

@Lucas nie, nie zrobiłby tego, ponieważ nie o to chodziło w tym pytaniu (w rzeczywistości, gdy zostało zadane, nuget nie istniał) - możesz zacząć nowe pytanie i pingować mnie tam, ale mogę ci teraz powiedzieć, że w większości przypadków jest to niemożliwe. W przypadku większości projektów katalog nuget znajduje się packagesobok pliku SLN. ALE podczas kompilacji i dystrybucji nie ma pliku SLN ani katalogu pakietów. Podczas kompilacji rzeczy, które są potrzebne (ale nie wszystko) są kopiowane do katalogu bin. Najlepszym rozwiązaniem jest użycie skryptu postbuild do skopiowania żądanego pliku.
George Mauer,

Odpowiedzi:


1036

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

Assembly.LocationNieruchomość czasami daje jakieś zabawne rezultaty przy użyciu NUnit (gdzie zespoły uruchomić z folderu tymczasowego), więc wolę używać CodeBaseco daje ścieżkę w formacie URI, a następnie UriBuild.UnescapeDataStringusuwa File://się na początku, a GetDirectoryNamezmienia go do formatu normalne okna .


29
Wystąpił jeden problem, z którym się zetknąłem, jeśli nazwa twojego katalogu to: c: \ My% 20Directory, wówczas zwróci Uri.UnescapeDataString: c: \ My Directory Oznacza to, że File.Exists ("c: \ My Directory \ MyFile.txt „) zwróci false, ponieważ właściwa ścieżka to w rzeczywistości„ c: \ My% 20Directory \ MyFile.txt ”Natknąłem się na to, ponieważ nasze ścieżki SVN mają w nich spacje, a kiedy je sprawdzamy, koduje spacje.
wiersz 1

5
Zachowaj ostrożność, gdy używasz tego do sprawdzania File.Exist (), ponieważ ta metoda zwróci false na ścieżce UNC. Zamiast tego użyj odpowiedzi @ Keitha.
AZ.

3
Nie wiedziałem, że możesz umieścić statyczny przed publicznym. Miło to wiedzieć i myślę, że wolę czytelność
Valamas

5
Uwaga: nie działa to z lokalizacjami sieciowymi (np. \\ REMOT_EPC \ Folder)
Muxa

5
To również nie zadziała, jeśli katalog zawiera znaki numeryczne „#”. Znaki liczbowe są dozwolone w nazwach katalogów i plików w systemie Windows.
Huemac,

321

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

nie widzę mojej edycji, czy to coś dziwnego w tym, jak MbUnit robi rzeczy?
George Mauer,

3
Ustaw pliki XML jako treści, skopiowane z biblioteką DLL lub zasobami odczytanymi z biblioteki DLL.
Keith,

22
Lub po prostutypeof(DaoTests).Assembly
SLaks

4
@SLaks @JohnySkovdal @Keith: Cześć chłopaki, używajcie Assembly.GetExecutingAssembly(). To „dostaje zespół, który zawiera kod, który jest aktualnie wykonywany” (z opisem metody). Używam tego w moich AddIn „ EntitiesToDTOs ”. Zobacz przykładowy plik AssemblyHelper.cs .
kzfabi

4
Wystąpił problem z postem @John Silby, ponieważ nie wygląda na to, że działa ze ścieżkami UNC ... np. \\ Server \ Folder \ File.ext. Ten załatwił sprawę. +1
Jagoda

312

To takie proste:

var dir = AppDomain.CurrentDomain.BaseDirectory;

11
To powinno być przyjęte rozwiązanie. AppDomain.CurrentDomain.BaseDirectory to prawidłowe podejście.
aBetterGamer

5
dziękuję za zwrócenie mojej uwagi na to - nie jestem pewien, czy było to dostępne w momencie, gdy zadałem pytanie, ale teraz jest.
George Mauer,

120
Nie, to źle. Zwraca ścieżkę ORYGINALNEGO PUNKTU WEJŚCIA, a nie aktualnie wykonywanego kodu. Jeśli zespół został załadowany ręcznie z innej ścieżki lub jeśli został załadowany z GAC, zwróci nieprawidłowy wynik. Ta odpowiedź jest poprawna: stackoverflow.com/a/283917/243557 Quicker nadal jest Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location).
nathanchere

9
W rzeczywistości nie będzie to działać w aplikacjach internetowych, ale o ile mi się wydaje, następujące ulepszenie powinno działać w przypadku każdego rodzaju aplikacji:AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory
Ilya Chernomordik

4
Jest to doskonałe do testowania jednostek, jeśli chcesz uzyskać oryginalną ścieżkę bin zestawu testowego (powiedzmy, aby dotrzeć do plików danych pomocniczych w podfolderach). Zestaw testowy jest punktem wejściowym twojego kodu.
MarioDS

68

Taki sam jak odpowiedź Johna, ale nieco mniej rozbudowana metoda rozszerzenia.

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();

6
Miałeś na myśli assemblyzamiast Assembly.GetExecutingAssembly()?
Koleś Pascalou,

3
Jak wskazuje Dude, podałeś argument i nie wykorzystałeś go.
Chris Moschini

4
Ta odpowiedź jest po prostu błędna dla danego pytania. Zmodyfikowana wersja tej odpowiedzi może podać ścieżkę do danego zestawu. Jednak tutaj szczególnie szukamy wykonującego zestawu, więc przekazanie zestawu nie ma sensu. Metoda rozszerzenia jest niewłaściwym narzędziem dla zadania.
Edward Brey

46

Jedynym rozwiązaniem, które działało dla mnie podczas korzystania z CodeBase i udziałów sieciowych UNC było:

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

Działa również z normalnymi identyfikatorami URI.


5
To powinna być zaakceptowana odpowiedź. Naprawdę denerwujące jest to, że domyślna baza kodów nie obsługuje poprawnie udziałów UNC.
Daniel Gilbert

Dzieje się tak, gdy folder zawiera spacje, a Bóg wie, jakie inne postacie ...
MarioDS

1
Używam tego bardzo często i znalazłem jeden scenariusz, w którym się nie udaje: jeśli ten wiersz kodu sam jest częścią pakietu NuGet, który jest następnie używany przez aplikację! Możemy również wesprzeć ten scenariusz, zastępując GetExecutingAssembly()go GetCallingAssembly().
Timo,

@ Timo: czy sprawdziłeś, czy ta zmiana ma skutki uboczne? Jeśli tak, edytuj odpowiedź, aby dołączyć poprawkę.
Ignacio Soler Garcia

@IgnacioSolerGarcia Niestety niestety muszę zgłosić, że działał on głęboko tylko na jednej warstwie, tzn. Nie powiedzie się, jeśli pakiet NuGet został wywołany przez inny pakiet NuGet! Jestem teraz za pomocą tego (z komentarzem na tej stronie przez Chernomordik) AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory. Pierwsza część dotyczy aplikacji internetowych, a druga dotyczy innych aplikacji.
Timo,

32

Powinno to działać, chyba że zestaw jest kopiowany w tle :

string path = System.Reflection.Assembly.GetExecutingAssembly().Location

14

A co z tym:

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

11

Podejrzewam, że prawdziwym problemem jest to, że Twój tester kopiuje zestaw w innym miejscu. W środowisku wykonawczym nie ma sposobu, aby dowiedzieć się, skąd zestaw został skopiowany, ale prawdopodobnie możesz przełączyć przełącznik, aby poinformować biegacza testowego, aby uruchomił zestaw z miejsca, w którym się znajduje, i nie kopiował go do katalogu cienia.

Oczywiście taka zmiana może być inna dla każdego uczestnika testu.

Czy rozważałeś osadzenie swoich danych XML jako zasobów w zestawie testowym?


+1 za wskazanie problemu z kopiowaniem w tle. Rzeczywiście można jednak ustalić oryginalne miejsce na podstawie Assembly.CodeBase.
tm1


10

Wierzę, że to zadziała dla każdego rodzaju aplikacji:

AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory

1
Moje eksperymenty pokazują, że jest to najbardziej niezawodna odpowiedź, obejmująca nie tylko aplikacje internetowe i konsolowe, ale także wywołania z testów jednostkowych i pakietów NuGet (zagnieżdżonych na dowolnym poziomie rekurencji).
Timo,

8

O ile wiem, większość innych odpowiedzi ma kilka problemów.

Prawidłowym sposobem na to w przypadku zestawu opartego na dysku (w przeciwieństwie do zestawu internetowego) bez GACed jest użycie właściwości aktualnie wykonywanego zestawu CodeBase.

Zwraca URL ( file://). Zamiast manipulować ciągami znaków lub UnescapeDataString, można to przekonwertować przy minimalnym zamieszaniu, korzystając z LocalPathwłaściwości Uri.

var codeBaseUrl = Assembly.GetExecutingAssembly().CodeBase;
var filePathToCodeBase = new Uri(codeBaseUrl).LocalPath;
var directoryPath = Path.GetDirectoryName(filePathToCodeBase);

1
Nie działa, jeśli ścieżka zawiera #( EscapedCodeBasedziała, ale EscapedCodeBase nie działa, jeśli ścieżka zawiera np. %20Dosłownie (która jest dozwoloną sekwencją znaków w ścieżce systemu Windows)
Martin Ba

Jeśli chcemy mieć ten kod w pakiecie NuGet, możemy naprawić ten scenariusz, zastępując GetExecutingAssembly()go GetCallingAssembly().
Timo,

8

Co powiesz na to ...

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

Następnie po prostu zhakuj to, czego nie potrzebujesz


7
var assembly = System.Reflection.Assembly.GetExecutingAssembly();
var assemblyPath = assembly.GetFiles()[0].Name;
var assemblyDir = System.IO.Path.GetDirectoryName(assemblyPath);

7

Oto port VB.NET kodu Johna Sably'ego. W programie Visual Basic nie rozróżniana jest wielkość 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

6

Przez te wszystkie lata nikt tak naprawdę nie wspomniał o tym. Sztuczka, której nauczyłem się z niesamowitego projektu ApprovalTests . Sztuczka polega na tym, że używasz informacji debugowania w zestawie, aby znaleźć oryginalny katalog.

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

Ale to da ci ścieżki, które są względne względem lokalizacji pliku kodu źródłowego, z którego go wywołujesz

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

5

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

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

Jeśli skopiujesz plik .xml z kompilacją, powinieneś go znaleźć.

lub

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

// The location of the Assembly
assembly.Location;

będzie to problematyczne, jeśli zespół został skopiowany w tle .
spędził

+1520! Environment.CurrentDirectorydziała, jeśli używasz refleksji w klasie zadań MSBuild, gdzie wykonujący zestaw rezyduje w GAC, a twój kod jest gdzie indziej.
vulcan raven

4
Ogólnie CurrentDirectory nie mówi ci, gdzie znajdują się twoje pliki wykonywalne. Nie do tego służy. Zdarza się, że często jest to ta sama lokalizacja, w której znajdują się pliki wykonywalne, więc wielu programistów nie rozumie różnicy. Następnie powodują problemy dla niektórych użytkowników końcowych, którzy oczekiwali, że aplikacja zrozumie prawidłowe użycie CurrentDirectory.
Bent Tranberg,

5

Korzystałem z Assembly.CodeBase zamiast Location:

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 na stronie http://blogs.msdn.com/suzcook/archive/2003/06/26/assembly-codebase-vs-assembly-location.aspx mówi:

„CodeBase to adres URL miejsca, w którym plik został znaleziony, a Lokalizacja to ścieżka, w której rzeczywiście został załadowany. Na przykład, jeśli zestaw został pobrany z Internetu, jego CodeBase może zaczynać się od„ http: // ” , ale jego lokalizacja może zaczynać się od „C: \”. Jeśli plik został skopiowany w tle, lokalizacja byłaby ścieżką do kopii pliku w katalogu kopii w tle. Dobrze jest również wiedzieć, że CodeBase nie jest gwarantowana należy ustawić dla zestawów w GAC. Jednak lokalizacja będzie zawsze ustawiona dla zestawów ładowanych z dysku.

Ty może chcesz używać kodzie zamiast gości.


1
@Kiquenet: Tyle kodu tylko do konwersji URI na ścieżkę. Pewnie, że można to poprawić. Spójrz na odpowiedź Mike'a Schall'a lub SoMoS. Nie powinieneś próbować konwertować identyfikatorów URI na poziomie łańcucha, ale zamiast tego użyj odpowiednich obiektów. OK, niezręcznie jest również, że Assembly.CodeBase zwraca ciąg zamiast bardziej odpowiedniego obiektu, takiego jak URI lub FileInfo.
Siedem


2

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

Spowoduje to wyświetlenie listy wszystkich wykonujących 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 tego, jak to zrobić dla biblioteki DLL wewnątrz II - http://nodogmablog.bryanhogan.net/2016/09/locating-and-checking-an-executing-dll-on-a-running-web -serwer/


Zauważ, że po pierwsze, kod w artykule jest dość skoncentrowany na IIS, a po drugie, daje (jak sądzę) wszystkie aktualnie załadowane dll, a nie to, co jest uruchomione w danym momencie.
George Mauer,

Podany przykład dotyczy iis, ale te same kroki mają zastosowanie, jeśli biblioteka DLL działa w procesie poza iis. To tylko kwestia zidentyfikowania identyfikatora procesu. Zaktualizuję artykuł, aby to zauważyć. Dzieki za sugestie.
Bryan,

2

w aplikacji systemu Windows można po prostu użyć Application.StartupPath

ale w przypadku bibliotek DLL i aplikacji 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"


1

Otrzymasz niepoprawny katalog, jeśli ścieżka zawiera symbol „#”. Używam więc modyfikacji odpowiedzi Johna Sible'a, która jest kombinacją UriBuilder.Path i UriBuilder.Fragment:

public static string AssemblyDirectory
{
    get
    {
        string codeBase = Assembly.GetExecutingAssembly().CodeBase;
        UriBuilder uri = new UriBuilder(codeBase);
        //modification of the John Sibly answer    
        string path = Uri.UnescapeDataString(uri.Path.Replace("/", "\\") + 
          uri.Fragment.Replace("/", "\\"));
        return Path.GetDirectoryName(path);
     }
}

0

Właśnie to wymyśliłem. Pomiędzy projektami internetowymi, testami jednostkowymi (biegacz testowy nunit i resharper) ; Odkryłem, że to działało dla mnie.

Mam był patrząc na kod do wykrywania co konfiguracja kompilacji jest, Debug/Release/CustomName. Niestety, #if DEBUG. Więc jeśli ktoś może to poprawić !

Możesz edytować i ulepszać.

Pobieranie folderu aplikacji . Przydatny w przypadku katalogów internetowych, pozwala na uzyskanie folderu 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;
    }
}

Pobieranie folderu bin : Przydatne do wykonywania złożeń za pomocą odbicia. Jeśli pliki są tam kopiowane ze względu na właściwości kompilacji.

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

To powinno dział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 wdrażania bibliotek plików DLL wraz z niektórymi plikami konfiguracyjnymi (jest to użycie log4net z pliku DLL).


Do czego fileMapsłuży tutaj?
George Mauer,

0

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

var executingAssembly = new FileInfo((Assembly.GetExecutingAssembly().Location)).Directory.FullName;

Jest to już jedna z najwyżej ocenianych odpowiedzi i jest wyraźnie wymieniona w pytaniu jako coś, co nie działa w tej sytuacji.
George Mauer,

Przepraszamy za przeoczenie! Oczywiście nie przeczytałem dokładnie.
Tez Wingfield

0

W NUnitprzeszłości miałem takie samo zachowanie . Domyślnie NUnitkopiuje zestaw do katalogu tymczasowego. Możesz zmienić to zachowanie w NUnitustawieniach:

wprowadź opis zdjęcia tutaj

Może TestDriven.NETi MbUnitGUI mają te same ustawienia.


-3

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

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

Otrzymasz ten wynik:

„c: \ users \ ricooley \ Document \ visual studio 2010 \ Projects \ Windows_Test_Project \ Windows_Test_Project \ bin”


6
Nie widzę powodu, aby unikać Path.getDirectoryName tutaj
Max Keller

@MaxKeller Jeśli nie widzisz powodów, nie oznacza to, że ma rację. Ta alternatywna metoda Path.GetDirectoryName jest dziesięć razy szybsza.
Ruslan Veselov,

-3

Aplikacja internetowa?

Server.MapPath("~/MyDir/MyFile.ext")

2
@christiandev to odpowiedź, ale może to być odpowiedź na złe pytanie. Z pytania jasno wynika, że ​​nie jest to aplikacja internetowa, ale zestaw uruchamiany za pomocą MbUnit. Biorąc to pod uwagę, odpowiedź wciąż nie jest prawdziwa z powodu kopiowania w tle Asp.Net (chociaż może być to, czego szuka ktoś lądujący na tym pytaniu).
George Mauer,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.