2015-12-10 31 views
6

Giả sử tôi có một kịch bản PowerShell đơn giản:PowerShell có biên dịch tập lệnh không?

1..3 | Write-Host 
  • Làm thế nào để quá trình PowerShell nó?
  • Công cụ có xây dựng bộ nhớ trong hoặc một số tệp .dll tạm thời không?
  • Tôi có thể kiểm tra hội đồng này và MSIL bằng cách sử dụng một số công cụ (ví dụ: ILSpy, VS, WinDbg) không?
  • PowerShell có xử lý việc xử lý tập lệnh và nhập lại dòng lệnh REPL theo cùng một cách (tức là cả hai được biên dịch/giải thích) không?
  • Tôi có thể sử dụng cụm được biên dịch này cùng với C# và các ngôn ngữ Net khác không?
  • Tập lệnh PS có thể được biên dịch thành mã nhị phân gốc không?
+3

PowerShell là ngôn ngữ diễn giải (có V3 ** bộ nhớ cache nội bộ ** một số IL được tạo). Không có các hội đồng như vậy thì bạn không thể _use_ chúng cùng với các ngôn ngữ .NET khác nhưng tất nhiên bạn có thể lưu trữ PowerShell trong ứng dụng .NET của bạn (cũng chia sẻ điều gì đó!). Câu trả lời khác sau đó là hậu quả của việc này. Giới thiệu về kiểm tra IL được lưu trong bộ nhớ cache ...tốt, tất nhiên kiểm tra mã PS với ILSpy và sử dụng WinDbg bạn có thể thực hiện hầu hết mọi thứ bạn muốn ... –

+0

Nếu mục tiêu của bạn là triển khai tập lệnh PowerShell dưới dạng tệp thực thi, bạn có thể muốn xem dự án này: https: // gallery.technet.microsoft.com/PS2EXE-Convert-PowerShell-9e4e07f1 –

Trả lời

9

PowerShell V2 và trước đó chưa bao giờ biên dịch tập lệnh, nó luôn được diễn giải qua phương pháp "eval" ảo trong cây phân tích cú pháp.

PowerShell V3 và sau đó biên dịch cây phân tích cú pháp (Ast) thành cây biểu thức LINQ, sau đó được biên dịch thành mã byte và mã byte được diễn giải.

Nếu tập lệnh được thực thi 16 lần, tập lệnh được biên dịch trong nền và ngay sau khi jit hoàn thành, mã giải thích sẽ không được sử dụng. Điều tương tự cũng áp dụng cho các vòng lặp, nếu một vòng lặp lặp lại 16 lần, thân vòng lặp sẽ được biên dịch và thân vòng lặp sẽ chuyển từ giải thích sang jit được biên dịch trong thời gian sớm nhất có thể.

Nhiều thao tác như truy cập thành viên hoặc gọi phương thức C# luôn được biên dịch theo các phương thức động nhỏ. Các trang web động này được tối ưu hóa cho bản chất động của PowerShell, thích nghi với các loại đầu vào khác nhau theo yêu cầu.

Mã được biên dịch jit được lưu trữ trong hội đồng "phương pháp ẩn danh" và không thể lưu được. Với windbg, bạn có thể tháo rời IL của mã được tạo ra.

Lưu mã IL đã biên dịch dưới dạng dll không hoàn toàn có thể do mã được tạo phụ thuộc vào các đối tượng trực tiếp. Về mặt kỹ thuật, PowerShell có thể tạo mã có thể được lưu dưới dạng dll, nhưng điều đó không được triển khai.

Kịch bản và công việc thay thế giống hệt nhau. Lưu ý rằng nếu PowerShell đã thực sự tạo ra một hội đồng, nó vẫn sẽ yêu cầu phiên bản PowerShell đã biên dịch tập lệnh được cài đặt, bạn không thể tạo ra một exe hoàn toàn có thể di chuyển được. Một số yếu tố - chủ yếu là pipelining và tham số ràng buộc khác với phần nào từ việc gửi phương thức thông thường, sẽ khó khăn và khó xử khi gọi các kịch bản PowerShell từ các ngôn ngữ khác.

Bạn có thể sử dụng các đối tượng được trả lại từ tập lệnh PowerShell trong C#. Bắt đầu từ V3, nếu bạn sử dụng từ khóa động trong C#, bạn có thể truy cập các thuộc tính, gọi phương thức tập lệnh, v.v. trên PSObject giống như bạn làm với bất kỳ đối tượng nào khác. Trước V3, bạn phải sử dụng api như psobj.Properties ['SomeProperty'].

Các vấn đề liên quan