伏鹏飞

疑难杂症博物馆,.net老司机

Blog

24 Feb 2020

C#获取整个屏幕内容生成图片

之前有个需求获取屏幕生成图片提交给服务器(其实就是服务端有个按钮,让客户端截图)。公司前辈写的代码是采用.net框架的API。获取屏幕的长宽来生成图片。但是后来由于业务需要,针对拼接屏幕的截屏处理失效。所以我和后来换了方案: 模拟键盘的PrintScreen按键。之后从剪贴板获取数据生成图片。非常方便,而且无关驱动,不管多屏幕设置的是复制还是扩展都可以很好的支持。 ScreenPrint.printScreen(); IDataObject data = System.Windows.Forms.Clipboard.GetDataObject(); //Metafile metafile = MetafileHelper.GetEnhMetafileOnClipboard(IntPtr.Zero); //从粘贴板获取数据 Image bm = (Image)(data.GetData(typeof(System.Drawing.Bitmap))); using (Graphics g =...

24 Feb 2020

C#中的STA线程

单线程单元访问外部是串行的,在前一个任务完全结束之前不会进行下一个任务(an object is always executed to completion before another is invoked),开发者一般情况下可以不用担心竞争和死锁等问题(The developer therefore does not need to worry about thread...

20 Feb 2020

Asp.net Core MVC 登录后返回登录签页面的技巧

本文记录最近使用ASP.net Core做Web应用服务时登录用到的技巧。 在一些场景下,客户可以浏览web应用中的一些页面且不写要登录,但客户需要进行某些操作时,此时到登录页面。比如我们浏览“知乎”时候可以不登录,如果需要进行评论,那么会跳转到登录页面。此时用户如果登录完成后直接跳转到首页而不是刚刚浏览的内容,那么体验会大大降低(也许再也找不到刚刚的帖子)。 那么我们怎么在登录后回到之前的页面呢? asp.net core MVC中如果authorize验证不通过,会跳转到指定的页面(比如登录页面)。 首先我们注册服务指定无权限是跳转的方式如下: services.ConfigureApplicationCookie(options => { options.LoginPath = "/Account/Login"; options.LogoutPath = "/Account/Login"; options.ExpireTimeSpan = new...

18 Feb 2020

sql server和 sqlite 判断建表语句

本文记录下在Asp.net Core在署时候可能会遇到的一些疑问。 本文针对有.net framework web程序部署经验并刚刚接触到asp.net core的小伙伴,且暂时不介绍Lunix上部署 — 作为一名有过.net framework部署经验的人员,我们知道,当在vs发布项目到文件夹后,会生成项目的dll,如果有依赖的第三方的dll会一并发布到对应的文件夹下。之后我们在iis中新建网站指定文件夹为我们发布的文件夹即可。网站的运行方式为托管的方式,即:我们的网站不能独立运行,程序的入口为iis的w3wp.exe;我们发布的dll为这个程序的扩展或者说外挂,当iis接收到浏览器请求时候,会交给我们生成的dll处理,处理好的结果再返回给iis,而iis返回给客户浏览器。 那么在asp.net core中有哪些不同了呢?首先我们知道.net core是跨平台的,iis是只能运行在windows,那么我们就会有一个疑问 .net core 是如何解决这个问题的?.net core 生成的dll我们是否可以在iis以原有的方式进行托管?下面我们就开始学习下 我们使用vs2017新建一个asp.net core的web应用程序,并且配置如下图: 通过以上两个步骤,我们已经建立好一个可以发布的web应用(这个模版是一个包含权限配置功能和页面的,并且可以直接运行,有一些示范的页)。...

18 Feb 2020

sql server和 sqlite 判断建表语句

本文记录下sql server和sqlite 创建表的时候需要判断表存不存在,如果存在则不作处理否则新建表。 sql server if not Exists(select 1 from sysobjects where id = object_id('TB{0}SERIALLOG') and type = 'U') begin...

13 Feb 2020

以简单的方式实现离线升级包的自动安装

这两天有个需求如下: 用户已经安装应用程序为P,假如安装目录为“C:\Program(x86)\P”,后期如果程序需要升级给用户升级包,无论升级包在什么位置,用户双击升级包可以自动升级P。 以上需求分析后需要解决如下问题: 1.双击升级包可以执行。 2.找到原程序的安装路径。 针对第一个问题我想到了两种解决方案: 1.可以自己写程序生成exe文件,用户双击运行后释放文件到指定目录(也就是找到原安装路径)中,这显然不合适,因为每次升级都需要制作安装包,而且这个安装包中需要有一定的业务逻辑,制作复杂,成本较高。 2.定义一种文件格式做文件关联,关联程序为安装目录底下的update.exe,升级包采用zip压缩后将后缀改为自定义后缀,用户双击升级包时会运行时运行升级程序同时传入升级包路径。升级程序要做的就是解压、替换。 — 比较连个方案,很容易发现,方案二很快捷而且同时解决了上面的问题二(因为升级程序的路径就是原程序的安装路径)。 这边我们来看下文件关联的代码: [DllImport("shell32.dll")] public static extern void SHChangeNotify(uint wEventId, uint uFlags,...

11 Feb 2020

记录wpf中canvas保存为图片的过程

本文记录使用RenderTargetBitmap导出Canvas的过程 最基础的尝试 大家可能同过网上一些资料了解到使用RenderTargetBitmap导出Canvas代码如下: bool SaveImg(string path) { try { RenderTargetBitmap targetBitmap = new RenderTargetBitmap((int)this.c1.ActualWidth, (int)this.c1.ActualHeight, 96d, 96d, PixelFormats.Pbgra32); targetBitmap.Render(this.c1); PngBitmapEncoder...

13 Jan 2020

有关tcp通讯问题的答疑解惑

这篇文章是分享了我多年来从学习和使用tcp的过程中,遇到的问题,以及处理方式。 首先很多刚接触TCP的新手会习惯性的进入一个思维惯性:发送一个数值接收一个返回值;比如我们调用webservice、调用webapi;在tcp通讯过程中,虽然可以是请求+应答的,但这是一个无需且无状态的过程。什么意思呢,我给大家举个例子: 现在有两个人分别为A、B,A为客户端,B为服务端。A喊出:请回答;B应答:我在。理想情况下: A:请回答 B:我在 A:请回答 B:我在 A:请回答 B:我在 …..一直循环下去。 但是B应答给A时,出现了网络波动,就会出现 A:请回答 A:请回答 B:我在 B:我在 A:请回答 B:我在 ….. 次序错乱了。A不能准确的收到B的应答。 在tcp的传输过程中是以字节流发送和接收,那么每次收到的字节流可能不是完整的,有可能是部分的或者是上次对方应答的字节流+本次应答的部分字节流(其实就是粘包)。这种情况下,我们无法从字节流还原到想要的信息。为什么tcp会这样呢,因为tcp是传输层协议,只保证传输数据送达并且保证流次序,并不处理具体的传输字节表达的内容;而我们使用的http协议是应用层的协议属于上层协议。...

08 Jan 2020

一场http与tcp的交互

今天写给大家一些干货。场景是这样的:客户需要http的方式对接我们原有的的一个程序,但是我不想每台机器上都部署IIS服务,因为这样会增加部署复杂度和成本。而且也不能保证每个机器都可以部署成功。于是我想换一种方式来应答对方程序的请求。于是有了以下尝试: 我使用tcp工具建立一个端口为6000的监听服务,再用浏览器访问 http://127.0.0.1:6000这个地址。可以发现tcp工具获得到了浏览起的请求信息。 我们在尝试将访问的地址改为:http://127.0.0.1:6000?para1=123。 可以看到在tcp工具中可以获得到请求的参数信息。如下图: 经过上面的尝试,我们发现用tcp服务来监听http请求这个方法是可行的,有兴趣的同学可以使用postman这个工具来尝试各种get请求或者post提交请求,来看看tcp服务到底会收到什么样格式的数据。 ##那么我们怎么来响应对方的http的请求呢? 假设业务上我们需要给对方返回的http状态有: 成功200、未找到页面或者文件404、服务器内部错误400、无需操作304;在返回类型上需要:普通的文本、本地文件。那么我们只要按照如下格式返回给对方: byte[] buffer = new byte[1024]; int revCount = client.Available; int revLen...

07 Jan 2020

有关goto语句的一点思考

刚开始接触编程的时候是从C语言入门,当时老师提到过goto语句的危害,后来也就一直没有用到过goto语法;直到这两天看到一份别人写的代码如下: //部分代码 int tryCount = 3; //至多3次重传机会 //Send command tt: commPort.Write(commandByte, 0, command.Count); DelegateState.InvokeDispatchStateEvent(BitConverter.ToString(commandByte), Color.Black); System.Threading.Thread.Sleep(500); //check command byte[] buffer...

06 Jan 2020

说一说WPF中使用多个MediaElement遇到的问题

背景 一款广告播放器的需求:可以循环播放多个视频当每个视频播完后立即播放下一个,中间不得有黑屏过程。 ##第一版方案 申明一个MediaElement 当每个视频播放完成后(MediaEnded)事件中指定下一个视频地址 这边就不贴出代码了 结果:每个视频交替时会有长时间空白期原因:1.设置MediaElement.source后视频缓冲需要时间(VlC就没有这问题 但是VLC在wpf下只能离屏渲染播放炒鸡卡 故放弃)。2.设置soucre后调用play()会出现不发调用成功的情况(应该正在缓冲加载,这个时候调用play()失效)。 放弃第一方案 第二方案 声明多个MediaElement每个初始化时设置source,当播放摸个视频时,显示对应的MediaElement并调用play(),否则隐藏并pause(); 结果:程序打开时开的要命,内存飙升。多个视频同时缓冲 崩溃。。。。 方案优化: /// <summary> /// MainWindow3.xaml 的交互逻辑...

06 Jan 2020

说一说C#使用websocket的一些问题

本位主要记录了奔驰项目中websocket通讯改造遇到的问题。 背景 之前终端与服务器通讯采用的是tcp/ip模式,但甲方对安全性要求极高不开放tcp通讯所需要的端口,无奈之下兄弟们决定采用websocket与终端交互,这样可以使用已有的80端口。 改造 原先的Tcp客户端结构如下(部分): public class TcpStocketClient { ///<summary> /// 客户端socket对象 /// </summary> public Socket Tcpsocket; /// <summary> ///...

18 Nov 2018

拼音输入法 快速输入带音调的字符

本文告诉大家如何使用本文提供的输入法快速输入带音调的字符 在教学的应用上,很多时候都需要混合输入带音调的拼音。但是无论是哪个输入法都无法满足需求,于是我就开发了一个。 使用方法 点击下载拼音输入法 下载的是压缩文件,需要解压缩到任意的文件夹,建议不要直接解压到桌面 打开拼音输入法,此时就可以进行快速的拼音输入 如输入 海 hǎi 可以这样输入 ha3i5 在每次按下元音的时候就可以选择数字对应。在使用的时候注意关闭原有的输入法,通过 shift 键关闭就可以 在不使用拼音输入法的时候,只需要关闭拼音输入法就可以。如果想要卸载输入法,只需要删除文件就可以。 下载链接:http://image.acmx.xyz/app/pinyin.zip 如果无法下载请联系我 如果觉得不好用,有任何建议都可以发邮件给我 参考 快速在课堂活动输入拼音带音调字符...

04 Jun 2016

Example content for posts

This demo page has been used from http://jasonm23.github.io/markdown-css-themes/. A First Level Header A Second Level Header A Third Level Header...

04 Jun 2015

Test Page

This is a test blog page where we can explore how to embedd images in the blog. Image example 1...