使用Assembly vs AppDomain查找我的主要可执行文件的路径

tse*_*mer 24 .net directory exe path

我是.NET用户,我的目标就像找到主执行程序集(EXE文件)目录的绝对路径一样简单.

我有几个候选人:

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

如果要通过.NET文档判断 - 我倾向于CodeBase.任何人都可以用比.NET文档更具体的术语来解释这三个问题吗?一个例子来证明这种差异?

Sor*_*scu 16

我会用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));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

把它放在控制台中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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

生成解决方案,复制ClassLibrary1.dllc:\temp和运行.

正如您将看到的,GetExecutingAssembly()在某些情况下可能会欺骗您.

最后一点,如果您的应用程序是Windows窗体,您可以使用Application.ExecutablePath.

  • Assembly.GetEntryAssembly不可靠,特别是如果应用程序在非托管上下文而不是托管上下文中启动,它将返回null.结果必须为空检查. (16认同)
  • 如果您发布输出而不是进行编译并运行它以查看您的观点,这将是很好的:-) (12认同)

Ren*_*ené 12

我不确定AppDomain.CurrentDomain.BaseDirectory,但是在这篇博客文章中解释Assembly.GetExecutingAssembly().CodeBase和之间的区别.Assembly.GetExecutingAssembly().Location

CodeBase是找到文件的地方的URL,而Location是实际加载文件的路径.例如,如果在组件从互联网上下载,它的codebase以"http://",但其位置可启动"C:\".如果文件是阴影复制的,则Location将是shadow-copy目录中文件副本的路径.

知道不保证为GAC中的程序集设置CodeBase也是很好的.但是,将始终为从磁盘加载的程序集设置位置.

因此,最好的办法是,Location如果您需要执行文件的真实目录.

  • 实际上,使用阴影复制单元测试和一些复制到输出的文件,您可能希望使用CodeBase(通过Uri类解析),原因完全相同. (2认同)

Ale*_*aum 8

不幸的是,如果您使用像XenoCode postbuild这样的虚拟化,上面的所有方法都会失败.我已经测试了许多方法,发现另一种解决方案在这里.我发现只有

System.Diagnostics.Process.GetCurrentProcess().ProcessName + ".exe"
Run Code Online (Sandbox Code Playgroud)

返回可执行文件的正确文件名.因此,将文件名与Assembly.GetEntryAssembly().Location您的路径相结合将获得可执行文件的正确路径.

  • 当然,这是ASP.NET中的主要执行程序集 (2认同)

o.k*_*k.w 0

来自:http://msdn.microsoft.com/en-us/library/system.reflection . assembly.codebase.aspx

程序集.代码库

要获取已加载的包含清单的文件的绝对路径,请改用该 Assembly.Location属性。

如果程序集作为字节数组加载,则使用采用字节数组的 Load 方法的重载,此属性返回方法调用方的位置,而不是加载的程序集的位置。

对于AppDomain.CurrentDomain.BaseDirectory,老实说,从实际角度来看,我不知道这些差异。