我想在PS中有一个截图工具。因为我不想重新发明轮子,所以我搜索并在github(https://github.com/mikepruett3/psfetch)找到了一个脚本,我根据自己的需要进行了调整。
现在我想改变行为 - 当脚本启动时没有参数时,它应该在当前目录中截屏。如果用户输入路径(-Path
),则应将屏幕截图保存在那里。
我的想法是定义(在我的情况下)$Tarpath
并在给出选项时重新定义它。怎么做?
这是我的实际脚本:
# PSFetch.ps1
# A Screenfetch writen in PowerShell
#
# -----------------------------------------------------------
# The Original Inspirations for CMDfetch:
# -----------------------------------------------------------
# screenFetch by KittyKatt
# https://github.com/KittyKatt/screenFetch
# A very nice screenshotting and information tool. For GNU/Linux (Almost all Major Distros Supported) *This has been ported to Windows, link below.*
#
# archey by djmelik
# https://github.com/djmelik/archey
# Another nice screenshotting and information tool. More hardware oriented than screenFetch. For GNU/Linux
# -----------------------------------------------------------
#
# DONE: Function to Take the Screenshot
Function Take-Screenshot {
[CmdletBinding()]
Param(
[string]$Width,
[string]$Height,
[string]$TarPath = "$PSScriptRoot"
)
PROCESS {
[Reflection.Assembly]::LoadWithPartialName("System.Drawing") > $Null
# Changed how $bounds is calculated so that screen shots with multiple monitors that are offset work correctly
$bounds = [Windows.Forms.SystemInformation]::VirtualScreen
# Check Path for Trailing BackSlashes
# $TarPath = $PSScriptRoot
if ( $TarPath.EndsWith("\") ) {
$TarPath = $TarPath.Substring(0,$Path.Length-1)
}
# Define The Target Path
$stamp = get-date -f MM-dd-yyyy_HH_mm_ss
$target = "$TarPath\screenshot-$stamp.png"
# Take the Screenshot
$bmp = New-Object Drawing.Bitmap $bounds.width, $bounds.height
$graphics = [Drawing.Graphics]::FromImage($bmp)
$graphics.CopyFromScreen($bounds.Location, [Drawing.Point]::Empty, $bounds.size)
$bmp.Save($target)
$graphics.Dispose()
$bmp.Dispose()
}
}
# DONE: Fix support for Multiple Monitors
# FROM: Shay Levy's Response - http://stackoverflow.com/questions/7967699/get-screen-resolution-using-wmi-powershell-in-windows-7
$ScreenWidth = 0
$ScreenHeight = 0
Add-Type -AssemblyName System.Windows.Forms
$DisplayCount = [System.Windows.Forms.Screen]::AllScreens.Bounds.Count
$Bounds = [System.Windows.Forms.Screen]::AllScreens | Select-Object -ExpandProperty Bounds
$ScreenWidth = $Bounds | Measure-Object -Property Width -Sum | Select-Object -ExpandProperty Sum
$ScreenHeight = $Bounds | Measure-Object -Property Height -Maximum | Select-Object -ExpandProperty Maximum
$RESOLUTION = "$ScreenWidth x $ScreenHeight"
# Take Screenshot if the Parameters are assigned...
Take-Screenshot -Width $ScreenWidth -Height $ScreenHeight -TarPath $target
修改的 我忘了删除PROCESS-block中的$ tarpath。 从我的第一次测试开始就一直存在......
答案 0 :(得分:1)
您在函数体中重新定义$TarPath
:
$TarPath = $PSScriptRoot
这无条件地取代先前分配给参数的任何值。删除该行,您可以传递这样的参数:
Take-Screenshot -TarPath 'C:\some\folder'
或省略参数以使其保持默认值($PSScriptRoot
)。
我建议也改行
$target = "$TarPath\screenshot-$stamp.png"
进入这个:
$target = Join-Path $TarPath "screenshot-$stamp.png"
所以你不需要摆弄尾随的反斜杠。
Function Take-Screenshot {
[CmdletBinding()]
Param(
[string]$Width,
[string]$Height,
[string]$TarPath = "$PSScriptRoot"
)
PROCESS {
[Reflection.Assembly]::LoadWithPartialName("System.Drawing") > $Null
# Changed how $bounds is calculated so that screen shots with multiple monitors that are offset work correctly
$bounds = [Windows.Forms.SystemInformation]::VirtualScreen
# Define The Target Path
$stamp = get-date -f MM-dd-yyyy_HH_mm_ss
$target = Join-Path $TarPath "screenshot-$stamp.png"
# Take the Screenshot
$bmp = New-Object Drawing.Bitmap $bounds.width, $bounds.height
$graphics = [Drawing.Graphics]::FromImage($bmp)
$graphics.CopyFromScreen($bounds.Location, [Drawing.Point]::Empty, $bounds.size)
$bmp.Save($target)
$graphics.Dispose()
$bmp.Dispose()
}
}
附录:有两种情况,将参数-TarPath
的默认值定义为$TarPath = "$PSScriptRoot"
不起作用:
该参数被定义为脚本的参数(而不是脚本中的函数),脚本从CMD运行:
powershell -File 'C:\path\to\script.ps1'
该脚本使用PowerShell v2运行。该变量仅在PowerShell v3之前的模块中可用。
在这两种情况下,"$PScriptRoot"
都可以替换为$PWD.Path
:
[CmdletBinding()]
Param(
[string]$Width,
[string]$Height,
[string]$TarPath = $PWD.Path
)
答案 1 :(得分:1)
好的,我自己解决了。
首先[string]$TarPath = "$PSScriptRoot"
根本不起作用!
变量始终为空。
但是,我的第一个想法是定义$TarPath
并保持不变直到再次定义。结果证明这不起作用。
这是我的解决方案:
# Define The Target Path
Write-Host "Please enter Screenshot-Path"
$TarPath = Read-Host "Else the screenshot will be in $PWD"
if (!$TarPath) {$TarPath = $pwd}
如果在提示符处输入任何内容$pwd
将被使用。
答案 2 :(得分:0)
您只需要使用以下任一方法修改脚本的最后一行:
对于默认目录:
Take-Screenshot -Width $ScreenWidth -Height $ScreenHeight
对于自定义目录:
Take-Screenshot -Width $ScreenWidth -Height $ScreenHeight -TarPath "D:\Piyush\temp"
并注释掉PROCESS块中的以下行,因为您不希望使用默认路径覆盖自定义目录路径。
$TarPath = $PSScriptRoot
答案 3 :(得分:0)
嗯,是的,关于它,这种方法会起作用。唯一的问题是,在PROCESS
区块中,您再次重新分配了$TarPath
,使您的后备机制失效:
$TarPath = $PSScriptRoot
删除该行,它将像魅力一样工作。
此外,您可以添加验证,例如确保参数可以为null,但不能为空,并且必须是有效路径:
[ValidateScript({if ($_){ Test-Path $_}})]
[string]$TarPath = "$PSScriptRoot"
最后一件事,如您所希望的,如您所希望的那样,让用户在通话中使用-Path
,您还可以为Param
添加别名。
[Alias('Path')]
[ValidateScript({if ($_){ Test-Path $_}})]
[string]$Path = "$PSScriptRoot"