1-й PS1:
#$dll = 'C:\Some\Path\To\dll'
$dll = $PSScriptRoot+'\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()
2-й PS1:
$job = Start-Job -FilePath "Myps1.ps1" -Name "aaa"
$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
}
Звоню на первый пс1 со 2-го пс1. Проблема возникает потому, что при вызове первого пс1 со 2-го, если я использую
$dll = 'C:\Some\Path\To\dll'
тогда программа работает. Но если я использую
$dll = $PSScriptRoot+'\dll'
тогда программа ничего не делает.
Излишне говорить, что если я вызову первый ps1, он будет работать с обеими версиями пути dll.
Я ожидаю, что это будет относительный путь к моему исходному файлу. при запуске он печатает правильный путь к моему PS1.
Можете ли вы показать буквальные значения $PSScriptRoot — текущие и ожидаемые? Помните, что люди, читающие ваш вопрос, не видят ваш экран, поэтому вам необходимо предоставить в своем вопросе конкретные технические подробности. даже если они кажутся вам очевидными
C:\Users\Admin\Documents\PowerShell Scripts
это значение $PSScriptRoot и значение ожидаемого пути.
В каждом отдельном случае $PSScriptRoot ведет себя очень хорошо.
Я знаю, что он работает правильно, потому что когда я запускаю первый скрипт сам по себе, он работает, но когда я запускаю его из второго сценария, он ничего не делает. Код С# ничего не делает :(
Вы имеете в виду, что значение $PSScriptRoot всегда правильное? Даже когда вы вызываете его из второго скрипта?
@OcasoProtal - я подозреваю, что $PSScriptRoot внутри сценария 1 равен $null или не определен при вызове его из Start-Job в сценарии 2, а ОП предоставляет неоднозначные факты - Start-Job запускает файл как блок сценария, а не сценарий, а блоки сценариев не $PSScriptRoot определены ...
спасибо, это очень помогло мне понять мою проблему. таким образом, обходным путем можно было бы отправить параметры в функцию, но это кажется таким трудным, особенно внутри Start-Job
Окасо Протал, да, я вот что имею в виду.





Так это твоя проблема...
$job = Start-Job -FilePath "Myps1.ps1" -Name "aaa"
Если вы посмотрите документацию по параметру -FilePathStart-Job, там написано:
При использовании этого параметра PowerShell преобразует содержимое указанного файла сценария в блок сценария и запускает блок сценария в качестве фонового задания.
Итак, ваш код эквивалентен:
$src = Get-Content "Myps1.ps1"
$sb = [scriptblock]::Create($src)
$job = Start-Job -ScriptBlock $sb -Name "aaa"
А если мы запустим почти идентичный пример с возможностью вырезания и вставки:
$src = @"
write-host "root = '$PSScriptRoot'"
"@
$sb = [scriptblock]::Create($src)
$job = Start-Job -ScriptBlock $sb -Name "aaa"
Wait-Job $job
Receive-Job $job
Мы видим следующий вывод:
root = ''
Это связано с тем, что $PSScriptRoot не определяется при запуске внутри ScriptBlock, а только при запуске как скрипт:
Содержит полный путь к родительскому каталогу исполняемого сценария.
В PowerShell 2.0 эта переменная действительна только в модулях сценариев (.psm1). Начиная с PowerShell 3.0, он действует во всех сценариях.
ScriptBlock — это объект в памяти, поэтому у него нет «родительского каталога», а создание ScriptBlock из содержимого файла не сохраняет путь к файлу в ScriptBlock, поэтому $PSScriptRoot не определен в обоих случаях.
Этот ответ дает более подробную информацию:
https://stackoverflow.com/a/72026978/3156906
Предлагаемый обходной путь — сделать вызов Start-Job простой оболочкой вокруг оператора вызова для вызова вашего сценария, поскольку тогда ваш сценарий выполняется как сценарий (а не блок сценария) и имеет доступ к автоматической переменной $PSScriptBlock. :
$sb = { & ".\first.ps1" }
$job = Start-Job -ScriptBlock $sb -Name "aaa"
$result = Wait-Job $job
Receive-Job $job
Таким образом, файл сценария запускается как сценарий, а не как блок сценария, и в результате ему доступна автоматическая переменная $PSScriptRoot, что приводит к следующему выводу:
C:\src\so\root\dll
большое спасибо. Теперь я намного лучше понимаю свою проблему <3
НП. не стесняйтесь отмечать как ответ, если это решит вашу проблему.
Каково значение
$PSScriptRootво втором скрипте (используйтеwrite-host “script root = ‘$PSScriptRoot’”, чтобы узнать) и какое оно должно быть, по вашему мнению?