首页WIN11问题为.NET应用添加截图功能

为.NET应用添加截图功能

时间2022-12-16 12:15:29发布分享专员分类WIN11问题浏览100

本文介绍了 .NET 实现截图功能的思路和过程,如果你仅想了解最后的解决方案,可以直接查看文章末尾imeutil exe是什么进程 。

截图的功能我们应该都经常使用,在开发软件时,我们有时也或多或少需要提供这方面的功能,无论是为用户更方便提供远程诊断,还是获取用户的选择区域,亦或是提供某些功能上的辅助imeutil exe是什么进程 。

开发截图无非就这几种选择:教用户使用截图工具、自行开发一个、使用第三方库imeutil exe是什么进程 。

教用户使用

教的成本无疑是最低的,但是不知道用户那边会发生什么,存在很大的不确定性imeutil exe是什么进程 。截图软件除了我们经常用的聊天工具和系统自带的 Win + Ctrl + S 外,我用起来感觉最好的还是 C++ 写的开源软件 flameshot [1] ,功能非常强大。

为.NET应用添加截图功能

flameshot

使用的第三方的截图软件,不仅有教的成本,还会打断用户对本身软件的一个使用体验imeutil exe是什么进程 。教用户使用最好还是用系统自带的 Win + Ctrl + S 截图,已经可以满足基本的截图需求。

自行开发

自行开发的原理也非常简单:创建一个半透明的全屏无边框窗体,记录鼠标在窗体上的框选矩形位置,使用 CopyFromScreen 获取该位置的屏幕图片即可imeutil exe是什么进程 。

以上只是针对单个显示器的情况,若有多个显示器,则需要增加鼠标所在显示器的逻辑imeutil exe是什么进程 。

虽然听起来不难,但代码实现起来还是有许多要注意的细节imeutil exe是什么进程 。简单的矩形截图实现不难,难得是让用户易用,易接受,毕竟聊天软件已经帮你培养了用户习惯。

使用第三方库

CSkin [2] 是我在 2012 年就在使用的一款界面库,在 WinForm 无疑是软件 UI 美化的王者,可以直接作出和 PC 端 QQ 一样的界面体验imeutil exe是什么进程 。库里也提供了截图工具 FrmCapture ,没中不足的是,在多显示器场景下会报错,无法正常使用,代码库也有 4 年没有更新了。

privateFrmCapturem_frmCapture;

if(m_frmCapture ==null||m_frmCapture.IsDisposed)

m_frmCapture =newFrmCapture;

m_frmCapture.IsCaptureCursor=false;

// 截图结束事件

m_frmCapture.Disposed+=M_frmCapture_Disposed;

m_frmCapture.Show;

HandyControl [3] 和在 nuget 上搜索到的 ScreenCapturerSharp [4] 虽然也可以实现截图功能,但都无法处理多显示器的场景imeutil exe是什么进程 。HandyControl 社区活跃,其使用体验会比较好。ScreenCapturerSharp 提供了类似 QQ 的截图工具库,在 UI 上稍差一些。

如何又快又好又容易

如果只是获取截图,有没有更简单的方式呢?我们只需要模拟按键 Win + Ctrl + S 就可以了呀,然后通过剪贴板获取到截图imeutil exe是什么进程 。说起来容易,但是事情其实并没有那么简单。

首先 SendKeys 就不支持发送 Windows 徽标按键,我们需要通过 WinAPI keybd_event 来替代实现,然后还要获取到截图结束的事件imeutil exe是什么进程 。

[DllImport("user32.dll",SetLastError=true)]

staticexternvoidkeybd_event(bytebVk,bytebScan,uintdwFlags,UIntPtrdwExtraInfo);

其实上面是一个保底的通用方案imeutil exe是什么进程 ,我们可以自行启动截图软件,启动截图软件读取剪贴板 Clipboard.GetImage 一套结束,无缝无感,堪称完美:

ProcesssnippingToolProcess =newProcess

StartInfo=newProcessStartInfo("C:\\Windows\\system32\\SnippingTool.exe","/clip"),

EnableRaisingEvents=true,

snippingToolProcess.Exited+=SnippingToolProcess_Exited;

snippingToolProcess.Start;

事情其实远没有那么简单,直到我在 Win11 用了我的软件imeutil exe是什么进程 。才意识到,这只是可以在 Win10 的 64 位操作系统使用。 SnippingTool /clip 这样带参数启动在 Win11 不支持了,这个路径下的 exe 还被删除了。

虽然你可以在 Win11 通过控制台使用 SnippingTool /clip 启动截图软件,但是并不会直接进入截图流程,而是打开软件主界面imeutil exe是什么进程 。

仔细研究你会发现,Win11 的截图其实已经是 UWP 应用了,就算你吧 Win10 的 SnippingTool.exe 复制到 Win11 也是报错,无法使用的,所以你也不可能在自己的软件打包带上它imeutil exe是什么进程 。

经过几番折腾,我在微软社区提问和提交反馈( Win + F 的时候我觉得这个软件是不是这样启动直接就先截了个屏 ),但是没有找到新版本截图的启动参数imeutil exe是什么进程 。最后直到我前几天发现 Microsoft Learn 的文章 启动屏幕截取 - UWP applications [5] 。在 UWP 里使用这么简单嘛,使用 LaunchUriAsync 就可以了。

boolresult =await Windows.System.Launcher.LaunchUriAsync(newUri("ms-screenclip:"));

有了 URI 的方式,一切就变简单了,你甚至可以在浏览器里调用截图,放一个超链接,或者直接在浏览器地址栏粘贴 ms-screenclip: 后回车打开截图imeutil exe是什么进程 。

之后我们只需要监听进程结束就可以了imeutil exe是什么进程 ,这里需要说明的是,不是启动的进程,而是截图的进程,下面直接上在 WinForm 中使用的代码:

varpsi =newProcessStartInfo

UseShellExecute=true,

FileName="ms-screenclip:"

Process.Start(psi);

// 获取 ScreenClippingHost 这个截图进程的结束事件varsnippingToolProcess =Process.GetProcessesByName("ScreenClippingHost")[0];snippingToolProcess.EnableRaisingEvents=true;snippingToolProcess.Exited+=SnippingToolProcess_Exited;

SnippingToolProcess_Exited 事件:

privatevoidSnippingToolProcess_Exited( object? sender, EventArgs e ) {this.BeginInvoke( newAction( => {varimg = Clipboard.GetImage; }));}

References

[1] flameshot:

[2] CSkin: /

[3] HandyControl: /

[4] ScreenCapturerSharp:

[5] 启动屏幕截取 - UWP applications:

爱资源吧版权声明:以上文中内容来自网络,如有侵权请联系删除,谢谢。

NETNETimeutil exe是什么进程
如何在Win上使用Windows Hello指纹和人脸识别? 论道攻防第2期丨攻防演练态势及防守思路