27

私は.NETユーザーです。目標は、実行中のメインアセンブリ(EXEファイル)のディレクトリの絶対パスを見つけることと同じくらい簡単です。

私にはいくつかの候補があります:

  • Assembly.GetExecutingAssembly().CodeBase
  • Assembly.GetExecutingAssembly().Location
  • AppDomain.CurrentDomain.BaseDirectory

.NETドキュメントで判断する場合-私はに傾いていCodeBaseます。誰かが.NETドキュメントよりももう少し具体的な用語で3つすべてに光を当てることができますか?おそらく違いを示す例は?

4

5 に答える 5

17

GetEntryAssembly()の代わりに使用しGetExecutingAssembly()ます。

理由を確認するには、次のようにします。

  • 新しいコンソール プロジェクトを作成する
  • クラス ライブラリ プロジェクト ( ) をソリューションに追加ClassLibrary1し、コンソール プロジェクトから参照します。

これを入れてくださいClassLibrary1

namespace ClassLibrary1
{
    using System;
    using System.IO;
    using System.Reflection;

    public class Class1
    {
        public void GetInfo(int n)
        {
            Assembly asm = Assembly.GetEntryAssembly();
            Console.WriteLine("[GetEntryAssembly {0}] Location:{1}", n, Path.GetDirectoryName(asm.Location));
            asm = Assembly.GetExecutingAssembly();
            Console.WriteLine("[GetExecutingAssembly() {0}] Location:{1}", n, Path.GetDirectoryName(asm.Location));
        }
    }
}

これをコンソールに入れますProgram.cs

namespace ConsoleApplication4
{
    using System;
    using System.IO;
    using System.Reflection;
    using ClassLibrary1;

    class Program
    {
        static void Main(string[] args)
        {
            Assembly asm = Assembly.GetEntryAssembly();
            Console.WriteLine("[GetEntryAssembly() 1] Location:{0}", Path.GetDirectoryName(asm.Location));
            asm = Assembly.GetExecutingAssembly();
            Console.WriteLine("[GetExecutingAssembly() 1] Location:{0}", Path.GetDirectoryName(asm.Location));

            Class1 obj1 = new Class1();
            obj1.GetInfo(2);

            asm = Assembly.LoadFile(@"C:\temp\ClassLibrary1.dll");
            Type t = asm.GetType("ClassLibrary1.Class1");
            object obj2 = asm.CreateInstance("ClassLibrary1.Class1");
            t.GetMethod("GetInfo").Invoke(obj2, new object[] { 3 });

            Console.ReadKey();
        }
    }
}

ソリューションをビルドし、コピーClassLibrary1.dllc:\tempて実行します。

ご覧のとおりGetExecutingAssembly()、特定の条件でだまされる可能性があります。

最後に、アプリが Windows フォームの場合は、Application.ExecutablePath.

于 2009-10-29T11:53:44.863 に答える
16

についてはわかりませんが、とAppDomain.CurrentDomain.BaseDirectoryの違いはこのブログ投稿で説明されています。Assembly.GetExecutingAssembly().CodeBaseAssembly.GetExecutingAssembly().Location

CodeBase はファイルが見つかった場所への URL であり、Location は実際に読み込まれた場所からのパスです。たとえば、アセンブリがインターネットからダウンロードされた場合、CodeBase は "http://" で始まりますが、Location は "C:\" で始まります。ファイルがシャドウ コピーされた場合、Location はシャドウ コピー ディレクトリ内のファイルのコピーへのパスになります。

また、CodeBase が GAC のアセンブリに対して設定されるとは限らないことも知っておくとよいでしょう。ただし、ディスクから読み込まれたアセンブリの場所は常に設定されます。

Locationしたがって、ファイルが実行された実際のディレクトリが必要な場合は、最善の策のようです。

于 2011-11-10T15:18:31.483 に答える
8

残念ながら、XenoCode postbuild のような仮想化を使用すると、上記のすべての方法が失敗する可能性があります。私は多くの方法をテストし、ここで別の解決策を見つけました。私が発見したのは、

System.Diagnostics.Process.GetCurrentProcess().ProcessName + ".exe"

実行可能ファイルの正しいファイル名を返します。したがって、ファイル名とパスを組み合わせるAssembly.GetEntryAssembly().Locationと、実行可能ファイルの正しいパスが取得されます。

于 2010-05-17T15:29:34.370 に答える
0

差出人:http ://msdn.microsoft.com/en-us/library/system.reflection.assembly.codebase.aspx

Assembly.CodeBase

ロードされたマニフェストを含むファイルへの絶対パスを取得するには、 Assembly.Location代わりにプロパティを使用します。

バイトの配列を受け取るLoadメソッドのオーバーロードを使用して、アセンブリがバイト配列としてロードされた場合、このプロパティは、ロードされたアセンブリの場所ではなく、メソッドの呼び出し元の場所を返します。

なぜならAppDomain.CurrentDomain.BaseDirectory、私は正直なところ、実用的な観点からの違いについてはわかりません。

于 2009-10-29T10:43:20.253 に答える
-3

System.Linq を使用する

string MainExecutablePath= (System.Diagnostics.Process.GetProcesses().First(P =>P.MainWindowTitle == "MainExecutable'sWindowName")).MainModule.FileName.ToString();
于 2014-02-19T09:45:49.743 に答える