C#获取程序集关联文件 C#如何找到与DLL或EXE在同一目录的文件

来源:这里教程网 时间:2026-02-21 17:41:46 作者:

Assembly.GetExecutingAssembly().Location
获取当前程序集路径

很多开发者误以为

Assembly.GetExecutingAssembly().Location
返回的是“当前运行目录”,其实它返回的是该程序集(.dll 或 .exe)**在磁盘上的绝对路径**,包括文件名。这是定位同目录文件最可靠起点。

注意:

Location
在某些场景下可能为空(比如动态生成的程序集、部分 .NET Core/.NET 5+ 的 AOT 编译或反射加载的内存程序集),此时应改用
CodeBase
GetAssembly(typeof(...)).Location
配合已知类型。

示例:

string assemblyPath = Assembly.GetExecutingAssembly().Location;
string assemblyDir = Path.GetDirectoryName(assemblyPath); // 得到目录,不含文件名
string configPath = Path.Combine(assemblyDir, "config.json");

别用
Environment.CurrentDirectory
找同目录文件

Environment.CurrentDirectory
是进程当前工作目录,它可能被用户双击启动、命令行 cd 后执行、IDE 调试配置、甚至其他 DLL 显式调用
Directory.SetCurrentDirectory
修改 —— 完全不可控。

常见错误现象:调试时正常,发布后读不到文件;或者 Windows 服务中始终报

FileNotFoundException

除非你明确需要“工作目录语义”(如命令行工具处理相对路径参数),否则一律避免用它定位程序集关联文件。

处理 .NET Core / .NET 5+ 中的 PublishSingleFile 场景

启用

PublishSingleFile=true
后,
Location
指向的是临时解压目录(如
C:Users...AppDataLocalTemp.netMyApp...
),而非原始部署目录。此时同目录文件(如
readme.txt
)根本不在
Location
所指位置。

解决方案取决于你的部署方式:

若文件是必需资源,改用嵌入式资源(
EmbeddedResource
)并用
Assembly.GetManifestResourceStream
读取
若必须保留外部文件,发布时禁用
IncludeNativeLibrariesForSelfExtract
,或改用
CopyToPublishDirectory
并配合
AppContext.BaseDirectory
AppContext.BaseDirectory
在 SingleFile 下指向实际发布根目录(即包含 .exe 的那个文件夹),比
Location
更适合找“部署同级文件”

路径拼接务必用
Path.Combine
,别字符串拼接

手动拼接路径(如

dir + "\" + "file.txt"
)在 Linux/macOS 上直接失败,且易引入双反斜杠、末尾多余分隔符等错误。

正确做法永远是:

string dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string filePath = Path.Combine(dir, "data", "cache.bin"); // 自动适配路径分隔符

另外,检查文件是否存在再读取,避免静默失败:

if (File.Exists(filePath))
{
    var content = File.ReadAllText(filePath);
}
else
{
    // 记录警告或抛出有意义异常,而不是让后续逻辑空引用
}
真正容易被忽略的是:同一个程序集在不同加载上下文(如
AssemblyLoadContext
)中,
Location
可能不同;而插件式架构里,你拿到的“执行程序集”未必是你以为的那个 DLL —— 此时得用
typeof(YourKnownType).Assembly.Location
锁定目标。

相关推荐