C#编写的PowerShell模块中AppContext.BaseDirectory返回异常路径问题
问题分析与解决方案
为什么PowerShell环境下路径不符?
PowerShell作为.NET程序的宿主进程,加载你的MyModule.dll时,.NET的AppContext.BaseDirectory会指向宿主的运行目录——也就是PowerShell的安装目录(即$PSHOME),而非模块DLL的实际所在目录。
这是因为默认情况下,.NET程序集的上下文会继承自宿主进程:控制台应用、WinUI3这类自托管.NET应用的宿主就是自身,所以AppContext.BaseDirectory指向自身可执行文件目录;而PowerShell自身的运行环境以$PSHOME为基准目录,你的模块DLL是被PowerShell进程加载的,自然继承了这个上下文。
解决方法
方案1:通过程序集自身位置定位Assets目录
直接在C#代码中获取当前DLL的物理路径,再拼接Assets目录,这是最可靠的方法,不受宿主进程影响:
using System.Reflection; using System.IO; // 获取当前程序集所在目录 var assemblyDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); // 拼接Assets目录的完整路径 var assetsFullPath = Path.Combine(assemblyDirectory, "Assets");
方案2:在PowerShell脚本中传递模块根路径
在MyModule.psm1中先获取模块的根目录,再通过环境变量或方法参数传递给C#逻辑:
- 在
MyModule.psm1中获取并传递路径:
# 获取当前模块的根目录 $moduleRoot = $PSScriptRoot # 设置环境变量供C#代码读取 $env:MYMODULE_ROOT = $moduleRoot
- 在C#代码中读取环境变量:
using System; using System.IO; var moduleRoot = Environment.GetEnvironmentVariable("MYMODULE_ROOT"); var assetsFullPath = Path.Combine(moduleRoot, "Assets");
方案3:使用程序集加载上下文(进阶)
如果你的模块依赖复杂的资源加载逻辑,可以考虑创建独立的程序集加载上下文,确保资源查找路径指向模块目录,但这种方法实现复杂度较高,一般前两种方案即可满足需求。
内容的提问来源于stack exchange,提问作者Petr
相关产品推荐
相关产品推荐

