ChatGPT解决这个技术问题 Extra ChatGPT

获取应用程序文件夹路径的最佳方法

我看到有一些方法可以获取应用程序文件夹路径:

Application.StartupPath System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) AppDomain.CurrentDomain.BaseDirectory System.IO.Directory.GetCurrentDirectory() Environment.CurrentDirectory System.IO.Path.GetDirectoryName(System. Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase) System.IO.Path.GetDirectory(Application.ExecutablePath)

根据情况,最好的方法是什么?

为什么我们有很多方法可以获取应用程序的路径。我认为每种方式都有原因。
#6 中有一个错误:应该是:System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase), System.IO.Path.GetDirectoryName(Application.ExecutablePath)
#6 万岁,当我在一个 Web 项目中时,我不希望 IoC 加载库中的 Server.MapPath 逻辑本质上不是特定于 Web 的
我们现在有了可靠的 IHostEnvironment.ContentRootPath,通过注入的 IHostEnvironment 依赖项(其中包含其他有用的东西)进行访问。
还有Process.GetCurrentProcess().MainModule.FileName

J
Joe

AppDomain.CurrentDomain.BaseDirectory 对于访问位置与应用程序安装目录相关的文件可能最有用。

在 ASP.NET 应用程序中,这将是应用程序根目录,而不是 bin 子文件夹 - 这可能是您通常想要的。在客户端应用程序中,它将是包含主要可执行文件的目录。

在 VSTO 2005 应用程序中,它将是包含应用程序的 VSTO 托管程序集的目录,而不是 Excel 可执行文件的路径。

其他人可能会根据您的环境返回不同的目录 - 例如请参阅@Vimvq1987 的答案。

CodeBase 是找到文件的位置,可以是一个以 http:// 开头的 URL。在这种情况下,Location 可能是程序集下载缓存。不保证为 GAC 中的程序集设置 CodeBase。

更新 如今(.NET Core、.NET Standard 1.3+ 或 .NET Framework 4.6+)最好使用 AppContext.BaseDirectory 而不是 AppDomain.CurrentDomain.BaseDirectory。两者是等价的,但 multiple AppDomains are no longer supported


在 Windows XP 32 位中进行测试时,它会返回快捷方式开始的位置。
+1 @Joe,对于 VSTO 文档级插件,请参阅 THIS
请注意,这将返回最后带有反斜杠的路径。在格式化字符串并将结果作为进程参数传递时,这给我带来了问题。
@avenmore - 如果您正在格式化字符串以构建路径,请考虑使用 Path.Combine 代替。这将为您处理尾随反斜杠。
这是在 VS 2017 中为我返回 bin/debug 文件夹,而不是根目录。
l
legend1337

Application.StartupPathand 7. System.IO.Path.GetDirectoryName(Application.ExecutablePath) - 仅适用于 Windows 窗体应用程序 System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) 将给你类似的东西:“C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\Temporary ASP.NET Files\\legal-services\\e84f415e\\96c98009\\assembly\\dl3\\ 42aaba80\\bcf9fd83_4b63d101" 这是您正在运行的页面所在的位置。 Web 应用程序的 AppDomain.CurrentDomain.BaseDirectory 可能很有用,它会返回类似 "C:\\hg\\Services\\Services\\Services.Website\\" 的基本目录,非常有用。 System.IO.Directory.GetCurrentDirectory() 和 5. Environment.CurrentDirectory

将为您提供进程被触发的位置 - 因此对于从 Visual Studio 以调试模式运行的 Web 应用程序,例如 "C:\\Program Files (x86)\\IIS Express"

System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase)

将为您提供运行代码的 .dll 所在的位置,对于可能是 "file:\\C:\\hg\\Services\\Services\\Services.Website\\bin" 的网络应用程序

现在,例如控制台应用程序点 2-6 将是 .exe 文件所在的目录。

希望这可以节省您一些时间。


相当肯定想要“当前文件夹”无论如何只与非网络应用程序相关......
这就是答案。
P
Peter Mortensen

请注意,并非所有这些方法都会返回相同的值。在某些情况下,它们可以返回相同的值,但要小心,它们的目的是不同的:

Application.StartupPath

返回 StartupPath 参数(可以在运行应用程序时设置)

System.IO.Directory.GetCurrentDirectory()

返回当前目录,它可能是也可能不是应用程序所在的文件夹。 Environment.CurrentDirectory 也是如此。如果您在 DLL 文件中使用它,它将返回进程运行的路径(在 ASP.NET 中尤其如此)。


请不要使用 GetCurrentDirectory(),因为喜欢从不同的路径运行东西! :(
@kayleeFrye_onDeck 您没有说明上一个问题的原因。
P
Peter Mortensen

对于一个web应用来说,要获取当前web应用的根目录,一般通过web页面调用当前传入的请求:

HttpContext.Current.Server.MapPath();

System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;

Above code description


B
Bhargav Rao

我在实际登录的用户的会话中通过 Win32 API 从 Windows 服务启动了一个进程(在任务管理器会话 1 而不是 0 中)。在此我们可以了解,哪个变量是最好的。

对于上述问题的所有 7 个案例,结果如下:

Path1: C:\Program Files (x86)\MyProgram
Path2: C:\Program Files (x86)\MyProgram
Path3: C:\Program Files (x86)\MyProgram\
Path4: C:\Windows\system32
Path5: C:\Windows\system32
Path6: file:\C:\Program Files (x86)\MyProgram
Path7: C:\Program Files (x86)\MyProgram

当您为您的案例搜索最佳变量时,可能对你们中的一些人有帮助,做同样的事情。


非常相关的答案。很多人忘记了“工作目录”!=“程序目录”。
A
Ahmed Mansour

根据我的经验,最好的方法是结合这些。

System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase 将为您提供 bin 文件夹 Directory.GetCurrentDirectory() 在 .Net Core 但不是 .Net 上工作正常,并将为您提供项目 System.AppContext 的根目录。 BaseDirectory 和 AppDomain.CurrentDomain.BaseDirectory 在 .Net 中运行良好,但在 .Net 核心中运行良好,将为您提供项目的根目录

在应该针对.Net 和.Net 核心的类库中,我检查哪个框架托管该库并选择其中一个。


重新“会给你项目的根目录”,不,它给了当前目录,可以是任何目录
C
Camilo Estevez

我已经成功使用了这个

System.IO.Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName)

它甚至可以在 linqpad. 内使用


这缺少 GetCurrentProcess 的左括号。顺便说一句,它在我的 .net 核心项目中评估为 C:\Program Files\dotnet,同时在 Visual Studio 中进行调试,因为那是 dotnet.exe 所在的位置
R
Rekshino

为了获得简单桌面应用程序的 .exe 路径,我使用

Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)

它返回 .exe 的路径。
另外请注意,对于多个域,默认域的 .exe 将被返回,或者 ExecuteAssembly(String) 的第一次调用执行的 .exe 并且 如果条目不受管理,则将返回 null

小心 GetExecutingAssembly(),命名让我感到困惑,因为我希望得到 .exe,但它返回放置代码的 .dll.exe,所以如果是 GetExecutingAssembly() < strong>放置在库中它返回库。


A
Alparslan ŞEN

根目录:

DriveInfo cDrive = new DriveInfo(System.Environment.CurrentDirectory);
var driverPath = cDrive.RootDirectory;

这似乎获取了当前的工作目录,虽然有时这可能很有用,但绝对不能保证它是 EXE 路径。
A
Alparslan ŞEN

如果您知道获取根目录:

string rootPath = Path.GetPathRoot(Application.StartupPath)

K
Kiran Shahi

这个 System.IO.Path.GetDirectory(Application.ExecutablePath) 更改为 System.IO.Path.GetDirectoryName(Application.ExecutablePath)