[成功]又逮到M$的BUG——十六进制模式下NumericUpDown错误解析,无痛修补!

作者:V君 发布于:2020-4-16 13:47 Thursday 分类:折腾手记

这次遇到的问题是在 WinForms 中使用 NumericUpDown 空间的十六进制模式时,若输入了大于 7FFFFFFF 的值之后,控件会把值非预期地变为 0 的情况。

点击查看原图

TL;DR

  1. 引入 NuGet 包「Lib.Harmony」
  2. 这个文件搬入项目中
  3. 调用 DoPatch 方法

这样不用改变任何现有实现,问题就解决啦!

现在你可以出去了(pia

如果还有时间,可以听我扯扯

最近在折腾一个参数设置的页面,需要填入一系列16、32位的十六进制数值,为了方便操作我就选择了 NumericUpDown 控件。首先将值范围设置成 0 到 65535(0xFFFF) 和 4294967295(0xFFFFFFFF)然后愉快地拿去用了。但是没有想到调试过程中发现了这个问题,起初以为是粘贴的值有空格导致拒绝接受,又尝试手打还是不行,摸索发现是超过 7FFFFFFF 就会触发。

进入解决问题的模式,先在咕狗上查找解决方案,然后就找到了继承并重写的方式。嗯问题的原因找到了,是 WinForms 控件的实现有 BUG,问题也解决了,既然咕狗能找到解决方案,那就不要发表内容重复文章污染互联网!(当时我压根没想过要发表出来

然鹅,这种方式并不适用于所有情况,比如对于封装了原生控件的界面库,就不能使用继承并重写的方式了,比起魔改 DLL 或者找到库源代码改掉,然后驮着到处跑,还是寻找另一种路子来解决这个问题吧。

一个鬼点子冒出来:能不能把跑起来之后把方法替换掉?这样无论是直接使用还是封装使用的情况,统统都把这个问题解决掉。又是一阵咕狗,然后就找到了 Harmony 库,如其名「和谐」,解决 BUG 于无形之中,达到不用修改现有实现、无痛修补代码的目的。

标签: 软件开发 C# bug

评论(0) 引用(0) 浏览(35)

通过嗅探标准输入输出来了解VisualGDB烧录操作

作者:V君 发布于:2020-4-12 13:55 Sunday 分类:折腾手记

这篇文章主要面向的是和我一样不熟悉 GDB 的人,请已经熟练使用 GDB 的老鸟不要笑,或者来看看我是怎样嗅探标准输入输出的也还凑合吧。

最近用起 VisualGDB 之后,总算从 Keil 的地狱中逃出生天,开发过程的确是很爽了。然而,如果仅仅是程序烧录到单片机也要装一个 VS 带上 VisualGDB,还得拿到源代码?很显然实际量产不应该这么做,理想的方式应该是将编译后的程序用烧录工具刷入单片机。

好奇心使我对这个过程产生了兴趣,从调试器适配的时候提示下载 OpenOCD 能看出 VisualGDB 是透过它来调用 ST-LINK 的,进一步又发现 OpenOCD 的另一边由 GDB 来操作。命令行参数可以用 Procexp 轻松获得,但进程启动之后的就全都是通过标准输入输出流来操作 GDB 了。

因为使用 GDB 是个过于庞大的课题,就懒得去学了,短时间内也不会用得顺手吧(如果懂得如何使用 GDB 的话还用得着 VisualGDB 么?

想知道 VisualGDB 如何操作 GDB 来烧录程序。首先去咕狗找找标准输入输出的捕获方法,不断换关键字兜了几圈回来没有一点收获,甚至一点线索都没有。

一拍脑袋,那就搞个透明代理来记录双向传递的内容吧。于是就写了个简单的标准输入输出流嗅探工具,还上传了一个直接可用的二进制文件,将原来的 EXE 改名扩展名前面增加 -real,例如 GDB.EXE 改成 GDB-real.EXE 然后用嗅探工具冒充它,启动之后就会在旁边产生名为 GDB.EXE.stdio-sniff.yyyymmdd-HHmmss-fff.log 的文本文件,将命令行参数标准输入标准输出错误输出记录到里面。

这样问题就解决了——原来烧录要用 GDB 的 load 命令。

然后进一步尝试离开 VS 环境独立运行,将 OpenOCD 和 GDB 以及编译好的程序搬到一台没有环境的机器,装好 ST-LINK 驱动,按照嗅探来的操作走一波,嗯嗯,吼!现在离开 VS 环境也能烧录了!

标签: 软件开发 C# 命令行 cmd 多进程 控制台 调试技术 软件故障诊断

评论(0) 引用(0) 浏览(29)

开始接触 STM32 —— Keil μVision 和 Visual Studio 相比太难用啦!

作者:V君 发布于:2019-12-31 10:59 Tuesday 分类:折腾手记

最近开始摸STM32,用 Keil μVision 来编写代码和调试。单片机型号是 F103 用 ST-Link/v2 以 SWD 的方式下载和调试。尽管 Keil 在占据的市场份额不小,但对于我这个被 VS 宠坏了的家伙来说,太难用啦!先列举些槽点,然后再看看有没有代替方案,如果能用 VS 来搞 STM32 开发就好咯……

吐槽:文档页签不能拖动
吐槽:编译、下载、启动调试,似乎不能一气呵成,得分开操作
  但愿是我不知道怎么配置一键,难道大伙们都能忍?
吐槽:智能感知……只能说是聊胜于无吧,尽管默认绑了 F12——
  可以转到定义,但在找到多个重复定义时,你蹦出一个符号窗格给我……
吐槽:项目 wide 搜索,貌似没有像VS那样列出匹配,只能上一个、下一个来导航
  但愿又是默认不启用的功能,只是我不没调出来……

代替方案?起初想到用 VsCode 来编辑代码,然后再回到 Keil 调试,考虑到 C 语言过于依赖环境,多一个少一个符号定义都会发生很大变化,估计 VsCode 的智能感知估计也不会好到哪里去吧……用各种关键字喂咕狗,找到一个叫做 VisualGDB 的扩展,主页上提到可以用来搞 STM32,但目前还没有试试看能不能用……(咕咕咕)后话:剁手买了正版,很香!

月底了,不刷存在感会觉得很方,必须凑合着发点什么出来

标签: 软件开发 嵌入式

评论(2) 引用(0) 浏览(180)

Xamarin Android 新手历险记之 AccessibilityService

作者:V君 发布于:2019-11-30 19:49 Saturday 分类:折腾手记

最近开始折腾 Android 的原生功能,想获取显示在屏幕上的界面元素。说到 Android 还想用我大 C♯ 去写,当然就是 Xamarin 啦!和往常一样,还是从 TL;DR 开始,然后再展开详细。

- TL;DR -
1. 在项目中新增一个类,本例命名为 MyAccessibilityService
2. 使其继承于 AccessibilityService (Android.AccessibilityServices)
3. 追加必要的 Attribute ,如 Service、IntentFilter、MetaData
4. 重写 OnServiceConnected 方法增加 SetServiceInfo 调用
5. 重写 OnAccessibilityEvent 根据 ServiceInfo 做对应动作,达到目的

- 展开 -
1. 略 (o ‵-′)ノ”(ノ﹏<。)
2. 略 (o ‵-′)ノ”(ノ﹏<。)
3. 这里可以稍稍展开
 ✸ Service 特性主要是 Label 和 Permission
  > 用 Label 来指定服务的显示名称
  > 用 Permission 指定必须的权限 BindAccessibilityService
 ✸ IntentFilter 喂进去一个 "android.accessibilityservice.AccessibilityService"
 ✸ MetaData 喂进去 "android.accessibilityservice" 和 Resource = XML 资源路径
  > XML 路径一般是 "@xml/accessibility_service_config",在对应地方写好配置文件即可
  > 为了能访问界面元素,确保在配置文件中启用 android:canRetrieveWindowContent
  ⚠ 注意 MetaData 第一个参数写错不会有检查,只会让服务不按XML配置文件工作
4. 这里主要是创建一个 AccessibilityServiceInfo 实例,然后喂给 SetServiceInfo 方法
  > Flags 属性确保有 RetrieveInteractiveWindows 位
  > EventTypes 用来给接下来的地方做事件筛选,比如用 WindowsChanged
5. 到这里就可以开始搞事情啦
  > 使用当前对象的 RootInActiveWindow 属性获取界面元素的树状结构根节点

- 再稍稍补充一下 -
如果只有 Service 而没有主界面,那就得手动跑到系统设置的辅助功能去启动服务。
有的国产Android手机系统界面被魔改得连辅助功能入口都被砍掉,这太尴尬。
我们可以在主界面做个按钮来导航到辅助功能设置:
1. 使用 Android.Provider.Settings.ActionAccessibilitySettings 实例化 Intent
2. 将其喂给 StartActivity 就可以实现捷径了

- 感受 -
这次能分担给大家的东西并不多。
我不会说因为 MetaData 第一个参数写错,然而没有报错,也获取不到界面元素,让我花了很多时间才找到问题所在。这个细节上咕狗做得很不厚道呀……

说好的每月一篇文章,这次有点踩线呀,虽然创建时间是19点,但发布时已经超过零点了,咕咕咕

标签: 软件开发 C# Android

评论(0) 引用(0) 浏览(235)

初体验.NET Core 3.0,Core新特性和传统Framework的差别

作者:V君 发布于:2019-9-30 17:21 Monday 分类:折腾手记

这次不是解决问题,因此不像往常那样有TL;DR,那就做个TOC吧

- TOC -

  1. 框架程序集(差别)
  2. 接口默认实现(新特性)
  3. 编辑并继续(差别,已更正)
  4. 通过SSH远程调试(新特性)
  5. 项目文件(差别)
  6. 嵌入资源(差别)
  7. ASP .NET Core(差别)

- 0.先扯扯 -

最近更新了 VS2019,终于有机会接触 .NET Core 3.0,在看官方文档前先行体验一波,体验过程不断收集发现就有了本文的TOC,如果你去看文档,会发现有少量文档未提及的差别,也为撰写本文提供了动力。主要从个人体验总结。

- 1.框架程序集(差别) -

从新建第一个Core项目开始,和传统Framework的差别就能体现出来,Core已经自动把整个系统类库的所有程序集作为SDK引用到项目中,不像从前需要手动引入各种系统类库程序集。

- 2.接口默认实现(新特性) -

早在半年多以前就听说,C♯ 8.0 将能够在接口中定义包含方法体的方法,这个特性名为「接口默认实现」,也是打动我,使我投奔Core的诱惑之一。亲手操练之后发现,现在不仅能在接口中写实现方法,更能定义常量、甚至还能写静态方法,昔日的接口扩展方法将可以用默认实现代替。

- 3.编辑并继续(差别,已更正) -

这个差异在16.3.0得到更正,现在已经能在改变当前语句的同时将代码变更应用。(请无视这一条)编辑并继续:在调试中命中断点停下来,编辑代码,改变当前语句并继续执行。这里有点细节和传统不一样,需要改变操作顺序,会稍稍造成一点体验差异。传统Framework调试时我们可以按照 命中断点→修改代码→拖动箭头或者使用上下文菜单来改变接下来要执行的语句,拖动在改变语句的同时,代码变更会生效,使我们能够执按修改如期执行;到了.NET Core就有点不一样了,修改完代码之后不能紧接就着改变当前语句,这会实代码变更的提交动作被跳过,执行的行为和看到的代码将会不一致,我们只能继续往前走一步才生效。操作顺序就变成 命中断点→改变当前语句到要修改的代码前→修改代码→继续执行。

- 4.通过SSH远程调试(新特性) -

在过去要调试运行在Linux上的.NET应用程序,只能依靠第三方调试器,比如之前提到的MonoRemoteDebugger,第三方工具的体验和稳定性都远远比不上官方集成功能。现在我们可以通过SSH的方式直接附加到远程进程了。

- 5.项目文件(差别) -

过去的C♯项目文件记录着所有已包含的文件,而且变更后VS会重新载入项目,动作有点大。在Core之后有了极大改善,项目文件不再一一记录包含文件而是引入默认行为,将项目目录下的文件以扩展名对应默认生成行为的方式默认包含到项目中,如果有变更则仅记录变更的项。在项目文件变更后也极大地减轻了重新载入(刷新、应用变更)项目的动作。

- 6.嵌入资源(差别) -

这一点还没有查到相关文档。受影响的地方是生成操作为「嵌入的资源」的项,若和旁边的.cs文件同名(任意扩展名),则会生成与.cs文件中定义的第一个类全名的嵌入资源,且不带扩展名。若在.cs文件旁边有两个同名(不同扩展名)的文件设置为嵌入资源,将引发重名编译错误。这个行为和传统Framework不同。

- 7.ASP .NET Core(差别) -

关于ASP.NET Core和传统ASP.NET的差别太多,这里就简单点一下个人感受。对于ASP.NET Core而言Web服务器不再是必备环境,引入了SelfHost的工作方式。HTTP Runtime格局也有巨大变化,传统ASP.NET想要以最简单粗暴地方式处理请求需要引入HTTP模块,到了ASP.NET Core,新建一个空项目就是一个空的回调并传入HTTP上下文给你处理,简单粗暴更上一层楼了!

差点以为这个月会打破惯例至少发表一篇文章…

标签: 软件开发 C#

评论(0) 引用(0) 浏览(253)

Powered by emlog 去你妹的备案 sitemap