You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在设计时获取C#类文件的父目录路径?

问题描述

技术开发环境

  • .NET Core 3.1
  • PostgreSQL 14.2(由Visual C++ build 1914编译,64位)
  • EntityFramework.Functions Version=1.5.0
  • Microsoft.EntityFrameworkCore.Design Version=5.0.17
  • Microsoft.EntityFrameworkCore.Tools Version=5.0.17
  • Npgsql.EntityFrameworkCore.PostgreSQL Version=5.0.10

场景与问题

C#代码文件JohnDoeCSharp.cs位于VisualStudioProjectDir\Migrations\1.0.5目录下,构造函数代码如下:

public class JohnDoeCSharp
{
    public JohnDoeCSharp()
    {
        
    }
}

希望在构造函数中获取父目录名称“1.0.5”,但使用以下代码返回的是运行时目录路径,无法满足需求:

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

string strWorkPath = System.IO.Path.GetDirectoryName(strExeFilePath);

需要获取设计时/编码时的目录路径值,该如何操作?


解决方案

编译后程序集的运行时路径与编码时的源文件目录完全分离,因此不能通过Assembly.GetExecutingAssembly().Location获取源文件目录。以下是两种可靠的实现方式:

1. 编译时常量注入源文件路径

在项目的.csproj文件中添加编译常量,直接将目标目录路径注入到代码中:

<PropertyGroup>
  <DefineConstants>$(DefineConstants);SOURCE_DIRECTORY=$(MSBuildThisFileDirectory)Migrations\1.0.5</DefineConstants>
</PropertyGroup>

之后在代码中直接使用该常量提取目录名称:

public class JohnDoeCSharp
{
    public JohnDoeCSharp()
    {
        string versionDir = System.IO.Path.GetFileName(SOURCE_DIRECTORY); // 得到"1.0.5"
    }
}

注意:若后续文件目录结构变动,需同步更新项目文件中的常量值。

2. 通过项目根目录动态推导(更灵活)

如果不想硬编码目录路径,可通过在项目根目录放置标记文件(如_ProjectRootMarker.txt),以此定位项目根目录后拼接目标路径:

public class JohnDoeCSharp
{
    public JohnDoeCSharp()
    {
        string currentDir = System.IO.Directory.GetCurrentDirectory();
        // 向上遍历直到找到项目根目录的标记文件
        while (!System.IO.File.Exists(System.IO.Path.Combine(currentDir, "_ProjectRootMarker.txt")))
        {
            currentDir = System.IO.Path.GetDirectoryName(currentDir);
            if (string.IsNullOrEmpty(currentDir)) break;
        }
        // 拼接得到目标目录并提取名称
        string targetDir = System.IO.Path.Combine(currentDir, "Migrations", "1.0.5");
        string versionDir = System.IO.Path.GetFileName(targetDir); // 得到"1.0.5"
    }
}

这种方式适配目录结构变动的场景,只需保证标记文件始终在项目根目录即可。

区分设计时与运行时环境

设计时(如EF迁移工具执行时)的当前目录通常为项目根目录,而运行时目录不同,可通过EF的设计时判断API区分:

using Microsoft.EntityFrameworkCore.Design;

public class JohnDoeCSharp
{
    public JohnDoeCSharp()
    {
        string rootDir;
        // 判断是否处于设计时环境
        if (DesignTimeServicesBuilder.IsDesignTime)
        {
            rootDir = System.IO.Directory.GetCurrentDirectory();
        }
        else
        {
            // 运行时使用程序集目录或其他配置逻辑
            rootDir = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
        }
        string targetDir = System.IO.Path.Combine(rootDir, "Migrations", "1.0.5");
        string versionDir = System.IO.Path.GetFileName(targetDir);
    }
}

内容的提问来源于stack exchange,提问作者crazyTech

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 02:45:45