当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] 重温 PowerShell 日历

作者:精品下载站 日期:2024-12-14 07:53:12 浏览:13 分类:玩电脑

重温 PowerShell 日历


本周早些时候,我在脚本文件夹中发现了一段旧代码,最初由 Lee Holmes 发布。这是一个 2008 年的旧脚本,使用 PowerShell 显示带有外出信息的日历。我似乎记得我一直在尝试做类似的事情 - 在控制台中显示每月日历,当时我遇到了 Lee 更好的解决方案。我决定恢复并更新他的剧本。新版本包括在控制台中显示日历的功能。

原始脚本允许您指定要显示的月份的开始日期和结束日期。您还可以指定用星号或方括号突出显示的日期。我决定简化并只保留代码以用星号突出显示某些日子。我还决定将原始代码(脚本)转变为高级函数。转到函数,使其更易于使用,并让我利用参数集等高级函数功能。是的,我知道您可以在脚本文件中使用其中许多功能,但该函数使这一切变得更加容易。事实上,现在我正在思考我所编写的代码,请给我几分钟时间。我马上回来。

我意识到我需要获取代码并将其转换为适当的模块。它现已发布到 PowerShell 库。

Install-Module PSCalendar

该模块应在 Windows 和 Linux 平台上的 PowerShell Core 上运行。我没有 Mac 可以测试。源代码可以在 https://github.com/jdhitsolutions/PSCalendar 找到,尽管我将在这里解释一些事情。

主要命令是获取日历。默认行为是显示当前月份并突出显示当前日期。

[玩转系统] 重温 PowerShell 日历

您还可以指定月份范围。

[玩转系统] 重温 PowerShell 日历

我希望能够指定月份,但我还需要具有文化意识的值。我不想对 ValidateSet 属性进行硬编码,因为这会迫使我使用美国值。我开始使用动态参数,但这些并不是很用户友好。所以我最终在模块中添加了一个自动完成器。

PowerShell 现在包含一个名为 Register-AutoCompleter 的命令。此命令允许您定义帮助您自动完成参数值的代码。您可能已经看到,当您键入 Get-Service 后跟空格和制表符时,PowerShell 会自动补全可能的值。您可以将相同的功能添加到您的代码中。

Register-ArgumentCompleter -CommandName Get-Calendar, Show-Calendar -ParameterName Month -ScriptBlock {
    param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)

    #get month names, filtering out blanks
    (Get-Culture).DateTimeFormat.MonthNames | Where-object {$_ -match "\w+" -and $_ -match "$WordToComplete"} |
        ForEach-Object {
        [System.Management.Automation.CompletionResult]::new($_.Trim(), $_.Trim(), 'ParameterValue', $_)
    }
}

该代码与您在查看 Register-AutoCompleter 帮助时看到的代码非常相似。就我而言,我正在为命令 Get-Calendar 和 Show-Calendar(稍后详细介绍)定义一个自动完成器,这两个命令的参数名称均为 Month。脚本块本质上是一个将被执行的函数。据我所知,将参数与脚本块一起使用,就像我在这里一样。关于这个命令的文档很少,所以我从示例开始工作。脚本块的第一部分是获取文化特定的月份名称。在我的计算机上,我也得到了一些空白,因此我过滤到Where-Object以仅保留带有单词字符的值。我还使用 $WordToComplete 变量/参数。当我运行 Get-Calendar -Month 并开始按 Tab 时,PowerShell 将从列表中的第一项“一月”开始。但如果我输入“ju”并点击 Tab,PowerShell 将跳转到“June”。 “ju”成为 $WordToComplete 的值。然后添加每个月份名称作为完成结果。参数是 CompletionText、ListItemText、ResultType(参数值)和 ToolTip。

我使用 -Year 参数执行类似的操作来显示当前年份以及接下来的 5 年。

Register-ArgumentCompleter -CommandName Get-Calendar, Show-Calendar -ParameterName Year -ScriptBlock {
    param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)

    $first = (Get-Date).Year
    $last = (Get-Date).AddYears(5).Year
    $first..$last |
        ForEach-Object {
        [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
    }
}

它看起来是这样的:

[玩转系统] 重温 PowerShell 日历

目前,没有什么可以阻止用户输入无效月份。但我假设自动完成器提供了指导。不过,我会在某个时候返回并为不正确的月份添加一些额外的错误处理。

哦,该命令还可以让您突出显示一个或多个日期。

[玩转系统] 重温 PowerShell 日历

但我喜欢颜色。因此,我还编写了一个名为 Show-Calendar 的“包装”函数,它使用相同的参数,但它使用 Write-Host 将彩色版本写入控制台。

[玩转系统] 重温 PowerShell 日历

Get-Calendar 将字符串写入管道。因此,我面临的挑战是将字符串转换为字符串数组,并使用 Write-Host 将每一行写回。最棘手的部分是识别标有星号的日期,这样我就可以以突出显示颜色显示这些日期。这需要一点正则表达式的魔力。

$cal = Get-Calendar @PSBoundParameters

    #turn the calendar into an array of strings
    $calarray = $cal.split("`n")

    # a regular expression pattern to match on highlighted days
    [regex]$m = "(\*)?[\s|\*]\d{1,2}(\*)?"
    foreach ($line in $calarray) {

        if ($line -match "\d{4}") {
            write-Host $line -ForegroundColor Yellow
        }
        elseif ($line -match "\w{3}|-{3}") {
            Write-Host $line -ForegroundColor cyan
        }
        elseif ($line -match "\*") {
            #write-host $line -foregroundcolor Magenta
            $week = $line
            $m.Matches($week).Value| foreach-object {

                $day = "$_"

                if ($day -match "\*") {
                    write-host "$($day.replace('*','').padleft(3," "))  " -NoNewline -ForegroundColor $HighlightColor
                }
                else {
                    write-host "$($day.PadLeft(3," "))  " -nonewline
                }
            }
            write-host ""
        }
        else {
            Write-host $line
        }
    }

但现在我可以这样使用它:

[玩转系统] 重温 PowerShell 日历

我在 PowerShell 配置文件脚本中使用 Show-Calendar 以及其他一些代码来突出显示即将到来的重要日期。

我希望这向您表明旧代码仍然可以发挥作用。尝试一下该模块,让我知道您的想法。使用 Github 存储库报告任何问题。

享受!

更新:我担心此代码在其他文化中可能存在问题,情况似乎确实如此。与其他文化一起进行测试和开发具有挑战性。但我已经向自己提出了一个问题,并将进一步调查。

更新 #2:我已将 v1.2.0 推送到 PowerShell 库。我根据 [system.threading.thread]::CurrentThread 的文化价值观做出了许多文化决策。对于非美国朋友,请告诉我这对您有何帮助。

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯