解决方案

解决方案

Windows 有一个内置热键(Win + Shift + S)以矩形条模式执行截图工具,任何捕获的屏幕都将作为图像复制到剪贴板。

我目前正在寻找最有效的方法,我们可以将内置的快捷键与一些脚本配对,该脚本在截图后自动执行,并将截图自动保存到特定位置。

我已经尝试过使用键盘pyautogui等模块Python用于获取/创建键盘事件。问题是这些模块确实很慢,而且不稳定,尤其是在较慢的硬件上。

我期待一个可以利用 Windows 内置快捷方式并在其上运行的解决方案。

提前致谢。

答案1

解决方案

据我了解,所需的解决方案预计为 -

..脚本在截图后自动执行,并自动将截图保存到特定位置。

我将进一步阐述“使用任务计划程序运行 Powershell 批处理脚本“想法。这个想法并不新鲜,我很惊讶这个问题还没有得到最充分的回答。所以我们开始吧。

步骤 1:任务计划程序

当用户登录时,这将启动 Powershell 脚本。

  • 打开任务计划程序并点击“创建任务...
  • 一般的选项卡将任务设置为run whether the user is logged in or not-Do not store passwords这些使 Powershell 脚本在隐藏中启动

常规选项卡

  • 触发器选项卡,创建一个触发器An log on,并在下面选择您的用户

触发器标签

  • 操作选项卡,创建一个动作Start a program作为powershell我们的程序,使用以下参数 -
-Command "Get-Content -Path 'D:\Apps\Windows Powershell Scripts\ScreenSnip Manager\Activate.ps1' -Raw | Invoke-Expression"

简而言之,该参数指示 Powershell 将我们的脚本的各行加载为一行,然后执行它,从而绕过有关启动独立脚本的通常 Windows 限制。

笔记:脚本的路径必须有效,并且必须包含名为“Activate.ps1”的文件。

添加动作

任务到此结束。关闭调度程序并继续。

步骤 2:Powershell 脚本

前言:Windows 在截图后会创建 3 个文件 - 屏幕截图、缩略图(在我的 FullHD 设置上始终为 364x180)和一个 Json 文件。所有文件都转储到同一个系统目录ScreenClip,从 Win10 21H1 开始,该目录位于C:\Users\Your-username\AppData\Local\Packages\MicrosoftWindows.Client.CBS_cw5n1h2txyewy\TempState\ScreenClip。我们在循环中的工作相当简单 -

  • 监视文件夹中出现的新文件
  • 然后得到正确的图片
  • 重命名/复制到所需的用户空间文件夹
  • 可选择清除ScreenClip文件夹

下一个,创建文件“激活.ps1”某处在我的例子中,我将其存储在D:\Apps\Windows Powershell Scripts\ScreenSnip Manager\Activate.ps1

脚本内容

$watcher = New-Object System.IO.FileSystemWatcher;

$watcher.Path = "$HOME\AppData\Local\Packages\MicrosoftWindows.Client.CBS_cw5n1h2txyewy\TempState\ScreenClip";

$watcher.Filter = "*.png";

$watcher.NotifyFilter = "FileName";

$watcher.EnableRaisingEvents = $true;

$action = {

    $path = $Event.SourceEventArgs.FullPath;

    # Last chance for a file to unlock;
    Start-Sleep -Milliseconds 100;
    
    try {

        Add-Type -AssemblyName System.Drawing;

        # Open image file;
        $png = [System.Drawing.Image]::FromFile((Get-Item $path));

        $dimensions = -join ($png.Width, " x ", $png.Height);

        # Skip automatic thumbnails which are always the same size;
        If ($dimensions -ne "364 x 180") {
             Copy-Item -Path $path -Destination "$HOME\Downloads\Screenshot-$(get-date -f yyyy-MM-dd-HHmmss.fff).png"; 
        }
        
    } catch {
        
        Write-Host "Problem acquiring image";

    } finally {
        
        $png.Dispose();
    }

}

Register-ObjectEvent -InputObject $watcher -EventName "Created" -SourceIdentifier 'SnipGrab' -Action $action;

Remove-Item -Path (Join-Path $watcher.Path '\*') -Recurse;

while ($true){  Wait-Event -SourceIdentifier "SnipGrab";  };

正如代码所示,Snips 被复制到Username\Downloads文件夹并重命名为类似Screenshot-2021-05-17-213501.033.png。确保调整所需的路径和生成的文件名。

从第一眼看,这个脚本其实没什么复杂的,但还是有一些瑕疵。图像必须小心处理,资源必须在代码中释放。新创建的原始片段通常无法同时使用 - 其内容仍在写入磁盘,因此我添加了100 毫秒等待文件写入完成的时间。我很高兴终于能把这里和那里的片段编译成工作版本。这是我的第二个 Powershell 脚本,我花了一个晚上阅读文档并测试一些东西。希望它能有所帮助)

答案2

编辑:后来(2020 年 10 月)它被发现于Reddit 帖子Windows 已经临时保存了在其某个窗口中捕获的任何屏幕截图的文件Windows ShellExperience 主机文件夹,其中引入了使用 power shell 脚本来完成复制临时创建的文件并通过将其复制到指定位置使其永久化的任务的想法。这种方法后来 (2021 年 5 月) 由 Anton 作为答案提供,现在已成为标记的解决方案。

下面的原始答案经过了轻微修改以提高其质量,并留给后人作为使用 PowerShell 脚本的替代方案(以防您没有/或激活使用 PowerShell)。但是,除非结合使用 AutoHotKey(如后所述),否则它不是整个过程的完全自动化。


我考虑写这样一个脚本已经有一段时间了,因为我发现自己经常使用屏幕截图工具,而且点击并打开,然后点击保存并指定名称变得相当麻烦并且耗费时间。

虽然我最终还是屈服于使用第三方软件(顺便说一下,安装后可能只有 2MB)绿射)我当时想到的是:

概述

总体思路是帮助加快截图保存过程,而 Paint 会自动打开,用户需要手动点击Ctrl+V然后Ctrl+S才能快速粘贴和保存。它包括:

  • 使用事件查看器随时追踪屏幕截图被使用并充当触发器
  • 使用任务计划程序提交保存操作,通过立即打开画图从剪贴板输出已保存的片段来加快保存操作

~或者~

  • 使用任务计划程序运行 Powershell 批处理脚本(如 Anton 的答案所述)
  • 使用任务计划程序运行自动热键脚本会自动打开绘画、粘贴并保存文件(但涉及第三方软件,与 OP 的原始要求相反)

步骤 1:启用事件查看器使用的触发器

  • 跑步安全警察管理系统(又名本地安全策略
  • 在左侧转到当地政策然后审计政策
  • 然后双击“审计过程追踪“并勾选“成功

第 2 步:根据该触发器创建计划任务

每当使用屏幕截图工具时,它都会自动打开画图

  • 打开任务计划程序并点击“创建任务...“*(确保不使用创建基本任务

  • 一般的Tab,随意命名任务

  • 触发器选项卡,单击“新建”,下拉菜单选择“开始任务:“ 选择 ”在一次活动中

  • 选择“自定义”,然后单击“新事件过滤器...”

  • 在顶部,选择“XML”选项卡并点击“手动编辑查询”复选框并输入以下内容之一:

    • 选项1: 如果您希望在做出选择后立即打开 Paint,以便可以粘贴和保存:
<QueryList>
  <Query Id="0" Path="Security">
    <Select Path="Security">*[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and Task = 13312 and (band(Keywords,9007199254740992)) and (EventID=4688)]] 
   and 
     *[EventData[Data[@Name='NewProcessName'] and (Data='C:\Windows\System32\backgroundTaskHost.exe')]] 
   and 
     *[EventData[Data[@Name='ProcessId'] and (Data='0x54c')]]
    </Select>
  </Query>
</QueryList>

作为警告,上述选项尝试通过指定进程 ID(您可以从事件查看器中获取)来限制进程被其他应用程序触发。BackgroundTaskHost但是,进程 ID改变和为什么在尝试使用 Snip & Sketch 中的屏幕截图功能时,同时又有某种形式的“自动”保存功能,这会让事情变得复杂

  • 选项 2:自动化程度稍微低一些,需要您单击进行屏幕截图后弹出的通知才能触发其运行:
<QueryList>
  <Query Id="0" Path="Security">
    <Select Path="Security">*[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and Task = 13312 and (band(Keywords,9007199254740992)) and (EventID=4688)]] 
   and 
     *[EventData[Data[@Name='NewProcessName'] and (Data='C:\Program Files\WindowsApps\Microsoft.ScreenSketch_10.1907.2471.0_x64__8wekyb3d8bbwe\ScreenSketch.exe')]]
    </Select>
  </Query>
</QueryList>

这是因为屏幕截图一直在后台运行,当您创建屏幕截图时,使用的进程是和BackgroundTaskHost的子进程。因此,为了使事件触发器特定于屏幕截图(截图和草图),您需要单击弹出的预览图像通知,以便从屏幕截图和草图中调出RuntimeBrokersvchost后台进程到 *活动任务

  • 单击OKOK返回任务创建窗口。

步骤 3 - 指定要完成的任务

  • 现在转到操作标签
  • 选择“新建...”
  • 如果没有选择,则默认的“操作:”应该是“启动程序”
  • 然后浏览到 mspaint.exe (通常%windir%\system32\mspaint.exe
  • 点击OKOK然后你就设置好了

现在,剪切后画图将自动打开,让您可以立即粘贴并保存文件。

[编辑注:当时没有提供解决方案,上述答案是希望提供某种答案而提供的贡献。事后看来,这似乎很初级,但也许对一小部分人来说会很有用]

任务计划程序的替代操作

以下是我在撰写此答案时尝试实现此目标的一些替代措施:

  • 用一个Powershell 批处理脚本 为了您的方便,此方法不需要第三方程序,幸运的是,Anton 后来提供的答案涵盖了此方法
  • 使用自动热键使整个过程真正自动化,不再需要用户输入。

就我个人而言,在弄清楚这一切之前,我就已经放弃了,并下载、安装和使用了 Greenshot,但是我迫切地想要给出答案,这促使我在 6 小时后才发表了这篇文章。

相关内容