【问题标题】:Best way to get application folder path获取应用程序文件夹路径的最佳方法
【发布时间】:2011-08-27 20:00:01
【问题描述】:

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

  1. Application.StartupPath
  2. System.IO.Path.GetDirectoryName( System.Reflection.Assembly.GetExecutingAssembly().Location)
  3. AppDomain.CurrentDomain.BaseDirectory
  4. System.IO.Directory.GetCurrentDirectory()
  5. Environment.CurrentDirectory
  6. System.IO.Path.GetDirectoryName( System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase)
  7. 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

标签: c# .net


【解决方案1】:

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

Application.StartupPath

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

System.IO.Directory.GetCurrentDirectory()

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

【讨论】:

  • 请不要使用GetCurrentDirectory(),因为喜欢从不同的路径运行东西! :(
  • @kayleeFrye_onDeck 你没有说明上一个问题的原因。
【解决方案2】:

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 32bit 中测试时,返回快捷方式开始的位置。
  • +1 @Joe 和对于 VSTO 文档级加载项,请参阅 THIS
  • 请注意,这会返回一个末尾带有反斜杠的路径。这导致我在格式化字符串并将结果作为进程参数传递时出现问题。
  • @avenmore - 如果您正在格式化字符串以构建路径,请考虑改用 Path.Combine。这将为您处理尾随反斜杠。
  • 这是在 VS 2017 中为我返回 bin/debug 文件夹,而不是根目录。
【解决方案3】:

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

HttpContext.Current.Server.MapPath();

System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;

Above code description

【讨论】:

    【解决方案4】:
    1. Application.StartupPathand 7. System.IO.Path.GetDirectoryName(Application.ExecutablePath) - 仅适用于 Windows Forms application

    2. 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" 这是你正在运行的页面所在的位置。

    3. AppDomain.CurrentDomain.BaseDirectory 用于 Web 应用程序可能很有用,并且会返回类似 "C:\\hg\\Services\\Services\\Services.Website\\" 的内容,它是基本目录,非常有用。

    4. System.IO.Directory.GetCurrentDirectory() 和 5.Environment.CurrentDirectory

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

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

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

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

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

    【讨论】:

    • 相当肯定想要“当前文件夹”无论如何只与非网络应用程序相关......
    • 这就是答案。
    【解决方案5】:

    我在实际登录的用户的会话中通过 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
    

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

    【讨论】:

    • 非常相关的答案。很多人忘记了“工作目录”!=“程序目录”。
    【解决方案6】:

    这个我用过成功

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

    即使在 linqpad. 内部也可以使用

    【讨论】:

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

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

    【讨论】:

      【解决方案8】:

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

      1. System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase 会给你bin文件夹
      2. Directory.GetCurrentDirectory() 在 .Net Core 上运行良好,但在 .Net 上运行良好,并且会为您提供项目的根目录
      3. System.AppContext.BaseDirectoryAppDomain.CurrentDomain.BaseDirectory 在 .Net 中运行良好,但在 .Net 核心中运行良好,并且会为您提供项目的根目录

      在一个应该以 .Net 和 .Net 核心为目标的类库中,我检查托管该库的框架并选择其中一个。

      【讨论】:

      • Re "会给你项目的根目录",不,它给出的是当前目录,可以是任何目录
      【解决方案9】:

      如果知道要获取根目录:

      string rootPath = Path.GetPathRoot(Application.StartupPath)
      

      【讨论】:

        【解决方案10】:

        根目录:

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

        【讨论】:

        • 这似乎是获取当前工作目录,虽然有时可能有用,但绝对不能保证是EXE路径。
        【解决方案11】:

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

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

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

        小心GetExecutingAssembly(),命名让我感到困惑,因为我预计会得到.exe,但它返回.dll.exe,代码所在的位置,所以如果是@ 987654332@ 放在库中它返回库。

        【讨论】:

          猜你喜欢
          • 2010-09-23
          • 2016-12-12
          • 2019-02-08
          • 1970-01-01
          • 2012-01-15
          • 1970-01-01
          • 2021-10-24
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多