【问题标题】:What's the best way to get the directory from which an assembly is executing获取正在执行程序集的目录的最佳方法是什么
【发布时间】:2010-09-20 04:31:35
【问题描述】:

对于我的应用程序,我将一些配置文件与程序集(exe)一起存储在 xml 中,以及用于处理目的的其他临时文件。

我发现了".\\"Application.StartupPath 的一些怪癖。

我一直在用

String configPath = ".\\config.xml";

在我调用OpenFIleDialog 打开其他文件夹中的一些文件之前,它工作正常,上面的语句失败了。显然“.\”指的是“CurrentDirectory”,每次我们浏览到另一个文件夹时都会改变。

在某些时候,我正在使用

String configPath = Path.Combine(Application.StartupPath + "config.xml");

在某些时候,当我需要使用 Process.Start() 从另一个文件夹执行此程序集时,事情开始分崩离析。显然工作目录设置不正确,Application.StartupPath 实际上指的是工作目录,而不是我假设的程序集正在执行的目录。所以我不得不求助于使用 ProcessInfo 将工作目录设置为程序集的目录。我在写 VSTO 时也遇到过这个问题。

所以,我的问题是,在没有我刚才提到的那些怪癖(或误解)的情况下,获取程序集正在执行的当前目录的最佳、最简单和最可靠的方法是什么?

编辑:我的意思是获取程序集所在的目录

编辑:根据AppDomain.BaseDirectory 上的 MSDN,它似乎可以在运行时进行更改,这是我不想要的(只是为了澄清,不是我不想允许更改 BaseDirectory,而是,当我在不确定是否已更改的情况下检索它时)

编辑:我注意到一个相关问题发布得更早。 What would cause the current directory of an executing app to change?

谢谢大家的回答。

【问题讨论】:

    标签: .net directory


    【解决方案1】:

    您想要实际的工作目录,还是包含程序集的目录?不完全清楚。

    Environment.CurrentDirectory 如果你想要工作目录,或者Path.GetDirectoryName(typeof(Foo).Assembly.ManifestModule.FullyQualifiedName) 来查找程序集的位置(或者至少是它的清单模块,在几乎所有情况下都是一样的)。

    【讨论】:

    • 如果在打开文件对话框(Winforms + WPF)的应用程序中使用Environment.CurrentDirectory,请小心,因为只是浏览到不同的目录会改变Environment.CurrentDirectory
    【解决方案2】:

    还有,

    System.Reflection.Assembly.GetExecutingAssembly().CodeBase
    

    【讨论】:

    • @tafa,打败我吧。 :) @Jon,也可以试试 System.Reflection.Assembly.GetExecutingAssembly().Location
    • 这两者都不是实际要求的答案。 Robinkor 的答案更完整。
    【解决方案3】:

    怎么样

    string currentAssemblyFile = System.Reflection.Assembly.GetExecutingAssembly().Location;
    

    然后从那里弄清楚......

    【讨论】:

      【解决方案4】:
      System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location))
      

      【讨论】:

      • 这种方法是否涉及反射?在性能影响方面?
      • 我不确定“反射”和“性能影响”之间是否存在 1:1 的相关性;它在 Reflection 命名空间中,但实际上并没有反映到程序集中——它使用的是它已经知道的元数据。
      • 是的...只需要像这样进行一次调用,就可以看到它会占用您所有的 CPU 周期,并将您的 Xeon Octa-core 变成 HP12c。因为任何人都知道反射是撒旦的产物,并且代表了世界上所有的一切都是真正的邪恶(这个名字归功于 Scott Hanselman :))
      【解决方案5】:

      我会从以下link 尝试这样的事情:

      string path;
      path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase );
      MessageBox.Show( path );
      

      【讨论】:

        【解决方案6】:

        短一点:

        AppDomain.Current.BaseDirectory
        

        【讨论】:

        • 应该是 AppDomain.CurrentDomain.BaseDirectory 而不是 AppDomain.Current.BaseDirectory。
        【解决方案7】:

        试试下面的实现。 CodeBase 属性是获取位置的最可靠方法,然后其余代码将其转换为标准 Windows 格式(而不是 URI)。

        static public string AssemblyLoadDirectory
        {
            get
            {
                string codeBase = Assembly.GetCallingAssembly().CodeBase;
                UriBuilder uri = new UriBuilder(codeBase);
                string path = Uri.UnescapeDataString(uri.Path);
                return Path.GetDirectoryName(path);
            }
        }
        

        【讨论】:

        • 如果路径中有哈希标记,您的解决方案将不起作用。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-04
        • 2017-10-27
        • 2012-04-17
        • 2020-09-25
        相关资源
        最近更新 更多