Компилирует ли PowerShell скрипты?

Предположим, у меня есть простой скрипт PowerShell:

1..3 | Write-Host 
  • как PowerShell обрабатывает его?
  • создает ли он сборку в памяти или какую-то временную .dll файл?
  • могу ли я изучить эту сборку и MSIL с помощью некоторых инструментов (например, ILSpy, VS, WinDbg)?
  • PowerShell обрабатывает обработку файловых скриптов и ввод командной строки REPL одинаково (т. е. как скомпилированные, так и интерпретированные)?
  • могу ли я использовать эту скомпилированную сборку вместе с C# и другими языками .Net?
  • можно ли скомпилировать скрипт PS в собственный двоичный код?

1 ответов


PowerShell V2 и ранее никогда не компилировал скрипт, он всегда интерпретировался с помощью виртуальных методов "eval" в дереве синтаксического анализа.

PowerShell V3 и более поздняя компиляция дерева синтаксического анализа (АСТ) в дерево выражений LINQ, которое затем компилируется в код, который затем интерпретируется.

Если скрипт выполняется 16 раз, то скрипт JIT-скомпилирован в фоновом режиме, и как только компиляция JIT завершится, интерпретируемый код не будет использоваться. То же самое относится и к циклам: если цикл повторяется 16 раз, тело цикла будет скомпилировано JIT, и тело цикла переключится с интерпретируемого на JIT-скомпилированное в кратчайшие сроки.

многие операции, такие как доступ к члену или вызов метода C#, всегда JIT-скомпилированы в небольших динамических методах. Эти динамические сайты оптимизированы для динамической природы PowerShell, адаптируясь к различным видам ввода по требованию.

В JIT-скомпилированный код размещается в сборке "анонимные методы" и не может быть сохранен. С WinDbg, вы можете разобрать IL сгенерированного кода.

сохранение скомпилированного кода IL как DLL не совсем возможно, потому что сгенерированный код зависит от живых объектов. Технически PowerShell может генерировать код, который может быть сохранен как DLL, но он не реализован.

скрипты и REPL (интерактивная командная строка) работа точно такая же.

обратите внимание, что если PowerShell действительно создает сборку, все равно потребуется версия PowerShell, которая скомпилировала скрипт для установки, вы не сможете создать полностью переносимый exe.

было бы несколько сложно и неудобно вызывать сценарии PowerShell с других языков, потому что несколько факторов-в первую очередь конвейеризация и привязка параметров - несколько отличаются от обычного метода отправки.

вы можете использовать объекты вернулся из сценариев PowerShell в C#. Начиная с V3, если вы используете dynamic ключевое слово в C#, вы можете получить доступ к свойствам, методам сценария вызова и т. д. на PSObject экземпляр, как и на любом другом объекте. До V3 вы должны были использовать API, как psobj.Properties['SomeProperty'].