877

現在のコードが存在するアセンブリのパスを取得する方法はありますか?呼び出し元のアセンブリのパスは必要ありません。コードを含むパスだけが必要です。

基本的に、私の単体テストは、dllに関連して配置されているいくつかのxmlテストファイルを読み取る必要があります。テストdllがTestDriven.NET、MbUnit GUI、またはその他のものから実行されているかどうかに関係なく、パスが常に正しく解決されるようにしたい。

編集:人々は私が求めていることを誤解しているようです。

私のテストライブラリは次の場所にあります

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

そして私はこの道を取得したいと思います:

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

MbUnit Guiから実行すると、これまでの3つの提案は失敗します。

  • Environment.CurrentDirectoryc:\ Program Files\MbUnit を与えます

  • System.Reflection.Assembly.GetAssembly(typeof(DaoTests)).LocationC:\ Documents and Settings \ george \ Local Settings \ Temp \ ....\DaoTests.dllを提供し ます

  • System.Reflection.Assembly.GetExecutingAssembly().Location 前と同じになります。

4

31 に答える 31

1136

単体テストでよく使用するため、次のプロパティを定義しました。

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.Locationプロパティは、NUnit (アセンブリが一時フォルダーから実行される場所) を使用するときに面白い結果をもたらすことがあるのでCodeBase、URI 形式でパスを提供し、先頭の をUriBuild.UnescapeDataString削除して、通常の Windows 形式に変更する方法を使用することをお勧めします。 .File://GetDirectoryName

于 2008-11-12T13:24:56.133 に答える
346

これは役に立ちますか?

//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 );
于 2008-09-09T21:26:52.093 に答える
345

次のように簡単です。

var dir = AppDomain.CurrentDomain.BaseDirectory;
于 2010-05-22T09:14:20.027 に答える
73

ジョンの答えと同じですが、少し冗長な拡張方法です。

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

これで、次のことができます。

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

または、必要に応じて:

var localDir = typeof(DaoTests).Assembly.GetDirectoryPath();
于 2010-04-02T14:43:27.357 に答える
50

CodeBase と UNC Network 共有を使用しているときに私にとって有効だった唯一の解決策は、次のとおりでした。

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

また、通常の URI でも機能します。

于 2012-03-16T12:40:45.580 に答える
38

アセンブリがシャドウコピーされていない限り、これは機能するはずです:

string path = System.Reflection.Assembly.GetExecutingAssembly().Location
于 2008-09-09T20:14:36.807 に答える
15

これはどうですか:

System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
于 2008-09-09T21:40:06.367 に答える
14
AppDomain.CurrentDomain.BaseDirectory

MbUnitGUIで動作します。

于 2010-06-16T08:07:46.710 に答える
12

ここでの本当の問題は、テスト ランナーがアセンブリを別の場所にコピーしていることだと思います。実行時にアセンブリがどこからコピーされたかを知る方法はありませんが、おそらくスイッチを切り替えて、テスト ランナーにアセンブリをその場所から実行し、シャドウ ディレクトリにコピーしないように指示することができます。

もちろん、このような切り替えはテスト ランナーごとに異なる可能性があります。

テスト アセンブリ内に XML データをリソースとして埋め込むことを検討したことはありますか?

于 2008-09-09T21:36:04.270 に答える
10

これはどう ...

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

次に、必要のないものをハックします

于 2016-08-29T22:37:14.957 に答える
8

私が知る限り、他の回答のほとんどにはいくつかの問題があります。

(Web ベースではなく) ディスクベースの非 GAC アセンブリでこれを行う正しい方法は、現在実行中のアセンブリのCodeBaseプロパティを使用することです。

これは URL ( ) を返しますfile://文字列操作orをいじる代わりに、これは のプロパティをUnescapeDataString活用することで最小限の手間で変換できます。LocalPathUri

var codeBaseUrl = Assembly.GetExecutingAssembly().CodeBase;
var filePathToCodeBase = new Uri(codeBaseUrl).LocalPath;
var directoryPath = Path.GetDirectoryName(filePathToCodeBase);
于 2014-06-16T18:13:53.053 に答える
7

これは、JohnSiblyのコードのVB.NETポートです。Visual Basicでは大文字と小文字が区別されないため、彼の変数名のいくつかが型名と衝突していました。

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
于 2009-05-19T18:58:27.997 に答える
7
var assembly = System.Reflection.Assembly.GetExecutingAssembly();
var assemblyPath = assembly.GetFiles()[0].Name;
var assemblyDir = System.IO.Path.GetDirectoryName(assemblyPath);
于 2008-09-09T21:32:28.960 に答える
6

ここ数年、誰も実際にこれについて言及していません。すばらしいApprovalTests プロジェクトから学んだトリックです。秘訣は、アセンブリ内のデバッグ情報を使用して元のディレクトリを見つけることです。

これは、RELEASE モードでも、最適化が有効な場合でも、コンパイルされたマシンとは異なるマシンでも機能しません。

ただし、これにより、呼び出し元のソースコードファイルの場所に相対的なパスが取得されます

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;
    }
}
于 2015-09-30T15:27:55.303 に答える
5

Location の代わりに Assembly.CodeBase を使用しています。

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("/", "\\");

動作していますが、100% 正しいかどうかはわかりません。http://blogs.msdn.com/suzcook/archive/2003/06/26/assembly-codebase-vs-assembly-location.aspxのページには次のように書かれています。

「CodeBase はファイルが見つかった場所への URL であり、Location は実際にロードされたパスです。たとえば、アセンブリがインターネットからダウンロードされた場合、その CodeBase は「http://」で始まる場合があります。 , but its Location may start with "C:\". ファイルがシャドウ コピーされた場合、Location はシャドウ コピー ディレクトリ内のファイルのコピーへのパスになります. CodeBase が保証されていないことも知っておくとよいでしょう. GAC 内のアセンブリに対して設定されます。ただし、ディスクからロードされたアセンブリに対しては常に場所が設定されます。

Location の代わりに CodeBase を使用することもできます。

于 2008-09-09T21:50:49.523 に答える
4

あなたが存在する現在のディレクトリ。

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

ビルドで.xmlファイルをコピーすると、それが見つかるはずです。

また

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

// The location of the Assembly
assembly.Location;
于 2008-09-09T20:16:04.463 に答える
1
string path = Path.GetDirectoryName(typeof(DaoTests).Module.FullyQualifiedName);
于 2008-09-09T21:46:48.783 に答える
0

これはうまくいくはずです:

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

これを使用して、いくつかの構成ファイルとともに DLL ファイル ライブラリを展開しています (これは、DLL ファイル内から log4net を使用するためです)。

于 2013-06-12T08:04:28.510 に答える
0

私は過去に同じ行動をしNUnitました。既定でNUnitは、アセンブリが一時ディレクトリにコピーされます。この動作はNUnit設定で変更できます。

ここに画像の説明を入力

たぶんGUIと同じ設定ですTestDriven.NETMbUnit

于 2015-09-30T09:55:13.407 に答える
0

これが私が思いついたものです。Web プロジェクトの合間に、単体テスト (nunit および resharper テスト ランナー) ; これがうまくいくことがわかりました。

ビルドの構成を検出するコードを探していましたDebug/Release/CustomName. ああ、#if DEBUG誰かがそれを改善できるなら

自由に編集して改善してください。

アプリ フォルダを取得しています。Web ルート、ユニットテストでテスト ファイルのフォルダーを取得するのに役立ちます。

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

bin フォルダーの取得: リフレクションを使用してアセンブリを実行する場合に便利です。ビルド プロパティのためにファイルがそこにコピーされる場合。

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;
    }
}
于 2013-07-03T05:20:50.563 に答える
-3

これを使用して、Bin ディレクトリへのパスを取得します。

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

次の結果が得られます。

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

于 2011-12-21T18:00:49.467 に答える