abeet / Blog

github写博客,博客文章见本项目Issues
23 stars 2 forks source link

用c#实现http服务器接受ajax请求,c#实现网页截图并上传文件到远程服务器 #36

Open abeet opened 5 years ago

abeet commented 5 years ago

目的

在ZCMS中专题可视化制作,原来的截图用的是html2canvas,其原理是解析html和css,在Canvas上绘制截图,相当于实现了浏览器的css解析部分的功能,不但无法正确还实际的界面效果,绘制的的速度还很慢,甚至会因为脚本错误导致无法返回截图。 现在的思路是用C#在本地跑一个http服务器,并响应js请求对网页截屏,然后上传图像到远程服务器。

实现过程

所以我们要开始一个新的项目,基于.NET Framework的实现

先看文档 https://docs.microsoft.com/zh-cn/dotnet/framework/index
记下可能要参考的文档
https://docs.microsoft.com/zh-cn/dotnet/framework/network-programming/network-programming-samples
《网络编程示例》
https://docs.microsoft.com/en-us/dotnet/api/system.net.httplistener?redirectedfrom=MSDN&view=netframework-4.7.2
没想到.NET Framework开启一个http访问也挺简单的。。。

遇到“c# 未能找到类型或命名空间”的解决 找到右侧的“解决方案“1个项目””下的子目录“引用”,右键点击,“添加引用”,选择“.net”,活动鼠标,找到“System.Drawing”,选中它,点击确定。就OK了!

在git上搜索 “Graphics.FromImage BackgroundImage WindowState ShowInTaskbar FormBorderStyle”
找到截图功能参考代码
https://github.com/Horiatu/PrintScreen/blob/master/PrintScreen/CaptureForm.cs
支持按下alt键

https://github.com/sysr-q/xcap/blob/master/src/Snap.cs
有图片上传示例

https://github.com/fish-li/ClownFish.Tucao/blob/master/src/client/ClownFish.Tucao.WinClient/CaptureForm.cs

https://github.com/Dinokaiz2/AUTONOTE/blob/master/AUTONOTE/SnipForm.cs
中文注释

https://github.com/adzm/BusinessCats/blob/master/SnippingCat.cs

https://github.com/rayel/SinaWeiboClient/blob/master/WeiboClient/Forms/ScreenShot.cs

在github上搜索”new HttpListener HttpListenerContext HttpListenerRequest 200 route“ 和 ”new HttpListener HttpListenerContext HttpListenerRequest 200 routes“ ”new HttpListener HttpListenerContext HttpListenerRequest 200 router“
找了一些实现HTTPServer的代码,选择最简短的几个类

https://github.com/MemoryPenguin/CodeSync2/blob/master/CodeSync2-Server/Network/HttpServer.cs
https://github.com/klasbj/fsxrelay/blob/master/fsx_relay_console/HttpServer.cs
https://github.com/ktos/BasicRestServer/blob/master/BasicRestServer.Netmf/BasicRestServer.cs

结合 https://github.com/Dinokaiz2/AUTONOTE/blob/93e60d91b9/AUTONOTE/SnipForm.cs
https://github.com/ktos/BasicRestServer/blob/master/BasicRestServer.Netmf/BasicRestServer.cs
实现了,访问 http://localhost:8080/capture?x=11&y=22&w=444&h=333 将主屏幕的特定位置载图的效果。

现在要定位浏览器所在的窗口进行截图,我设想浏览器所在窗口即鼠标所在窗口,
于是在github上搜索 ”AllScreens CopyFromScreen Cursor.Position“
找到如下代码,来获取当前鼠标所在屏幕的办法
https://github.com/pj-martins/ScreenCapture/blob/master/CaptureHelper.cs

将之前实现的word中图片上传到服务器的部分逻辑移到这个c#程序里

js交互部分比较简单,就不写了。

c#实现网页截图就这么完成了,代码量还挺少,发布后不到20k,耶。

还可以改进的地方,滚动窗口截长图——现在zcms里专题的编辑区是限定在一个iframe里的,要找到这个iframe并滚动它可能有点麻烦,容后再实现。

打包成服务后出现了一个大问题

总是截图失败,取到的鼠标位置总是0,0,取到的屏幕宽总是为1024*768, 在google上搜索“c# service Screen” 找到文章 https://stackoverflow.com/questions/4712532/why-does-print-screen-in-a-windows-service-return-a-black-image
原来出于安全考虑后台服务不允许读取屏幕。 只能把截屏程序另外写一个了。

查资料解决以下问题

所有问题解决后,仍然有问题还是获取不到真实屏幕,看来是另外一个问题了 搜索”服务 新进程 运行 Windows 7“——这个搜索词是在多次尝试后才得到的
发现文章 http://www.cnblogs.com/gnielee/archive/2010/04/08/session0-isolation-part2.html
再在github上搜索”CreateProcessAsUser“
找到项目 https://github.com/murrayju/CreateProcessAsUser
把代码搬过来,又有几个问题

注意一下后台服务的 ApplicationData 目录在 C:\Users\abeet\AppData\Roaming\zving.com 而前台应用的 ApplicationData 目录在 C:\Windows\SysWOW64\config\systemprofile\AppData\Roaming

cdoer commented 3 years ago

牛逼 感觉泽元cms的比拓尔思的好用,功能强大点, 变成泽元长沙分公司老总了, 作者牛啊,从产品到前端到老总