【发布时间】:2019-07-22 06:45:31
【问题描述】:
此案例的主要目标是在定义的时间自动创建生产车间的可视化屏幕截图。在生产车间里,有一个显示器运行关于生产力的可视化,它每 30 秒刷新一次。
我正在设置一种在指定时间创建屏幕截图的自动化方法,因为很难仅远程手动管理显示。至少应将屏幕截图保存到网络驱动器。
有一个错误,或者可能是管理员权限,但在我的个人电脑上,我可以使用任务计划程序制作精美的屏幕截图。在远程 pc 上,可视化正在运行带有任务调度程序的脚本,正在执行“black window”图像。
我已经尝试过下载适合每个客户需求的 PowerShell 脚本。该脚本正在创建整个背景的屏幕截图。当我在我的 PC 上尝试使用任务计划程序的脚本时,因为我需要在一天中设置 2 个不同的时间来生成屏幕截图而无需任何手动操作(例如登录远程 PC,然后点击 prtscrn 按钮并将其保存到文件中)。此脚本应由任务调度程序自动执行此操作。
尝试 1 这是脚本启动的演示 手动。如果脚本是使用 powershell 手动启动的(管理员 特权)只创建一个小分辨率的活动窗口(即使 屏幕定义是为参数“区域”编码的,它已经定义了 适合屏幕的 Width、Height、Left 和 Top 位置)(数字 3)
尝试 2 如果脚本正在由任务调度程序在定义的时间启动 时间,会弹出一个powershell窗口(因为-windowStyle 由于附加参数而隐藏)(第 2 条)
尝试 3 如果脚本是从 PowerShell ISE 编辑器手动运行的 比屏幕截图完美生成并适合整体 分辨率(4K) 代码没有变化。 (第 1 名)
图片:https://imgur.com/a/qOJAOi7
这个powershell脚本的代码是:
Function Get-ScreenShot
{
[CmdletBinding(DefaultParameterSetName='Directory', PositionalBinding=$false)]
Param(
[Parameter(ParameterSetName='File')]
[Parameter(Mandatory=$false, ValueFromPipeline=$False, ValueFromPipelineByPropertyName=$False)]
[ValidateScript({$_ -match "\.(bmp|gif|jpg|png|wmf)$"})]
[string]$FullName,
[Parameter(ParameterSetName='Directory')]
[Parameter(Mandatory=$false, ValueFromPipeline=$False, ValueFromPipelineByPropertyName=$False)]
[string]$Directory,
[Parameter(ParameterSetName='Directory')]
[parameter(Mandatory=$false)]
[ValidateSet('bmp','gif','jpg','png','wmf')]
[String]$Format='png',
[Parameter(ParameterSetName='Directory')]
[parameter(Mandatory=$false)]
[ValidateScript({$_ -ge 0})]
[int]$DurationInSeconds=0,
[Parameter(ParameterSetName='Directory')]
[parameter(Mandatory=$false)]
[ValidateScript({$_ -ge 0})]
[int]$IntervalInSeconds=0,
[parameter(Mandatory=$false)]
[ValidateSet('VirtualScreen','WorkingArea')]
[String]$Area='WorkingArea',
[parameter(Mandatory=$false)]
[Switch]$Beep
)
Add-Type -AssemblyName System.Windows.Forms
Add-type -AssemblyName System.Drawing
# Gather Screen resolution information
#$Screen = [System.Windows.Forms.SystemInformation]::VirtualScreen
#$Screen = [System.Windows.Forms.SystemInformation]::WorkingArea
$Screen = [System.Windows.Forms.SystemInformation]::$Area
$Width = $Screen.Width
$Height = $Screen.Height
$Left = $Screen.Left
$Top = $Screen.Top
$TimeElapsed = 0
$IsTimeStampedFileName = $false
if ($FullName)
{
$Directory = Split-Path -Path $FullName -Parent
$HasExtension = $FullName -match "\.(?<Extension>\w+)$"
if ($HasExtension)
{
$Format = $Matches['Extension']
}
New-Item -Path $Directory -ItemType Directory -Force | Out-Null
}
elseif ($Directory)
{
New-Item -Path $Directory -ItemType Directory -Force | Out-Null
$FullName = Join-Path -Path $Directory -ChildPath $((get-date -f yyyyMMddTHHmmss)+".$Format")
$IsTimeStampedFileName = $true
}
else
{
$Directory = [Environment]::GetFolderPath('MyPictures')
Write-Verbose "Target directory not specified we use [$Directory]"
$FullName = Join-Path -Path $Directory -ChildPath $((get-date -f yyyyMMddTHHmmss)+".$Format")
$IsTimeStampedFileName = $true
}
switch ($Format)
{
'bmp' { $Imageformat= [System.Drawing.Imaging.ImageFormat]::Bmp; }
'gif' { $Imageformat= [System.Drawing.Imaging.ImageFormat]::Gif; }
'jpg' { $Imageformat= [System.Drawing.Imaging.ImageFormat]::Jpeg; }
'png' { $Imageformat= [System.Drawing.Imaging.ImageFormat]::Png; }
'wmf' { $Imageformat= [System.Drawing.Imaging.ImageFormat]::Wmf; }
}
do
{
# Create bitmap using the top-left and bottom-right bounds
$Bitmap = New-Object -TypeName System.Drawing.Bitmap -ArgumentList $Width, $Height
# Create Graphics object
$Graphic = [System.Drawing.Graphics]::FromImage($Bitmap)
# Capture screen
$Graphic.CopyFromScreen($Left, $Top, 0, 0, $Bitmap.Size)
# Save to file
$Bitmap.Save($FullName, $Imageformat)
Write-Verbose -Message "[$(get-date -Format T)] Screenshot saved to $FullName"
if ($Beep)
{
[console]::beep()
}
if (($DurationInSeconds -gt 0) -and ($IntervalInSeconds -gt 0))
{
Write-Verbose "[$(get-date -Format T)] Sleeping $IntervalInSeconds seconds ..."
Start-Sleep -Seconds $IntervalInSeconds
$TimeElapsed += $IntervalInSeconds
}
if ($IsTimeStampedFileName)
{
$FullName = Join-Path -Path $Directory -ChildPath $((get-date -f yyyyMMddTHHmmss)+".$Format")
}
} While ($TimeElapsed -lt $DurationInSeconds)
}
#endregion
Clear-Host
New-Alias -Name New-ScreenShoot -Value Get-ScreenShot -ErrorAction SilentlyContinue
#Get-ScreenShot -Verbose
Get-ScreenShot -Directory 'C:\temp' -Format jpg -DurationInSeconds 300 - IntervalInSeconds 10 -Area WorkingArea -Beep -Verbose
#Get-ScreenShot -FullName 'c:\temp\screenshot.wmf' -Verbose
自动powershell任务运行的代码直接在任务调度器中定义(“task”->properties->actions->启动程序是“PowerShell.exe”,并且在后台运行这个脚本的附加参数是额外的参数“-windowStyle hidden C:/path...”,因为这个想法是自动创建整个可视化的屏幕截图,该屏幕显示在生产中的 4K 显示器上,而不会看到任何额外的窗口启动。
图片:https://imgur.com/a/kk9jItn
抱歉没有发布图片,没有足够的代表:-)
【问题讨论】:
-
[1] ISE 是一个 GUI 应用程序 - 因此它会加载所有需要的 winform 内容。您可能需要将其添加到脚本的顶部。 [2] 任务调度器通常通过特定帐户运行代码——系统、指定用户帐户或“当前用户”。唯一能够与您的显示器交互的是“当前用户”帐户......所以......运行脚本的帐户是什么?
-
运行脚本的帐户可能只是我有权访问的用户。注意到还有另一个“管理员”帐户,但我无权访问它。也许我会尝试在“管理员”下运行? ISE 使用的脚本顶部应该是什么?
-
我刚刚测试了你的代码,它可以在 Powershell.exe 控制台上运行......所以所有需要的东西都已经被加载了。请忽略
[1]评论。 [blush] ///// 您需要使用与运行显示相同的帐户运行代码 - 否则屏幕捕获将捕获错误的“屏幕”。 -
有趣的是,我认为帐户的存在就像具有有限权限的帐户一样。甚至没有考虑到可以捕获错误的屏幕,嗯。我不知道该怎么做,因为我使用的帐户具有管理员权限,并且已为该设备配置。至少还有一个单独的“管理员”帐户。我应该尝试第二个帐户吗?
-
通常你不能在“用户空间”远程做事。不过,使用当前登录的用户在任务计划程序中运行脚本是可行的。
标签: powershell