Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
182 views
in Technique[技术] by (71.8m points)

c# - Does PowerShell compile scripts?

Suppose I have a simple PowerShell script:

1..3 | Write-Host 
  • How does PowerShell process it?
  • Does it build in-memory assembly or some temporary .dll file?
  • Can I examine this assembly and MSIL using some tools (e.g. ILSpy, VS, WinDbg)?
  • Does PowerShell treat processing of file scripts and REPL command line input the same way (i.e. both compiled / interpreted)?
  • Can I use this compiled assembly together with C# and other .Net languages?
  • Can the PS script be compiled to a native binary code?
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

PowerShell V2 and earlier never compiled a script, it was always interpreted via virtual "eval" methods in the parse tree.

PowerShell V3 and later compile the parse tree (the AST) to a LINQ expression tree, which is then compiled to a bytecode, which is then interpreted.

If the script is executed 16 times, the script is JIT-compiled in the background, and as soon as the JIT compilation completes, the interpreted code will not be used. The same applies to loops: if a loop iterates 16 times, the loop body will be JIT-compiled and the loop body will switch from interpreted to JIT-compiled at the earliest possible time.

Many operations like accessing a member or invoking a C# method are always JIT-compiled in small dynamic methods. These dynamic sites are optimized for the dynamic nature of PowerShell, adapting to differing kinds of input on demand.

The JIT-compiled code is hosted in the "anonymous methods" assembly and cannot be saved. With WinDbg, you could disassemble the IL of the generated code.

Saving the compiled IL code as a DLL is not quite possible, because the generated code depends on live objects. It is technically possible for PowerShell to generate code that could be saved as a DLL, but that is not implemented.

Scripts and the REPL (interactive command prompt) work exactly the same.

Note that if PowerShell did actually generate an assembly, it would still require the version of PowerShell that compiled the script to be installed, you could not produce a fully portable exe.

It would be somewhat difficult and awkward to call PowerShell scripts from other languages because several factors - primarily pipelining and parameter binding - differ somewhat from normal method dispatch.

You can use objects returned from PowerShell scripts in C#. Starting in V3, if you use the dynamic keyword in C#, you can access properties, call script methods, etc. on a PSObject instance, just like you would on any other object. Before V3, you had to use an API like psobj.Properties['SomeProperty'].


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...