如何判断PowerShell模块函数调用来源:.NET/C#应用还是命令行?
嘿,针对你在PowerShell v5 + .NET 4.5.x环境下要判断模块函数调用来源的需求,我整理了几个实用的方案,分场景给你拆解清楚:
一、区分C#应用调用 vs 命令行直接调用
最可靠的方式是检查当前PowerShell进程的父进程,因为C#应用无论是直接启动PowerShell进程,还是通过System.Management.Automation.PowerShell类调用脚本,当前PS进程的父进程都会是你的C#应用程序;而命令行调用时,父进程就是powershell.exe(PSv5的主进程)。
给你写个现成的函数示例:
function Get-CallSourceCategory { # 获取当前PS进程的父进程ID $parentProcId = (Get-CimInstance Win32_Process -Filter "ProcessId = $PID").ParentProcessId # 获取父进程名称 $parentProcName = (Get-Process -Id $parentProcId -ErrorAction SilentlyContinue).ProcessName if ($parentProcName -ne 'powershell') { # 父进程不是powershell.exe,说明是外部C#应用调用 return 'CSharpApplication' } else { # 父进程是powershell.exe,说明是命令行直接调用 return 'CommandLine' } }
注意:如果你的C#应用是通过其他中间进程(比如某个调度工具)启动PS的,需要调整父进程的判断逻辑,比如检查父进程的名称是否匹配你的生产/测试工具名。
二、区分生产环境C#应用 vs 命令行单元测试场景
这一步需要你在单元测试场景里主动添加标识,因为命令行本身没法区分普通调用和单元测试调用,常见的两种方案:
方案1:通过自定义环境变量标记
在启动单元测试的PowerShell会话时,设置一个专属环境变量,生产环境不设置或设置不同值:
# 单元测试启动PS时先执行: $env:PS_RUN_CONTEXT = 'UnitTest'
然后在你的模块函数里检查这个变量:
function Get-CallScenario { # 先判断是否是单元测试场景 if ($env:PS_RUN_CONTEXT -eq 'UnitTest') { return 'UnitTest' } # 再判断生产C#应用还是普通命令行 $parentProcId = (Get-CimInstance Win32_Process -Filter "ProcessId = $PID").ParentProcessId $parentProcName = (Get-Process -Id $parentProcId -ErrorAction SilentlyContinue).ProcessName if ($parentProcName -ne 'powershell') { return 'ProductionCSharp' } else { return 'CommandLine' } }
方案2:通过隐藏参数传递标识
在你的模块函数里加一个隐藏参数,单元测试调用时传入$true,生产环境调用时不传或传$false:
function Your-TargetModuleFunction { [CmdletBinding()] param( # 隐藏参数,仅用于单元测试标记 [Parameter(DontShow)] [bool]$IsUnitTest = $false ) if ($IsUnitTest) { Write-Verbose "当前为单元测试场景调用" # 执行单元测试专属逻辑 } else { $parentProcId = (Get-CimInstance Win32_Process -Filter "ProcessId = $PID").ParentProcessId $parentProcName = (Get-Process -Id $parentProcId -ErrorAction SilentlyContinue).ProcessName if ($parentProcName -ne 'powershell') { Write-Verbose "当前为生产环境C#应用调用" # 执行生产环境逻辑 } else { Write-Verbose "当前为命令行直接调用" # 执行命令行逻辑 } } } # 单元测试调用示例: Your-TargetModuleFunction -IsUnitTest $true -Verbose
小提示:方案2比环境变量更可靠,因为环境变量可能在会话中被意外覆盖,而参数传递是显式的,更适合测试场景的隔离。
内容的提问来源于stack exchange,提问作者jalopy67
相关产品推荐
相关产品推荐

