什么是确定应用程序根目录的最佳方法?

61

我需要获取应用程序根目录中的所有dll文件。最好的方法是什么?

string root = Application.StartupPath;

或者,

string root = new FileInfo(Assembly.GetExecutingAssembly().Location).FullName;

之后,

Directory.GetFiles(root, "*.dll");

哪种方式更好?还有更好的方式吗?

5个回答

87

AppDomain.CurrentDomain.BaseDirectory是我常用的方式。

然而:

Application.StartupPath获取你的可执行文件所在目录

AppDomain.BaseDirectory获取解析程序集的目录

由于它们可能不同,除非您关心程序集的解析,否则可能需要使用Application.StartupPath。


10
如果在 exe 快捷方式中设置了“工作目录”,或者进程是从其他应用程序启动的,那么 Application.StartupPath 将受到影响。我直到很晚才意识到这一点,这让我花费了数天不眠之夜来排除问题。 - faulty

26

这得看情况。如果你想要启动应用程序的 EXE 目录,那么你的两个示例都可以工作。但请记住,.NET 非常灵活,可能会有另一个应用程序链接到你的 EXE 并调用它,可能是从另一个目录中调用。

虽然这种情况不经常发生,如果确实发生了,你可能已经写了出来,但这是一种可能性。因此,我更喜欢指定我感兴趣的程序集,并从中获取目录。然后我就知道我正在获取与该特定程序集相同目录中的所有 DLL。例如,如果你有一个名为 MyApp.exe 的应用程序,并在其中有一个类 MyApp.MyClass,那么你应该这样做:

string root = string.Empty;
Assembly ass = Assembly.GetAssembly( typeof( MyApp.MyClass ) );
if ( ass != null )
{
   root = ass.Location;
}

36
我特别喜欢确认我的屁股位置;D - Rob Prouse
2
我假装认为变量“ass”代表汇编语言单词“Lol”。 - Chutipong Roobklom
我猜这个笑话一定是在2016年12月9日的飞机上讲的。 - jamheadart

8
这是一个老问题,但我经常使用以下方法:

这是一个老问题,但我一直使用以下方法:

Environment.CurrentDirectory = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);

然而,从这里提供的解决方案来看,我认为需要进行一些简单的测试:

var r = new List<long>();
var s = Stopwatch.StartNew();

s.Restart();
string root1 = Application.StartupPath;
r.Add(s.ElapsedTicks);

s.Restart();
string root2 = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
r.Add(s.ElapsedTicks);

s.Restart();
string root3 = Path.GetDirectoryName(new FileInfo(Assembly.GetExecutingAssembly().Location).FullName);
r.Add(s.ElapsedTicks);

s.Restart();
string root4 = AppDomain.CurrentDomain.BaseDirectory;
r.Add(s.ElapsedTicks);

s.Restart();
string root5 = Path.GetDirectoryName(Assembly.GetAssembly( typeof( Form1 ) ).Location);
r.Add(s.ElapsedTicks);

所得出的结果如下:

  • 49
  • 306
  • 166
  • 26
  • 201

看起来AppDomain.CurrentDomain.BaseDirectory是正确的方式。


1
如果您想获取应用程序根文件夹路径,请使用以下代码示例。
string path =new DirectoryInfo(Environment.CurrentDirectory).Parent.Parent.FullName

1
我不认为这就是 OP 所指的根目录,虽然五年前确实是这样,所以很难确定。 - Rawling
我不知道那个答案是否与问题相关,但它解决了我的问题。 - Marcelo
1
在开发环境中它可以正常工作,但在生产环境中却无法正常工作。 - Bimal Das
System.Environment.CurrentDirectory,以防其他人想知道它来自哪个库。 - Eric Milliot-Martinez

0

我使用

Path.GetDirectoryName(new Uri(Assembly.GetEntryAssembly().CodeBase).LocalPath)

如果你使用了影子复制,那么Assembly.Location将指向影子副本,因此使用CodeBase是一个更好的选择,但CodeBase是一个Url。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接