Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
327 views
in Technique[技术] by (71.8m points)

screenshot - PowerShell Screen Capture

I have been stuck on this for last day or so and I think its something small that I just can't see.

To summarize the code: Powershell script that will run every 60 seconds to take a screen capture. On Windows Server 2012 this works perfectly fine. While on Windows 7, only first screen shot is taken and then all after are "blank" with just white space the size of dimensions. Any Ideas why this happens?

I also attempted to remove the bigger while loop and do a scheduled task that runs every 5 minutes, but again that doesn't work and all I get is a blank white image. Any thoughts? On windows 7. I am using local Admin user.

I am using powershell 4 across both windows 7 and windows server 2012. And .Net 4.5

while($true){   
[Reflection.Assembly]::LoadWithPartialName("System.Drawing")
function screenshot([Drawing.Rectangle]$bounds, $path) {
   $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($path)

   $graphics.Dispose()
   $bmp.Dispose()
}

#NUC bounds
$bounds = [Drawing.Rectangle]::FromLTRB(0, -1080, 1920, 1080)

#remote display bounds
#$bounds = [Drawing.Rectangle]::FromLTRB(0, 0, 1280, 800)

$PC_name=$(Get-WmiObject Win32_Computersystem).name

$dateandtime = Get-Date -Format yyyy-MM-dd-hh-mm-ss

$path_pcname= "C:ScriptsScreenshots" + $PC_name + "_screenshot_" + "$dateandtime"+ ".png"


screenshot $bounds $path_pcname

$limit = (Get-Date).AddMinutes(-15)
$path_todelete = "C:ScriptsScreenshots"

# Delete files older than the $limit.
Get-ChildItem -Path $path_todelete -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force

Start-Sleep -Seconds 60

}

Edit: I realized that this line: [Reflection.Assembly]::LoadWithPartialName("System.Drawing") which reads from the GAC, isn't being initiated correctly. Not sure if this helps.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

When the task is run from an alternate context than the logged-in user (any user, if the system is a terminal), it does not have access to the desktop, that's why you get empty screenshots. The script works, except that I've moved all the code that does loading, presetting and declaring a function out from the loop, and has managed to run it as a scheduled task with correctly formed screenshots. This behavior is by default, and is a security concern, because other users should not have access to the desktop of a current user, local system included. You can place such a task in the task manager to run under a specific user, but you'll be prompted for that user's password to store the task in the Task Scheduler. After you create the task, you'll be able to set its schedule and set it to be run only when the user is logged in (an interactive task). If so, hide Powershell window by using -WindowStyle hidden in powershell.exe parameters.

In short, this can only create correct screenshots if run from under the logged in user. Scheduled tasks qualify if users match. Running as system or local admin won't allow you to get screenshots.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...