2015-12-10 19 views
6

は、私は、単純なPowerShellスクリプトがあるとします。PowerShellはスクリプトをコンパイルしますか?

1..3 | Write-Host 
  • どのようにPowerShellプロセスそれ?
  • インメモリアセンブリまたは一時的な.dllファイルを作成しますか?
  • いくつかのツール(ILSpy、VS、WinDbgなど)を使用してこのアセンブリとMSILを調べることはできますか?
  • PowerShellは、ファイルスクリプトとREPLコマンドライン入力の処理を同じ方法で処理しますか(コンパイル/解釈の両方)ですか?
  • このコンパイルされたアセンブリをC#およびその他の.Net言語と共に使用できますか?
  • PSスクリプトをネイティブバイナリコードにコンパイルできますか?
+3

PowerShellはインタープリタ言語です(はい、V3 **内部キャッシュ**一部のIL生成)。このようなアセンブリがないと、他の.NET言語と一緒に使用することはできませんが、.NETアプリケーション内でPowerShellをホストすることもできます(何かを共有することもできます)。他の答えは、この結果です。キャッシュされたILを調べることについて...もちろん、ILSpyを使用してPSコードを検査し、WinDbgを使用して、あなたが望むほぼすべてを行うことができます。 –

+0

実行ファイルとしてPowerShellスクリプトを展開することを目標とする場合は、このプロジェクトを見てみましょう。https:// gallery.technet.microsoft.com/PS2EXE-Convert-PowerShell-9e4e07f1 –

答えて

9

PowerShell V2以前では、スクリプトをコンパイルしたことはなく、構文解析ツリーの仮想「eval」メソッドによって常に解釈されていました。

PowerShell V3以降では、構文解析ツリー(Ast)をLINQ式ツリーにコンパイルし、LINQ式ツリーをバイトコードにコンパイルしてバイトコードを解釈します。

スクリプトを16回実行すると、スクリプトはバックグラウンドでjitコンパイルされ、jitが完了するとすぐに解釈されたコードは使用されません。同じことがループにも適用されます。ループが16回反復されると、ループ本体はコンパイルされ、ループ本体は可能な限り早くコンパイルされた解釈から変換されます。

メンバーへのアクセスやC#メソッドの呼び出しなどの操作は、常に小さな動的メソッドでコンパイルされたjitです。これらの動的サイトは、PowerShellの動的性質に合わせて最適化されており、さまざまな種類のオンデマンド入力に対応しています。

jitコンパイルされたコードは、 "匿名メソッド"アセンブリでホストされており、保存することはできません。 windbgを使うと、生成されたコードのILを逆アセンブルすることができます。

生成されたコードが実際のオブジェクトに依存するため、コンパイルされたILコードをdllとして保存することはできません。技術的には、PowerShellがdllとして保存できるコードを生成することは可能ですが、これは実装されていません。

スクリプトとレプリケーションはまったく同じです。

PowerShellが実際にアセンブリを生成しても、スクリプトをコンパイルしてPowerShellをインストールする必要がある場合は、移植性の高いexeファイルを作成できないことに注意してください。

PowerShellスクリプトを他の言語から呼び出すのは、多少困難で厄介なことがあります。これは、主にパイプライニングとパラメータのバインディングが、通常のメソッドのディスパッチとは多少異なります。

C#でPowerShellスクリプトから返されたオブジェクトを使用できます。 V3から、C#でdynamicキーワードを使用すると、他のオブジェクトと同じように、PSObjectのプロパティにアクセスしたり、スクリプトメソッドなどを呼び出すことができます。 V3の前に、psobj.Properties ['SomeProperty']のようなapiを使用しなければなりませんでした。

関連する問題