我们可以查看 PowerShell cmdlet 的源代码吗?

Posted

技术标签:

【中文标题】我们可以查看 PowerShell cmdlet 的源代码吗?【英文标题】:Can we see the source code for PowerShell cmdlets? 【发布时间】:2010-09-20 22:38:03 【问题描述】:

我正在学习一些 PowerShell。是否可以看到像 Get-ChildItem 这样的内置 cmdlet 的源代码?

【问题讨论】:

二进制文件不是 .NET,所以反射是正确的。 什么?不,这很愚蠢。我会用一些反思的东西更新我的答案。 您现在可以 - github.com/PowerShell/PowerShell/blob/HEAD/src/…. 【参考方案1】:

我不相信 PowerShell 的源代码曾经发布过。

【讨论】:

开源代码(现在)比人们想象的要多:Windows PowerShell blog: The Archive module is now open-source。 @codekaizen Powershell is now open source.【参考方案2】:

您应该可以使用.NET Reflector“查看”源代码。您需要了解程序集,但也应该使用 GetType 方法或类似方法访问它。

这个PowerShellLanguage .NET Reflector Add-In 可能有用。

【讨论】:

看看我更新的答案,你不需要知道汇编!【参考方案3】:

实际上,您最好的选择是去查看PowerShell Community Extensions。这个开源软件社区项目“旨在提供一组广泛有用的附加 cmdlet……”。该项目的开发人员是 PowerShell MVP 并且知道他们的东西。

就在现有 PowerShell cmdlet 上使用反射而言,PowerShell MVP Oisin Grehan 制作了一个名为“Reflect-Cmdlet”的便捷函数。我不会窃取他的代码并将其放在这里,但基本上你要做的是:

Get-Command Get-ChildItem | Reflect-Cmdlet

然后.NET Reflector 弹出并打开并扩展了正确的程序集以及所有内容。真的很酷。

【讨论】:

我知道这是很久以前的事了,但是截图不见了。 :) 没关系,仅供参考。 看起来它又回来了,又过了很长时间。 +1 链接到Reflect-Cmdlet,非常有帮助。已修改以使其与 Jetbrains DotPeek 一起使用。 gist.github.com/dennisroche/013c5a56d9a7f16851cb 变得不可用。 该 cmd-let 的 SSL 证书无效。这似乎也是possibly without using any third-party tools【参考方案4】:

您可能还想看看 CodePlex 上的Windows Installer PowerShell Snap-In。这是一个比社区扩展更小的项目,因此更容易了解正在发生的事情。

查看Professional Windows PowerShell Programming: Snapins、Cmdlet、Hosts and Providers(Wrox 专业指南),ISBN:0470173939 - 这是我找到的用于编写 cmdlet 和提供程序的最有用的书籍之一.

【讨论】:

【参考方案5】:

PowerShell cmdlet 的程序集位于 GAC 中。您可以在以下位置找到“Get-ChildItem”cmdlet:

Microsoft.PowerShell.Commands.Management 程序集,Microsoft.PowerShell.Commands.GetChildItemCommand 类。

我使用了 ILSpy .NET 反编译器并通过“powershell”字符串过滤了 GAC 程序集。据我了解,Microsoft.PowerShell.Commands.* 程序集包含内置 cmdlet。

【讨论】:

【参考方案6】:

我认为如果您刚开始使用 PowerShell,这就是您要寻找的:

$metadata = New-Object system.management.automation.commandmetadata (Get-Command Get-Process)
[System.management.automation.proxycommand]::Create($MetaData) | out-file C:\powershell\get-process.ps1

这将创建一个脚本,显示Get-Process 如何运行。放入任何要替换 Get-Process 的 cmdlet。如果您想在 Google 上了解更多信息,这就是您创建代理功能的方式。

【讨论】:

漂亮而简单,不需要 Reflector.NET 或 DotPeek,干杯。顺便说一句,[System.management.automation.proxycommand]::Create($MetaData) 对我来说似乎足够了,只需在屏幕上显示结果。 这会创建一个proxy command,这与查看源代码完全不同。这不会为您提供 Get-Process 的源代码,也不会向您展示它是如何运行的;它返回一个基本脚本,您可以使用它来修改 cmdlet,例如,通过向其添加其他参数。【参考方案7】:

一些代码可以在参考资源网站上找到: http://referencesource.microsoft.com/#System.Management.Automation/System/Management/Automation/ChildItemCmdletProviderIntrinsics.cs,c6eed9f6a5417c19

这只是给出了大纲;不是代码的详细信息。

【讨论】:

【参考方案8】:

对于已编译 Cmdlet,您可以通过以下方式获取.dll 的路径:

(Get-Command Get-ChildItem).DLL

(将Get-ChildItem替换为您感兴趣的cmdlet)

一旦知道.dll 的路径,就可以使用.NET 反汇编程序打开它,例如dotPeek:

& dotPeek64.exe (Get-Command Get-ChildItem).DLL

【讨论】:

令人着迷,例如,这似乎不适用于带有 DnsClient 模块的 PowerShell 7.0。此外,Get-Module DnsClient|Get-Member 没有显示 DLL 属性/成员。【参考方案9】:

The source for Powershell is now available on Github.Get-ChildItem的来源可以在here找到。

【讨论】:

当问题的答案从“否”变为“是”时会发生什么? @GeekyI 大概 OP(原始发帖人)应该接受新的答案,而不是之前接受的答案。但是 OP 无论如何都没有接受答案,他也没有活跃的个人资料,所以我想这并不重要。【参考方案10】:

对于使用Install-Module 安装且包含源代码而非二进制文件的某些 cmdlet(例如 PSnmap):

Install-Module -Name PSnmap

...您可以通过查看Definition 属性来查看他们的代码:

Get-Command Invoke-PSnmap | Format-List

如果没有,您很可能需要反编译一些二进制文件(例如,DLL 属性中指定的文件)。

【讨论】:

以上是关于我们可以查看 PowerShell cmdlet 的源代码吗?的主要内容,如果未能解决你的问题,请参考以下文章

我可以使用 .NET Core 编写 PowerShell 二进制 cmdlet 吗?

是否可以/如何使用某些 cmdlet 停止 powershell?

是否可以/如何使用某些 cmdlet 停止 powershell?

对于自动化帐户,使用 azure 资源图是不是比 powershell cmdlet 更快?

powershell 如何查找需要使用的命令

powershell 如何查找需要使用的命令