【问题标题】:Better way to get the base directory?获取基本目录的更好方法?
【发布时间】:2010-07-02 05:47:20
【问题描述】:

我有这段代码来加载配置文件并读取所有值,它在运行应用程序时工作正常,但在团队城市当然会失败,因为 appdomain 的基本目录是构建脚本 (psake) 的启动位置。我知道我可以在执行测试之前将目录更改为构建目录,但我认为无论如何最好始终加载配置文件。

XDocument.Load(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, cfgFile));

还有其他方法可以获得始终有效的“BaseDirectory”吗?我也尝试了以下方法,结果相同:

string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase);
XDocument.Load(Path.Combine(path, cfgFile));

EDIT 1 问题如下。我的解决方案基目录是“C:\Project”,所有编译后的文件都复制到“C:\Project\build”。现在在 psake 构建脚本中,我有以下代码:

task Test -depends PrepareTests {
    try { 
        #$old = pwd
        #cd $build_dir
        &$mspec $mspec_projects --teamcity
        #cd $old
    }
    catch {
        &echo "Error starting test runner"
        Exit 1;
    }      
}

如您所见,我注释掉了目录的更改,这使得 BaseDirectory 成为构建文件/解决方案的位置,而不是构建目录,无论我如何尝试访问它。如果你问我,有点令人困惑。

更新我真的很想知道是否可以获取程序集的目录,而不管启动应用程序域的应用程序位于哪个目录。怎么样?

【问题讨论】:

  • “基本目录”是什么意思?与程序集相关的配置文件在哪里?如果配置文件与 DLL 位于同一目录中,则您的第二个示例应该可以工作...
  • 所以你要.exe所在的目录?
  • @craig - 是的,这就是我所追求的
  • 只是尝试从您的程序集中的一种类型中请求 CodeBase? IE。类似var path = typeof(SomeClassInMyAssembly).Assembly.CodeBase;?

标签: c# .net


【解决方案1】:

你的问题有点不清楚。我真的不知道这是不是你想要的。

我通常使用AppDomain.CurrentDomain.BaseDirectory

替代品

  • Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
  • Environment.CurrentDirectory

【讨论】:

  • 感谢您的建议,但结果相同。
【解决方案2】:

获取基目录的不同方法

  1. AppDomain.CurrentDomain.BaseDirectory

  2. Directory.GetCurrentDirectory() // 不保证在移动应用上工作

  3. Environment.CurrentDirectory // 这个调用Directory.GetCurrentDirectory()

  4. this.GetType().Assembly.Location // Assembly.location

  5. Application.StartupPath // 适用于 Windows 窗体应用程序

  6. Application.ExecutablePath // 同Application.StartupPath

【讨论】:

    【解决方案3】:
    string origAssemblyLocation = Assembly.GetExecutingAssembly().CodeBase;
    

    每个 MSDN:

    Assembly.CodeBase 属性

    获取程序集的位置为 原来指定

    【讨论】:

    • 我不得不删除 dll 的名称,但它确实让我知道了程序集在磁盘上的位置!
    • 注意,这会给出一个 uri 类型的字符串,即 file:///foo/bar/baz.DLL
    【解决方案4】:

    所以听起来/看起来您正在尝试获取程序集的配置文件。下面应该通过访问程序集的“位置”属性并使用它来检索配置路径来完成该任务:

    static string GetConfigFileByType(Type type)
    {
        Configuration config = 
            ConfigurationManager.OpenExeConfiguration(type.Assembly.Location);
    
        if (config.HasFile)
            return config.FilePath;
        throw new FileNotFoundException();
    }
    

    【讨论】:

      【解决方案5】:

      试试这个:

        Module[] modules = Assembly.GetExecutingAssembly().GetModules();
        return Path.GetDirectoryName(modules[0].FullyQualifiedName);
      

      【讨论】:

      • 谢谢我之前没试过。它仍然尝试在解决方案目录而不是构建目录中找到 xml 文件。
      • 您可以在复制后将程序集文件注册到构建目录中。
      【解决方案6】:

      您是否尝试过获取当前进程的文件名'MainModule

      System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName
      

      还是GetEntryAssembly()?

      System.Reflection.Assembly.GetEntryAssembly().Location
      

      【讨论】:

        【解决方案7】:

        我喜欢让我的类可配置——例如,它们将文件夹名称作为构造函数中的参数。 这使得使用不同的配置文件进行测试成为可能。

        在我们使用的测试代码中:

        TestContext.TestDeploymentDir
        

        这是 testrun 文件夹,用于测试运行的所有程序集连同测试部署项都复制到其中。我们将单元测试配置文件“部署”到测试运行文件夹 - 这可以在 Visual Studio 的 testrunco​​nfig 对话框中指定。

        对于我们的生产代码,我们通过

        Assembly.GetExecutingAssembly().Location
        

        到构造函数,这对我们有用。

        【讨论】:

        • "如果加载的文件被卷影复制,则位置是被卷影复制后的文件的位置。" / 在这种情况下,Location 属性不会向 OP 提供他所追求的内容。
        • 附带说明,如果您打算使用桌面网桥,这是最好的选择
        【解决方案8】:

        怎么样:

        Application.StartupPath;
        

        【讨论】:

          【解决方案9】:
          string baseDirectory=Application.StartupPath.Split(Path.DirectorySeparatorChar)[0];
          

          应用程序启动路径会返回exe保存的路径,我们用“\”分割,得到基目录为“C:”,例如,

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-04-07
            • 1970-01-01
            • 2016-01-07
            • 2020-03-19
            相关资源
            最近更新 更多