通过Start-Job调用脚本时$PSScriptRoot获取DLL路径失效问题
问题原因与解决方案
核心问题
用Start-Job启动后台作业时,作业进程的运行环境和直接执行脚本的环境存在差异:
- 直接运行第一个脚本时,
$PSScriptRoot会正确指向脚本所在的目录,因此拼接的dll路径有效。 - 但通过
Start-Job调用时,后台作业会启动全新的PowerShell进程,此时$PSScriptRoot的值并非原脚本的实际目录(通常是后台进程的默认工作目录,比如C:\Users\<用户名>\Documents),导致拼接出来的dll路径错误,脚本因找不到dll文件而卡住无响应。
解决方法
方法一:传递脚本路径作为参数
- 修改第一个脚本(1st ps1),添加参数接收原脚本所在目录:
param([string]$ScriptDir) # 用传递的目录拼接dll路径 $dll = Join-Path $ScriptDir 'Mydll.dll' Write-Host $dll -foreground Green $code = @" Some code that works "@ Add-Type -TypeDefinition $code -Language CSharp -ReferencedAssemblies $dll [System.Reflection.Assembly]::LoadFrom($dll) [HelloWorld.Program]::Main()
- 修改第二个脚本(2nd ps1),启动作业时传递当前脚本的目录:
$job = Start-Job -FilePath "Myps1.ps1" -Name "aaa" -ArgumentList $PSScriptRoot $dll = $PSScriptRoot+'\Mydll.dll' Write-Host $dll -foreground Yellow Start-Sleep 5 $JobStatus = $job.State Write-Host $job.State -foreground Yellow if ($JobStatus -like "Running") { Write-Host "Gresit" -foreground Red } else { Write-Host "Corect" -foreground Green }
方法二:在第一个脚本中直接获取自身路径
无需修改第二个脚本,直接调整第一个脚本中获取dll路径的逻辑:
# 获取当前脚本的完整路径,再提取所在目录 $scriptFullPath = $MyInvocation.MyCommand.Definition $scriptDir = Split-Path -Parent $scriptFullPath $dll = Join-Path $scriptDir 'Mydll.dll' Write-Host $dll -foreground Green $code = @" Some code that works "@ Add-Type -TypeDefinition $code -Language CSharp -ReferencedAssemblies $dll [System.Reflection.Assembly]::LoadFrom($dll) [HelloWorld.Program]::Main()
补充说明
注意检查dll文件名是否一致:你第二个脚本中写的是Mydll.dll,但第一个脚本原代码是\dll,这里可能是笔误,需要确保路径拼接后的文件名与实际dll文件名完全匹配。
内容的提问来源于stack exchange,提问作者Anne Marie
相关产品推荐
相关产品推荐

