c# - PowerShell 是否编译脚本?

标签 c# .net debugging powershell cil

假设我有一个简单的 PowerShell 脚本:

1..3 | Write-Host 
  • PowerShell 如何处理它?
  • 它是构建内存中的程序集还是一些临时的 .dll 文件?
  • 我可以使用一些工具(例如 ILSpy、VS、WinDbg)检查这个程序集和 MSIL 吗?
  • PowerShell 是否以相同的方式处理文件脚本和 REPL 命令行输入(即编译/解释)?
  • 我可以将此编译后的程序集与 C# 和其他 .Net 语言一起使用吗?
  • PS 脚本可以编译成原生二进制代码吗?

最佳答案

PowerShell V2 和更早版本从不编译脚本,它总是通过解析树中的虚拟“eval”方法进行解释。

PowerShell V3 及更高版本将解析树(AST)编译为 LINQ 表达式树,然后将其编译为 bytecode ,然后进行解释。

如果脚本执行16次,则脚本为JIT - 在后台编译,一旦JIT编译完成,解释后的代码将不会被使用。这同样适用于循环:如果循环迭代 16 次,则循环体将被 JIT 编译,并且循环体将尽早从解释转换为 JIT 编译。

许多操作,如访问成员或调用 C# 方法,总是在小型动态方法中进行 JIT 编译。这些动态站点针对 PowerShell 的动态特性进行了优化,以适应不同类型的按需输入。

JIT 编译的代码托管在“匿名方法”程序集中,无法保存。用WinDbg , 你可以反汇编 IL生成的代码。

将编译后的 IL 代码保存为 DLL 不太可能,因为生成的代码依赖于事件对象。从技术上讲,PowerShell 可以生成可以保存为 DLL 的代码,但尚未实现。

脚本和 REPL(交互式命令提示符)的工作方式完全相同。

请注意,如果 PowerShell 确实生成了程序集,它仍然需要安装编译脚本的 PowerShell 版本,您无法生成完全可移植的 exe。

从其他语言调用 PowerShell 脚本会有些困难和笨拙,因为有几个因素 - 主要是流水线和参数绑定(bind) - 与普通方法调度有些不同。

您可以在 C# 中使用从 PowerShell 脚本返回的对象。从 V3 开始,如果您在 C# 中使用 dynamic 关键字,您可以在 PSObject 上访问属性、调用脚本方法等。例如,就像您对任何其他对象所做的那样。在 V3 之前,您必须使用像 psobj.Properties['SomeProperty'] 这样的 API。

关于c# - PowerShell 是否编译脚本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34202462/

相关文章:

c# - 单击 MVC 中的按钮时如何避免回发

c++ - 如何使用 windbg "dt"命令从命名空间污染的内存转储中获取信息

c# - 有没有更快的方法来调试 ObjectARX 应用程序?

javascript - 如何将文件上传选择插入到 GridView 中,然后添加新行?

.net - Type.GetInterface 和嵌套类型

debugging - GDB中调试过程中的asm代码从何而来?

c# - 如何在同一行中获取用户输入?

c# - Microsoft.Bot.Schema.ErrorResponseException : Operation returned an invalid status code 'BadRequest'

c# - 使用 C# HttpClient API 和 postman 测试的区别?客户端调用适用于 postman ,但不适用于 C# httpClient getAsync

.net - ParamArray 不适用于 COM