![](https://img-blog.csdnimg.cn/20201014180756923.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
C#编程
文章平均质量分 68
zxy2847225301
毕业于广东工业大学,多年C#一线开发经验,熟悉常用数据库
展开
-
利用C#和Snap7工具模拟S7通信(包含DB地址讲解)
但KepServerEx是收费的,而且模拟的DB块超过64就不行了,当然Snap7在本文中也是只能模拟DB1、DB2和DB3的数据,但Snap7提供了C#版的运行程序,完全可以根据需要修改源码完成要模拟的DB块(由于有一个项目需要,我已经尝试过修改源码成功模拟DB100、DB101、DB102和DB103的数据,后面有空在把代码分享出来)上图中第1个红色方框的十六进制地址为0000,第2个红色方框十六进制的地址为000F,第3个红色方框十六进制的地址为0012,地址排布相信你能看得懂。原创 2024-06-18 21:25:52 · 1131 阅读 · 0 评论 -
Dnspy附加进程调试---代码被优化及无法获取局部变量
Dnspy附加应用程序调试,代码被优化或者无法获取局部变量原创 2024-05-10 10:01:15 · 486 阅读 · 0 评论 -
一个巧用委托解决的问题(C#)
我是做桌面医疗软件开发的,前段时间在做一个需求。在签发检验项目医嘱时,调用第三方接口,然后带出检验项目对应的采血管医嘱,生成医嘱时,需要调用UI界面的一个方法来获取到医嘱序号,不然会导致报错,而调用医嘱接口的逻辑时在业务逻辑层,不在UI层,所以无法直接调用到UI界面的方法获取医嘱序号,为了遵循系统原来分层的架构,我们不能把调用接口的逻辑放在UI层。业务逻辑层和UI层之间还嵌套其它的交互层,医嘱号的数据类型是int,所以想要在业务逻辑层获取到UI层的医嘱序号,我想到了C#自带的Func委托。原创 2024-04-10 17:29:01 · 367 阅读 · 0 评论 -
利用Winform实现电压表或电流表
本文的内容是搬运而来,还是国外的资源容易获取,不像国内的,遮遮掩掩,各种想让你掏钱。1 新建名为WinformDemo1的winform项目,.net framework选择4.0。2 新建名为AnalogMeterControl的类,并编辑如下。3 生成项目,在工具箱中就可以看到该自定义控件了,如下图。MaxValue是刻度最大值。MinValue是刻度最小值。Value是设置指针的值。好了,本文到此结束。转载 2024-04-03 16:26:19 · 146 阅读 · 0 评论 -
利用Winform实现简陋版的温度计(仅供参考)
本人水平有限,如有写得不对的地方,望指正。为了简单化,做了一个简陋版的温度计控件,有点丑哈。1 新建名为WinformDemo1的winform项目,.net framework选择4.0。设置属性值时同时调用Validate()方法,会触发OnPaint方法进行重新绘制控件。2 新建名为ThermometerControl的类,并编辑如下。3 可以设置它的属性值,Temperature属性是温度值。3 生成项目,在工具箱中就可以看到该自定义控件了,如下图。好了,本文到此结束。原创 2024-04-03 16:08:19 · 369 阅读 · 0 评论 -
利用Winform实现文字滚动(仅供参考)
Label的位置在最右边时,位置的坐标为(自定义控件的Width,Label的y值);Label的位置在最左边时,位置坐标为(0,Label的y值),所以Label在X方向上的值只能在0到Width之间变化。1 先自定义一个继承UserControl的控件,再放置一个Label控件,加一个定时器定时更新Label的x轴的位置即可。Speed是滚动的速度,1到100,如果设置的值小于1,则会自动重置为1,如果设置的值大于100时,会自动重置为100。本人水平有限,如有写得不对的地方,望指正。原创 2024-04-03 15:52:34 · 419 阅读 · 0 评论 -
通过C#和KepServer完成模拟S7协议通信
通过关键词KepServer、C#搜索,发现出来的文章都是关于OPC的,好奇怪,在搜索资料的过程中,了解到了软件博图(不好装,PLC编程的,要求电脑性能高,对操作系统有要求,动不动装不成功,直接劝退了我)、PLC仿真软件。本文作者水平有限,如有写得不对的地方望指正,我以前是做his开发的,没有上位机开发的工作经验,以下内容仅供学习参考使用,趁着有时间就学习一下,没有硬件PLC,只能用KepServer来造数据了。1.5 打开visual studio 2019。好了,本文的内容到此结束。原创 2024-03-17 18:14:20 · 759 阅读 · 0 评论 -
EF Core入门例子(以SqLite为数据库)
1 新增名称为EFCoreDemo的.net core控制台程序,版本选择.net core 2.1,项目不能放到带中文的目录下,不然到后面执行Add-Migration命令时会报如下的错误。上面的的KnowledgeDataBase.sqlite为SqLite的数据库名称。由于用的是SqLite数据库,会在项目中生成一个名为。6 打开程序包管理控制台,好了,本文的内容到此结束。原创 2024-02-02 11:27:13 · 1099 阅读 · 0 评论 -
dnSpy调试工具二次开发2-输出日志到控制台
NewTestScreen类Execute方法的outputService.Value.Create获取到写日志到控制台的接口,就是借鉴了类OutputLogger.cs中的Initialize_UI方法中的。dnSpy.Debugger项目下的ToolWindows\Logger目录下的类OutputLogger.cs。生成dnSpy项目,并点击dnSpy的"测试新增"菜单,可以看到成功输出了日志到dnSpy的控制台。在LogEditor.cs的这三个地方打上断点。好了,本文的内容到此结束。原创 2024-01-27 21:24:22 · 556 阅读 · 0 评论 -
dnSpy调试工具二次开发1-新增菜单
2 在名为dnSpy的项目下Properties目录的资源文件dnSpy.Resources.zh-CN.resx新增字符串资源(这里配置不同国家语言的资源文件,我的操作系统是中文,所以编辑的是dnSpy.Resources.zh-CN.resx),键的名称:Menu_TestNew 键值:测试新增。其实上面的Header就是绑定到资源对应的中文名称,所以这个一级菜单的名称将会是:测试新增。3 在名为dnSpy的项目下Menus目录的类文件AppMenus.cs新增一级菜单类。原创 2024-01-06 17:47:39 · 1239 阅读 · 0 评论 -
dnSpy调试工具断点信息是保存在哪里的呢
本人是C#开发,dnSpy工具用的比较多,有时候想把有用的断点信息保留下来,挪到别的机器上也能使用。3 打开dnSpy目录,可以看到一个名为dnSpy.xml的配置文件,我们的断点调试信息就保存在这个文件下,当然,那天你看得不爽了,可以直接删掉这个配置文件,下次还会自动生成的。接着去找注册表,也没找到,没办法,只能阅读dnSpy的源码了,经过一翻努力,被我找到了。2 在打开的目录中,我们可以看到一个名为dnSpy的目录(如果没有这个目录,要先打开dnSpy.exe后关闭就可以看到该目录了)原创 2023-12-28 13:18:51 · 596 阅读 · 0 评论 -
调用别人提供的接口无法通过try catch捕获异常(C#),见鬼了
通过反编译看了一下"调用封装CA签名接口的代码块"对应的代码,它的大概处理流程是这样的:先通过Spring.Net接口调用CA签名的业务逻辑,记为业务逻辑A,业务逻辑A的实现流程如下:通过反射,拿到对应的CA签名的实现类(因为我们这边的代码需要兼容多个CA签名的厂商),我们这边对接的是网政通的CA,我这边就只介绍一下它的大概流程:先获取提供接口的CA用户的用户信息,记为步骤1;4 是不是在不同的AppDomain的异常,就捕获不到,后面也尝试过了,也是能捕获的。原创 2023-12-10 12:02:34 · 1326 阅读 · 0 评论 -
C#动态拦截并覆盖第三方进程的函数,实现函数篡改(外挂)
TargetClient.TargetTestClass这个要被篡改方法的TargetTestClass类的全路径(即TargetClient.exe客户端中的类TargetTestClass的全路径,即命名空间+类名)这就可以干很多坏事了,如把别人的系统登录方法该篡改了(不管是混淆过或者没被混淆过的代码,都有方法拿到,这里就不展开了),你懂的。原创 2023-11-10 17:52:34 · 836 阅读 · 1 评论 -
把wpf的窗体保存为png图片
昨晚在stack overflow刷问题时看到有这个问题,今天早上刚好来尝试学习一下。1 新建.net framework 3.5的wpf窗体程序。原创 2023-11-07 09:21:20 · 857 阅读 · 0 评论 -
深度学习框架TensorFlow.NET之数据类型及张量2(C#)
TensorFlow中数据的基本单位为张量,前面例子中我们操作的变量或者常量都是属于张量的一中,我们可以使用张量表示标量(0维度数组)、向量(1维数组)、矩阵(2维数组)、RBG图像(3维数组)、视频(4维数组)等n维数组。如:tf.add(number1, number2)是对number1和number2的值相加,可以相加,都是int类型。通过tf.constant(2,name:"常量2名称")声明了一个值为2,名为'常量2名称'的整型常量。声明了一个值为10,名为'int变量'的整形变量。原创 2023-11-05 18:33:05 · 1627 阅读 · 3 评论 -
深度学习框架TensorFlow.NET环境搭建1(C#)
2 在tf.constanct(str)报未能将对象引用到实例,应该是TensorFlow.NET包和SciSharp.TensorFlow.Redist包的版本对应不上,应该多尝试TensorFlow.NET的版本,直到不报错为止。2 分别安装TensorFlow.NET包(先装)和SciSharp.TensorFlow.Redist(后装),版本兼容性不好,最好安装的版本与我的保持一致,不然报错到你怀疑人生。(异常来自HRESULT:0x8007007E)window10 64位。原创 2023-11-05 11:13:22 · 2088 阅读 · 0 评论 -
带你人工识别C#开源库BarcodeLib生成的一维码Code128
1 先把数字如:6986081进行编码,两个数字作为一组进行编码,这里数字69一组,86一组,08一组,剩下一个1就比较特别,源码看得不是很懂,有特殊的规则进行编码。3 通过C#的绘图类Graphics的画线方法.DrawLine进行绘制线,如要绘制10110010000编码,碰到1就纵向绘制一定宽度的直线,碰到0就不绘制直线。通过编码10011100110 查找本文后面的编码表得到的数值为17,但前面有一个CODE_A,应该编码为1。2 把两位数字通过查表法进行编码,编码为11位的0或1数字。原创 2023-11-02 16:58:35 · 1026 阅读 · 0 评论 -
利用win32的GetLastInputInfo函数实现锁屏(C#)
前两天刚好看到群里面讨论这个问题,刚好看到我们系统也有这个功能,就研究了一下,我们这边实现这个功能的目的如下:当用户长时间不操作系统时,自动退出系统并退回到登录界面,想要使用系统,就得重新输入账号和密码。上述代码启用了一个定时器,定时1秒,其中lockScreenSecond是锁屏的秒数,即超过lockScreenSecond秒都没操作电脑就弹出锁屏界面。1 新建winform项目,项目名称为:LockScreen。运行程序后,不做任何操作等待10秒左右弹出锁屏界面。(检测鼠标的位置及焦点事件)原创 2023-11-01 16:31:11 · 960 阅读 · 0 评论 -
wpf资源Resources探究性学习(一)
你注意观察一下,上图中不同控件下的资源键值key都为txt2,但都不报错,那以那个为准呢,我们大概都能猜到是从里到外进行寻找,如果在Button控件上使用key值,则会先找Button自己定义的,没找到再往上寻找StackPanel中声明的资源,如果还是没找到,则会再会往Window标签寻找。在这里用到了Binding,Source指定的是静态资源stu2,Path指定要显示对应的那个属性,这里是要显示Student2的Name属性,运行程序没有任何问题。assembly=程序集名称"原创 2023-09-20 22:14:33 · 808 阅读 · 0 评论 -
Winform直接与Wpf交互
2.1 在前文的基础上继续操作(当然咯,这三个PresentationCore.dll PresentationFramework.dll WindowsBase.dll引用是少不了的),新建项,模板选择'用户控件(WPF)',名称为WindowTest。winfrom通过新建项的方式不能直接新建wpf窗体,但我们可以使用新建的wpf的用户控件,然后略做修改就行,当然你也可以添加已有的wpf窗体,这样就可以省略2.1步骤的操作。以非模态的方式(即Show的方式)弹出wpf窗体。原创 2023-09-19 15:58:07 · 1818 阅读 · 0 评论 -
代码控制鼠标光标移动并点击和代码模拟键盘按下(C#)
想要在'触发键盘按下'按钮(名为btnPress)触发自动按钮逻辑,就得通过PointToScreen把控件的坐标转换为计算机桌面的坐标(以前做Unity 3D的时候经常看到这种骚操作),然后把转换后的坐标作为鼠标光标的位置,最后通过模拟鼠标左键按下和抬起,一定要鼠标按下和抬起一起使用才有效,因为鼠标按下和抬起同时完成才算实现鼠标按下的逻辑。演示效果3: 点击按钮,然后控制鼠标光标移动到演示效果1中的那个按钮的位置上,并实现点击,接着就会看到效果1中的效果(模拟键盘输入,把输入的内容显示到文本框上)原创 2023-08-13 18:50:02 · 3164 阅读 · 0 评论 -
打印Winform控件实现简陋版的分页打印(C#)
为了简单起见,纸张大小,打印机等信息按照默认的来,本文的实现方案是:打印Panel中的控件信息,循环进行打印,打印完一张,把信息重新填充到对应的控件上再继续打印。说是要把控件里的内容重新赋值给另外一个控件myControlToDisplay,大概看了一下提供的代码,感觉代码不全,就没有照着来试了。从上往下,就像叠罗汉一样,直到截取并打印完毕,这只是个人的想法,还没验证。读取txt记事本里面的内容,并分页打印,提供的代码。作者的水平有限,如有错误,望指正。好了,本文的内容正式开始。代码太简单了,就不解释了。原创 2023-07-30 17:18:58 · 1041 阅读 · 0 评论 -
打印Winfrom控件实现简陋版的打印(C#)
好了,本水文到此结束。后面还有继续深入研究的,如打印单个控件TextBox,Button,还有实现分页打印等。通过截图的方式进行打印在前面的文章后面已经介绍过,有问题。原创 2023-07-30 15:33:14 · 1171 阅读 · 0 评论 -
Winform中的线程Threading in WinForms(翻译)
而这两个消息队列的区别是,发送到Send Message队列的线程(记为a),把消息发送到队列后,该a线程会堵塞并等主线程执行完消息队列中的消息后,该线程a才会往下执行。同样的,Form_Load中的for循环和AddControl中的for循环并不会并行执行,Form_Load中的for循环和AddControl中的for循环都在主线程执行(即在同一个线程中执行),由于Invoke方法有堵塞的作用,所以会先执行AddControl中的for循环,再执行Form_Load中的for循环。翻译 2023-07-28 09:13:34 · 109 阅读 · 0 评论 -
利用Graphics的CopyFromScreen实现简陋版的打印(C#)
今天趁着有空,就查一下有没有打印Winform的Control控件相关的API,在Youtube中看到了一个视频与之相关的,视频地址:Print contents of WinForms Application using C# and VB.Net。前段时间,在做一个打印的需求,需要把Winform界面的控件及内容全部打印出来,但有一个比较坑的地方是,公司提供的打印API打印单选框,打印单选框时发现选框和内容总是有那么一点点不对齐,看着很别扭。可以看到,任务栏中的菜单都出来了。原创 2023-07-23 16:49:46 · 563 阅读 · 0 评论 -
配置legacyUnhandledExceptionPolicy属性防止处理异常后程序崩溃退出(C#)
依旧没找到解决的方案,上一家另外一个系统的代码就无法获取到了,但我看过,记得是在AppDomain.CurrentDomain.UnhandledException注册的事件中通过代码的方式Dump出文件,但程序依旧还是会崩溃。但我试了一下,并不好使,改变.net framework的版本都试过,不好使,可能是我操作的姿势不对吧。-------------------废话开始,可以跳过不看。-------------------废话结束,可以跳过不看。好了,废话到此结束,正式开始本文的内容。原创 2023-06-17 17:07:28 · 2293 阅读 · 0 评论 -
利用WinDbg查看堆栈中方法入参的值4(C#)
1 32位应用程序导出的Dump文件要用32位的WinDbg打开,想要没有那么多的问题,还得要求用32位的任务管理器导出Dump文件,32位的任务管理器的路径如下:C:\Windows\SysWOW64\taskmgr.exe。可以看到方法WindbgDemo.DownLoadBp.DownLoadOperation中的参数名称为url,对应的值的地址为:0x0000000003222bd8。本文目的,就是查看导出的dump文件中堆栈中的方法参数值,这样方便后续分析问题。threads查看线程。原创 2023-06-11 18:24:04 · 1340 阅读 · 0 评论 -
WinDbg安装入坑3(C#)
1 32位应用程序导出的Dump文件要用32位的WinDbg打开,想要没有那么多的问题,还得要求用32位的任务管理器导出Dump文件,32位的任务管理器的路径如下:C:\Windows\SysWOW64\taskmgr.exe。使用C#编写一段程序,并用64位的任务管理器导出为32位的Dump文件,试一下WinDbg Preview和老版的WinDbg在使用过程中的坑。又是提示版本不一致了,看着有戏,看看是不是64位的任务管理器导出的原因。可以看到导入成功,接着再来看堆栈信息,可以看到成功了。原创 2023-06-11 18:02:45 · 1902 阅读 · 0 评论 -
WinDbg安装入坑2(C#)
1 32位应用程序导出的Dump文件要用32位的WinDbg打开,想要没有那么多的问题,还得要求用32位的任务管理器导出Dump文件,32位的任务管理器的路径如下:C:\Windows\SysWOW64\taskmgr.exe。不管是使用.load C:\Windows\Microsoft.NET\Framework64\v4.0.30319\SOS.dll还是使用。可能是我们导入的sos版本不对,由于我们的应用程序是.net framework 3.5 的,可以试试。没有报错,再次输入!原创 2023-06-11 17:13:29 · 1723 阅读 · 0 评论 -
WinDbg安装入坑1(C#)
1 32位应用程序导出的Dump文件要用32位的WinDbg打开,想要没有那么多的问题,还得要求用32位的资源管理器导出Dump文件,32位的资源管理器的路径如下:C:\Windows\SysWOW64\taskmgr.exe。自动安装,安装完成后,在桌面左下角开始中搜索WinDbg即可搜索到,下载完毕后,试了一下,不用添加符号路径也能正常使用。当然,这种方式是每次打开WinDbg都得配置一次,可以使用环境变量的方式进行配置,我们使用到的是32位的安装包,一路傻瓜式下一步就行。原创 2023-06-11 15:57:25 · 3322 阅读 · 0 评论 -
winform的RichTextBox控件追加文本及图片(实现笔记录入和笔记搜索功能)
在工作中,在工作中,难免有一些笔记要记录下来,方便后续工作中快速找到。最加一个笔记的富文本,先new了一个空的RichTextBox(richTextBox),然后把文本加载进MemoryStream,new出来的richTextBox通过LoadFile方法把内容加载进RichTextBox控件,最后通过目标RichText(rtInput)的SelectedRtf属性值 this.rtInput.SelectedRtf = richTextBox.Rtf完成富文本的追加工作。好了,本文到此结束。原创 2023-06-03 17:04:58 · 2671 阅读 · 0 评论 -
利用C#实现动态替换桌面快捷方式对应的应用程序
3 遍历快捷方式,获取快捷键方式对应程序的运行路径,并与当前exe程序运行的全路径比较,如果相等,则表示拿到当前exe程序运行的快捷方式。公司有一个特殊的业务可能会用到这个,至于什么业务就不展开了。本文的内容作为备用方案。1 新建控制台程序,名为ApplicationQuickLink。4 把新的程序的运行路径赋值给快捷方式。1 获取当前exe程序运行的全路径。2 获取桌面的所有快捷方式。好了,本文的内容到此结束。原创 2023-05-01 19:43:49 · 1218 阅读 · 1 评论 -
Modbus相关知识点及问题总结
应用类似于温度或者湿度传感器的值,但我在淘宝中搜索了多个使用modbus协议的传感器设备,它们都是使用保持性寄存器,其实是并不严谨的,从这个知乎链接。:读输入寄存器,所谓输入寄存器是指寄存器数值只能由传感器输入的模拟量来驱动更新数值,数值是只读的;:读保持寄存器,可读写,可读多个或者单个寄存器内容,所谓保持寄存器是指寄存器数值可以读写,该寄存器数值用于输出模拟量;线圈和离散输入寄存器的状态可以使用一个比特位来表示,其他的一个寄存器的值需要用两个字节来表示(数据高位、数据低位):读取线圈寄存器的值,可读写。原创 2023-03-26 20:22:07 · 1901 阅读 · 0 评论 -
解决Winform的ComboBox下拉框鼠标双击事件无效的问题
今天碰到一个需求:就是鼠标双击ComboBox后,然后模拟键盘空格键按下,测试发现,在ComboBox可以展开下拉框的情况下,鼠标双击事件是没有用的。想要实现鼠标双击事件,需要利用到鼠标单击事件,在鼠标单击事件中判断(当前时间减去上一次单击的时间)是否小于某个值(如200毫秒),则认为是用户进行了鼠标双击。注意:其中采了一个很冤的坑,计算两个时间的间隔的总毫秒,用了TimeSpan的Milliseconds,其实是不对的,应该是TimeSpan的TotalMilliseconds。原创 2023-03-15 18:09:57 · 1928 阅读 · 0 评论 -
C#通过代码的方式模拟键盘按下
如何模拟键盘按键触发产生的事件,比如模拟按下Alt + F4 关闭当前程序,Ctrl+Shift 切换输入法等。可以通过win32api 键盘事件 keybd_event() 来实现。2、引用win32api键盘函数。1、定义键盘按键对应得键码。1)模拟QQ截图按键。转载 2023-03-15 13:06:01 · 5739 阅读 · 0 评论 -
Modbus协议初探(C#实现)
从上面的图3可以看出,配置的从站的起始地址为十进制的9,小于256,所以起始地址的高位位0,即十六进制的00,如果从站配置的起始地址为十进制的257,则起始地址的高位为1,十六进制为01,起始地址 的低位为十进制的1,即十六进制的01 ,即257=256*1+1。从上面的图3可以看出,线圈数配置为十进制的10,小于256,可以这样写10=256*0+10,所以这里线圈数的高位为十进制的0,即十六进制的00。表明是从站的地址,从上面的图3可以看到下位机从站的地址为十进制的1,所以这里为01。原创 2023-03-04 19:13:09 · 6037 阅读 · 4 评论 -
winform控件PropertyGrid的应用(使运行中的程序能像vistual studio那样设置控件属性)
像有些卡业务流程或者调用第三方的接口的业务逻辑,某些机器因某种原因需要临时关闭该功能,就可以使用该控件实现个性化控制了,我上一家公司是用一个表来存储这种个性化设置参数,这样就要向数据库中查询一次,有点浪费性能了。好了,下面就和我一起体验一下该控件吧,当然网上也有很多博客教程了,本文就简单意思一下就行,核心就是设置PropertyGrid控件的SelectedObject属性为对应的Control控件。代码中添加了自定义属性NewProp,属性上的标记信息用于程序在运行时显示的属性信息。好了,本文到此结束。原创 2023-03-04 11:44:02 · 1540 阅读 · 0 评论 -
在屎山代码中快速找到想要的代码法-锁表法(C#)
要对检验项目进行分方操作,我大概知道是对处方表met_ord_recipedetail(这是我们公司的处方表)的处方号进行修改,虽然找到"签署"按钮对应代码的入口,但里面的业务逻辑牵扯较多,再加上命名不规范以及多个功能封装在一个命名不严谨的方法里面,想要找到对处方表met_ord_recipedetail操作的那一小段代码逻辑,还是很费劲的。由于本人水平有限,文中有写得不对的地方请指正,本文的方法有些投机取巧,实在是没招的情况下可以酌情使用,如有侵权,请联系删除。从上图中我们就可以看到对应的堆栈了。原创 2023-02-18 11:03:00 · 2234 阅读 · 0 评论 -
Emgu CV4图像处理之形状 (三角形, 矩形, 圆形, 直线) 检测3(C#)
本文要实现的效果是从摄像头中采集图像,然后送进public static Mat ProcessImage(Mat img)方法进行图像处理。vistual studio 2019 (.net framework控制台程序)添加的dll引用和环境搭建的一样。win10 64位。翻译 2022-11-01 17:49:59 · 1229 阅读 · 0 评论 -
Emgu CV4图像处理之7行代码实现打开摄像头2(C#)
只需要7行代码,就能实现从摄像机中采集图片并实时地显示到窗体上。添加的dll引用和环境搭建的一样。win10 64位。翻译 2022-11-01 17:31:40 · 787 阅读 · 0 评论