[玩转系统] 如何创建标准库二进制模块
作者:精品下载站 日期:2024-12-14 02:56:53 浏览:13 分类:玩电脑
如何创建标准库二进制模块
我最近有一个模块的想法,我想将其实现为二进制模块。我还没有使用 PowerShell 标准库创建一个,所以这感觉是一个很好的机会。我使用创建跨平台二进制模块指南来创建此模块,没有任何障碍。我们将遵循相同的过程,并且我会在此过程中添加一些额外的评论。
笔记
本文的原始版本出现在@KevinMarquette 撰写的博客上。 PowerShell 团队感谢 Kevin 与我们分享这些内容。请查看他的博客:PowerShellExplained.com。
什么是 PowerShell 标准库?
PowerShell 标准库允许我们创建可在 PowerShell 和 Windows PowerShell 5.1 中工作的跨平台模块。
为什么是二进制模块?
当您用 C# 编写模块时,您就放弃了对 PowerShell cmdlet 和函数的轻松访问。但如果您创建的模块不依赖于许多其他 PowerShell 命令,则性能优势可能会非常显着。 PowerShell 是针对管理员而不是计算机进行优化的。通过切换到 C#,您可以摆脱 PowerShell 增加的开销。
例如,我们有一个关键流程,它使用 JSON 和哈希表进行大量工作。我们尽可能地优化了 PowerShell,但该过程仍需要 12 分钟才能完成。该模块已经包含了很多 C# 风格的 PowerShell。这使得到二进制模块的转换变得干净而简单。通过转换为二进制模块,我们将处理时间从 12 分钟以上减少到 4 分钟以下。
混合模块
您可以将二进制 cmdlet 与 PowerShell 高级功能混合使用。您所了解的有关脚本模块的一切都以相同的方式应用。其中包含空的 psm1
文件,以便您稍后可以添加其他 PowerShell 函数。
我创建的几乎所有已编译的 cmdlet 首先都是作为 PowerShell 函数开始的。我们所有的二进制模块都是真正的混合模块。
构建脚本
我在这里保持构建脚本简单。我通常使用大型 Invoke-Build
脚本作为 CI/CD 管道的一部分。它还有更多魔力,比如运行 Pester 测试、运行 PSScriptAnalyzer、管理版本控制以及发布到 PSGallery。一旦我开始为我的模块使用构建脚本,我就能够找到很多可以添加到其中的东西。
规划模块
该模块的计划是为 C# 代码创建一个 src
文件夹,并像构建脚本模块一样构造其余部分。这包括使用构建脚本将所有内容编译到 Output
文件夹中。文件夹结构如下所示:
MyModule
├───src
├───Output
│ └───MyModule
├───MyModule
│ ├───Data
│ ├───Private
│ └───Public
└───Tests
入门
首先,我需要创建文件夹并创建 git 存储库。我使用 $module
作为模块名称的占位符。这将使您在需要时更容易重用这些示例。
$module = 'MyModule'
New-Item -Path $module -Type Directory
Set-Location $module
git init
然后创建根级文件夹。
New-Item -Path 'src' -Type Directory
New-Item -Path 'Output' -Type Directory
New-Item -Path 'Tests' -Type Directory
New-Item -Path $module -Type Directory
二进制模块设置
本文重点讨论二进制模块,因此我们将从这里开始。本节从创建跨平台二进制模块指南中获取示例。如果您需要更多详细信息或有任何问题,请查看该指南。
我们要做的第一件事是检查已安装的 dotnet core SDK 的版本。我使用的是 2.1.4,但在继续之前您应该拥有 2.0.0 或更高版本。
PS> dotnet --version
2.1.4
我正在使用 src
文件夹来处理本节。
Set-Location 'src'
使用 dotnet 命令创建一个新的类库。
dotnet new classlib --name $module
这在子文件夹中创建了库项目,但我不想要额外的嵌套级别。我将把这些文件提升一个级别。
Move-Item -Path .$module\* -Destination .\
Remove-Item $module -Recurse
设置项目的.NET core SDK版本。我有 2.1 SDK,因此我将指定 2.1.0
。如果您使用的是 2.0 SDK,请使用 2.0.0
。
dotnet new globaljson --sdk-version 2.1.0
将 PowerShell 标准库 NuGet 包添加到项目中。确保您使用的最新版本可满足您所需的兼容性级别。我会默认使用最新版本,但我认为该模块没有利用任何比 PowerShell 3.0 更新的功能。
dotnet add package PowerShellStandard.Library --version 7.0.0-preview.1
我们应该有一个如下所示的 src 文件夹:
PS> Get-ChildItem
Directory: \MyModule\src
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 7/14/2018 9:51 PM obj
-a---- 7/14/2018 9:51 PM 86 Class1.cs
-a---- 7/14/2018 10:03 PM 259 MyModule.csproj
-a---- 7/14/2018 10:05 PM 45 global.json
现在我们准备将自己的代码添加到项目中。
构建二进制 cmdlet
我们需要更新 src\Class1.cs
以包含此启动 cmdlet:
using System;
using System.Management.Automation;
namespace MyModule
{
[Cmdlet( VerbsDiagnostic.Resolve , "MyCmdlet")]
public class ResolveMyCmdletCommand : PSCmdlet
{
[Parameter(Position=0)]
public Object InputObject { get; set; }
protected override void EndProcessing()
{
this.WriteObject(this.InputObject);
base.EndProcessing();
}
}
}
重命名该文件以匹配类名。
Rename-Item .\Class1.cs .\ResolveMyCmdletCommand.cs
然后我们就可以构建我们的模块了。
PS> dotnet build
Microsoft (R) Build Engine version 15.5.180.51428 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.
Restore completed in 18.19 ms for C:\workspace\MyModule\src\MyModule.csproj.
MyModule -> C:\workspace\MyModule\src\bin\Debug\netstandard2.0\MyModule.dll
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:02.19
我们可以在新的 dll 上调用 Import-Module
来加载新的 cmdlet。
PS> Import-Module .\bin\Debug\netstandard2.0$module.dll
PS> Get-Command -Module $module
CommandType Name Version Source
----------- ---- ------- ------
Cmdlet Resolve-MyCmdlet 1.0.0.0 MyModule
如果导入在您的系统上失败,请尝试将 .NET 更新到 4.7.1 或更高版本。创建跨平台二进制模块指南详细介绍了 .NET 支持以及旧版本 .NET 的兼容性。
模块清单
我们可以导入 dll 并拥有一个工作模块,这真是太酷了。我喜欢继续使用它并创建一个模块清单。如果我们想稍后发布到 PSGallery,我们需要清单。
从项目的根目录,我们可以运行此命令来创建我们需要的模块清单。
$manifestSplat = @{
Path = ".$module$module.psd1"
Author = 'Kevin Marquette'
NestedModules = @('bin\MyModule.dll')
RootModule = "$module.psm1"
FunctionsToExport = @('Resolve-MyCmdlet')
}
New-ModuleManifest @manifestSplat
我还将为未来的 PowerShell 功能创建一个空的根模块。
Set-Content -Value '' -Path ".$module$module.psm1"
这允许我在同一个项目中混合普通的 PowerShell 函数和二进制 cmdlet。
构建完整的模块
我将所有内容一起编译到输出文件夹中。我们需要创建一个构建脚本来做到这一点。我通常会将其添加到 Invoke-Build
脚本中,但在此示例中我们可以保持简单。将其添加到项目根目录下的 build.ps1
中。
$module = 'MyModule'
Push-Location $PSScriptRoot
dotnet build $PSScriptRoot\src -o $PSScriptRoot\output$module\bin
Copy-Item "$PSScriptRoot$module\*" "$PSScriptRoot\output$module" -Recurse -Force
Import-Module "$PSScriptRoot\Output$module$module.psd1"
Invoke-Pester "$PSScriptRoot\Tests"
这些命令构建我们的 DLL 并将其放入我们的 output$module\bin
文件夹中。然后它将其他模块文件复制到位。
Output
└───MyModule
├───MyModule.psd1
├───MyModule.psm1
└───bin
├───MyModule.deps.json
├───MyModule.dll
└───MyModule.pdb
此时,我们可以使用 psd1 文件导入我们的模块。
Import-Module ".\Output$module$module.psd1"
从这里,我们可以将 .\Output$module
文件夹放入 $env:PSModulePath
目录中,只要我们需要它,它就会自动加载我们的命令。
更新:dotnet 新 PSModule
我了解到 dotnet
工具有一个 PSModule
模板。
我上面概述的所有步骤仍然有效,但此模板删除了其中的许多步骤。它仍然是一个相当新的模板,仍在进行一些改进。期待它从这里开始变得更好。
这是安装和使用 PSModule 模板的方式。
dotnet new -i Microsoft.PowerShell.Standard.Module.Template
dotnet new psmodule
dotnet build
Import-Module "bin\Debug\netstandard2.0$module.dll"
Get-Module $module
这个最低限度可行的模板负责添加.NET SDK、PowerShell 标准库,并在项目中创建一个示例类。您可以立即构建并运行它。
重要细节
在结束本文之前,还有一些其他值得一提的细节。
卸载 DLL
一旦加载了二进制模块,您就无法真正卸载它。 DLL 文件将被锁定,直到您卸载它。这在开发时可能会很烦人,因为每次您进行更改并想要构建它时,文件通常都会被锁定。解决此问题的唯一可靠方法是关闭加载 DLL 的 PowerShell 会话。
VS Code 重新加载窗口操作
我的大部分 PowerShell 开发工作都是在 VS Code 中完成的。当我处理二进制模块(或带有类的模块)时,我养成了每次构建时都重新加载 VS Code 的习惯。 Ctrl+Shift+P 弹出命令窗口,并且重新加载窗口
始终位于我的列表顶部。
嵌套 PowerShell 会话
另一种选择是拥有良好的 Pester 测试覆盖率。然后,您可以调整 build.ps1 脚本来启动新的 PowerShell 会话、执行构建、运行测试并关闭会话。
更新已安装的模块
当尝试更新本地安装的模块时,这种锁定可能会很烦人。如果任何会话加载了它,您必须找到它并关闭它。从 PSGallery 安装时,这不是一个问题,因为模块版本控制将新版本放置在不同的文件夹中。
您可以设置本地 PSGallery 并作为构建的一部分发布到该 PSGallery。然后从 PSGallery 进行本地安装。这听起来工作量很大,但这就像启动一个 docker 容器一样简单。我在《为 PSRepository 使用 NuGet 服务器》一文中介绍了一种实现此目的的方法。
最后的想法
我没有涉及用于创建 cmdlet 的 C# 语法,但 Windows PowerShell SDK 中有大量相关文档。作为进入更严肃的 C# 的垫脚石,这绝对值得尝试。
猜你还喜欢
- 03-30 [玩转系统] 如何用批处理实现关机,注销,重启和锁定计算机
- 02-14 [系统故障] Win10下报错:该文件没有与之关联的应用来执行该操作
- 01-07 [系统问题] Win10--解决锁屏后会断网的问题
- 01-02 [系统技巧] Windows系统如何关闭防火墙保姆式教程,超详细
- 12-15 [玩转系统] 如何在 Windows 10 和 11 上允许多个 RDP 会话
- 12-15 [玩转系统] 查找 Exchange/Microsoft 365 中不活动(未使用)的通讯组列表
- 12-15 [玩转系统] 如何在 Windows 上安装远程服务器管理工具 (RSAT)
- 12-15 [玩转系统] 如何在 Windows 上重置组策略设置
- 12-15 [玩转系统] 如何获取计算机上的本地管理员列表?
- 12-15 [玩转系统] 在 Visual Studio Code 中连接到 MS SQL Server 数据库
- 12-15 [玩转系统] 如何降级 Windows Server 版本或许可证
- 12-15 [玩转系统] 如何允许非管理员用户在 Windows 中启动/停止服务
取消回复欢迎 你 发表评论:
- 精品推荐!
-
- 最新文章
- 热门文章
- 热评文章
[影视] 黑道中人 Alto Knights(2025)剧情 犯罪 历史 电影
[古装剧] [七侠五义][全75集][WEB-MP4/76G][国语无字][1080P][焦恩俊经典]
[实用软件] 虚拟手机号 电话 验证码 注册
[电视剧] 安眠书店/你 第五季 You Season 5 (2025) 【全10集】
[电视剧] 棋士(2025) 4K 1080P【全22集】悬疑 犯罪 王宝强 陈明昊
[软件合集] 25年6月5日 精选软件22个
[软件合集] 25年6月4日 精选软件36个
[短剧] 2025年06月04日 精选+付费短剧推荐33部
[短剧] 2025年06月03日 精选+付费短剧推荐25部
[软件合集] 25年6月3日 精选软件44个
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电视剧] 欢乐颂.5部全 (2016-2024)
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[影视] 【稀有资源】香港老片 艺坛照妖镜之96应召名册 (1996)
[剧集] 神经风云(2023)(完结).4K
[剧集] [BT] [TVB] [黑夜彩虹(2003)] [全21集] [粤语中字] [TV-RMVB]
[实用软件] 虚拟手机号 电话 验证码 注册
[资源] B站充电视频合集,包含多位重量级up主,全是大佬真金白银买来的~【99GB】
[影视] 内地绝版高清录像带 [mpg]
[书籍] 古今奇书禁书三教九流资料大合集 猎奇必备珍藏资源PDF版 1.14G
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电影] 美国队长4 4K原盘REMUX 杜比视界 内封简繁英双语字幕 49G
[电影] 死神来了(1-6)大合集!
[软件合集] 25年05月13日 精选软件16个
[精品软件] 25年05月15日 精选软件18个
[绝版资源] 南与北 第1-2季 合集 North and South (1985) /美国/豆瓣: 8.8[1080P][中文字幕]
[软件] 25年05月14日 精选软件57个
[短剧] 2025年05月14日 精选+付费短剧推荐39部
[短剧] 2025年05月15日 精选+付费短剧推荐36部
- 最新评论
-
- 热门tag