[玩转系统] 星期五乐趣 - 用 PowerShell 画一幅漂亮的图画
作者:精品下载站 日期:2024-12-14 08:05:53 浏览:12 分类:玩电脑
星期五乐趣 - 用 PowerShell 画一幅漂亮的图画
几个月前,我写了一篇关于我的 PSClock 模块的文章。这是一组 PowerShell 命令,用于使用透明 WPF 表单创建数字时钟。您可以从 PowerShell 库安装该模块。该存储库可以在 https://github.com/jdhitsolutions/PSClock 找到。由于我的 Windows 壁纸全天都会变化,有时我需要更改时钟颜色以使其更易于阅读。挑战在于颜色选项来自 [System.Drawing.Color]。我可以使用 PapayaWhip、Cornsilk 和 Moccasin 等值。但这些颜色是什么样子的呢?让我们玩得开心并找出答案。
第一步是确保我可以在 PowerShell 会话中使用 [System.Drawing.Color],这更像是一个安全网。我将使用 Add-Type 加载程序集。
Try {
Add-Type -AssemblyName system.drawing -ErrorAction Stop
}
Catch {
Throw "These functions require the [System.Drawing.Color] .NET Class"
}
据我所知,PowerShell 无法直接从此类渲染颜色值。然而,事实上,PowerShell 可以使用 ANSI 转义序列渲染颜色,但在 PowerShell ISE 中则不行。我们将朝那个方向前进。
获取颜色值
我可以使用这样的语法直接从类中获取颜色。
属性 R、G 和 B 是红色、绿色和蓝色值。我稍后会需要这些——首先,简单介绍一下这门课。
我怎么知道颜色名称?我使用 PSReadline 询问 PowerShell。
在 :: 运算符之后,我按 Ctrl+Space 并在出现提示时回答 y。
对于那些熟悉使用 .NET 类的人来说,“问题”是这不是一个枚举。你不能使用这样的代码:
[enum]::GetNames([System.ConsoleColor])
但是,我可以使用 GetProperties() 方法,选择名称属性并过滤掉与颜色名称不匹配的属性。
[system.drawing.color].GetProperties().name | Where-Object { $_ -notmatch "^\bIs|Name|[RGBA]\b" }
一旦知道名称,我就可以获取上面所做的值或使用 FromName() 方法。
转换为 ANSI
正如我之前提到的,如果我有 RBG 值,我可以构造一个 256 色 ANSI 转义序列。最简单的方法是在 PowerShell 7.2 中对 $PSStyle.Foreground 使用 FromRGB() 方法。
$psstyle.Foreground.fromrgb(127,255,0)
或者您可以使用实际的 ANSI 序列。
"$([char]27)[38;2;{0};{1};{2}m" -f 127,255,0
如果您使用 Chartreuse RBG 值尝试此操作,除了提示颜色的部分变化之外,您不会看到任何其他内容。那是因为这只是序列的开头部分。要使用它,请构建一个如下所示的字符串:
#PS 7.2
$ansi = $PSStyle.Foreground.FromRgb(127,255,0)
"$($ansi)Chartreuse$($psstyle.Reset)"
#Other
$ansi = "$([char]27)[38;2;{0};{1};{2}m" -f 127,255,0
"$($ansi)Chartreuse$([char]27)[0m"
工具制造
此时,我应该已经拥有了我需要的所有部件。我可以获得 [System.Drawing.Color.RGB 值]我可以使用这些值来创建 ANSI 序列。最后,我可以构建一个示例字符串。
$name = "Turquoise"
$color = [System.Drawing.Color]::FromName($Name)
$ansi = $PSStyle.Foreground.FromRgb($color.R,$color.G,$color.B)
"$($ansi)$Name$($psstyle.Reset)"
您几乎可以看到 PowerShell 函数自行编写。我本可以构建一个整体函数来完成所有事情,但我决定将其分解为更细粒度的级别。具有独立的功能使它们易于重复使用。这也使它们更容易进行 Pester 测试。特别是因为我正在调用几个您无法正确模拟的 .NET 方法。但是,我可以模拟这样的函数。
function Get-RGB {
[cmdletbinding()]
[OutputType("RGB")]
Param(
[Parameter(Mandatory, HelpMessage = "Enter the name of a system color like Tomato")]
[ValidateNotNullOrEmpty()]
[string]$Name
)
Try {
$Color = [System.Drawing.Color]::FromName($Name)
[PSCustomObject]@{
PSTypeName = "RGB"
Name = $Name
Red = $color.R
Green = $color.G
Blue = $color.B
}
}
Catch {
Throw $_
}
}
该函数将一个简单的对象写入管道。我可以使用该输出来创建 ANSI 序列。
function Convert-RGBtoAnsi {
#This will write an opening ANSI escape sequence to the pipeline
[cmdletbinding()]
[OutputType("String")]
Param(
[parameter(Position = 0, ValueFromPipelineByPropertyName)]
[int]$Red,
[parameter(Position = 1, ValueFromPipelineByPropertyName)]
[int]$Green,
[parameter(Position = 2, ValueFromPipelineByPropertyName)]
[int]$Blue
)
Process {
<#
For legacy powershell session you could create a string like this:
"$([char]27)[38;2;{0};{1};{2}m" -f $red,$green,$blue
#>
$psstyle.Foreground.FromRgb($Red, $Green, $Blue)
}
}
您会注意到参数的定义名称与 RGB 对象相同,并采用管道输入。那是因为我知道我想要运行这样的命令。
$name ="DeepSkyBlue"
$ansi = Get-RGB $name | Convert-RGBtoAnsi
"$($ansi)$Name$($psstyle.Reset)"
最后一个命令使运行这些命令变得更加容易。
Function Get-DrawingColor {
[cmdletbinding()]
[alias("gdc")]
[OutputType("PSColorSample")]
Param(
[Parameter(Position = 0, HelpMessage = "Specify a color by name. Wildcards are allowed.")]
[ValidateNotNullOrEmpty()]
[string[]]$Name
)
Write-Verbose "Starting $($MyInvocation.MyCommand)"
if ($PSBoundParameters.ContainsKey("Name")) {
if ($Name[0] -match "\*") {
Write-Verbose "Finding drawing color names that match $name"
$colors = [system.drawing.color].GetProperties().name | Where-Object { $_ -like $name[0] }
}
else {
$colors = @()
foreach ($n in $name) {
if ($n -as [system.drawing.color]) {
$colors += $n
}
else {
Write-Warning "The name $n does not appear to be a valid System.Drawing.Color value. Skipping this name."
}
Write-Verbose "Using parameter values: $($colors -join ',')"
} #foreach name
} #else
} #if PSBoundParameters contains Name
else {
Write-Verbose "Geting all drawing color names"
$colors = [system.drawing.color].GetProperties().name | Where-Object { $_ -notmatch "^\bIs|Name|[RGBA]\b" }
}
Write-Verbose "Processing $($colors.count) colors"
if ($colors.count -gt 0) {
foreach ($c in $colors) {
Write-Verbose "...$c"
$ansi = Get-RGB $c -OutVariable rgb | Convert-RGBtoAnsi
#display an ANSI formatted sample string
$sample = "$ansi$c$($psstyle.reset)"
#write a custom object to the pipeline
[PSCustomObject]@{
PSTypeName = "PSColorSample"
Name = $c
RGB = $rgb
ANSIString = $ansi.replace("`e", "``e")
ANSI = $ansi
Sample = $sample
}
}
} #if colors.count > 0
else {
Write-Warning "No valid colors found."
}
Write-Verbose "Ending $($MyInvocation.MyCommand)"
}
我可以通过名称指定颜色。
我还不知道使用此输出的所有方式,因此我正在创建一个丰富的对象。 ANSI 属性有一个值,但它不显示,因为它是实际的 ANSI 序列。这就是为什么我包含一个 ANSIString 属性,该属性将值显示为我可以在脚本中使用的字符串。
默认行为是显示所有内容。
并非每种颜色都使用 ANSI 显示,您的背景颜色也可能会影响显示,但这对于我的工作来说已经足够接近了。顺便说一句,该函数接受通配符。
此屏幕截图来自 VS Code。
自定义格式
您可能注意到我经常使用 Format-Table 来获得更好看的输出。事实上,我可能喜欢只显示示例的输出。
但让我们让这变得简单。我从 Get-DrawingColor 为自定义对象创建了一个格式 ps1xml 文件。如果您返回代码,您会看到我正在分配一个类型名称。这允许我创建该文件。
<!--
Format type data generated 02/08/2022 17:32:56 by PROSPERO\Jeff
This file was created using the New-PSFormatXML command that is part
of the PSScriptTools module.
https://github.com/jdhitsolutions/PSScriptTools
-->
<Configuration>
<ViewDefinitions>
<View>
<!--Created 02/08/2022 17:32:56 by PROSPERO\Jeff-->
<Name>default</Name>
<ViewSelectedBy>
<TypeName>PSColorSample</TypeName>
</ViewSelectedBy>
<WideControl>
<!--Delete the AutoSize node if you want to use PowerShell defaults.
<AutoSize />-->
<WideEntries>
<WideEntry>
<WideItem>
<PropertyName>Sample</PropertyName>
</WideItem>
</WideEntry>
</WideEntries>
</WideControl>
</View>
<View>
<!--Created 02/08/2022 17:35:40 by PROSPERO\Jeff-->
<Name>default</Name>
<ViewSelectedBy>
<TypeName>PSColorSample</TypeName>
</ViewSelectedBy>
<TableControl>
<!--Delete the AutoSize node if you want to use the defined widths.-->
<AutoSize />
<TableHeaders>
<TableColumnHeader>
<Label>Name</Label>
<Width>14</Width>
<Alignment>left</Alignment>
</TableColumnHeader>
<TableColumnHeader>
<Label>RGB</Label>
<Width>31</Width>
<Alignment>left</Alignment>
</TableColumnHeader>
<TableColumnHeader>
<Label>ANSIString</Label>
<Width>22</Width>
<Alignment>left</Alignment>
</TableColumnHeader>
<TableColumnHeader>
<Label>Sample</Label>
<Width>37</Width>
<Alignment>left</Alignment>
</TableColumnHeader>
</TableHeaders>
<TableRowEntries>
<TableRowEntry>
<TableColumnItems>
<!--
By default the entries use property names, but you can replace them with scriptblocks.
<ScriptBlock>$_.foo /1mb -as [int]</ScriptBlock>
-->
<TableColumnItem>
<PropertyName>Name</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>RGB</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>ANSIString</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>Sample</PropertyName>
</TableColumnItem>
</TableColumnItems>
</TableRowEntry>
</TableRowEntries>
</TableControl>
</View>
</ViewDefinitions>
</Configuration>
在包含所有函数的脚本文件中,我添加此行来加载格式化文件。
Update-FormatData $PSScriptRoot\pscolorsample.format.ps1xml
我将宽布局设置为默认布局。
我还创建了一个自定义表视图,它省略了 ANSI 属性,因为没有什么可看的。
概括
我承认您可能对这些功能没有迫切的需求。但我希望您遵循我的开发流程。考虑一下您的职能如何协同工作。将丰富的对象写入管道并使用格式化文件提供默认输出。
周末愉快。
猜你还喜欢
- 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