再见Windows C++
我3年多以前写过一个小工具,是用来检测Windows操作系统的版本及其所安装的.NET Framework版本的,我用它来排查由于缺乏运行环境支持所导致的程序无法运行的问题。这个工具是用Visual Studio 2010的C++写的,为什么不用C#写?——很明显,如果一台电脑连.NET都没安装的话,那我这个小工具也运行不了啊。我后来还把这个小工具发布出来了:《Windows及.NET Framework版本检测工具》
如果这个小工具不算在内的话,我上一次写Windows C++程序是2011年11月,许多年过去了……“Windows C++开发”,更专业点说,应称作“基于原生Windows SDK的程序开发”,它区别于使用.NET、Java、Python之类的需要特定运行平台的开发(使用CLI的C++也不算) ,它曾经是我最擅长和钟爱的技术,我从2004年开始接触Windows C++开发,中间所有的工作,或多或少都跟这个有关系,这么算来,我对Windows C++的使用年限有足足7年……
人生中许多事情的发展总有很大的偶然性,“一句话改变人的一生”这种鸡汤传闻理智上看是很荒谬,但却又时时刻刻发生着。我是在高中的时候(1996年)看电脑报有一则笑话,里面有句话,“不懂你说的什么超级C++语言”,以此来表示一个人说话很难理解,当时我对C++完全不懂,但按照字面上意思去看,肯定是先有C,然后有C+,接着才是C++,一个比一个难!难就意味着牛逼,那是肯定的,你想想那些奥林匹克竞赛的题目哪有容易的?解开难题才显得自己牛啊!就这样,我把C++和“难”和“牛逼”关联了起来,且接下来很长一段时间里都一直这么认为。
我获得第一份正儿八经的程序员的工作是2003年,那时候在一家外包公司做C开发,C++仍然只懂点皮毛,但无聊单调乏味的外包开发工作激发了我往更深处学习的欲望,我决定好好学学C++,一来自己有C的基础,二来身边有位懂C++的同事,有什么不懂可以请教他啊,最关键的还是之前植在自己内心深处的这个观点——这玩意儿牛!就这样,我买了几本书,开始了漫长的学习旅程。而在此前,我曾经用过Visual Basic 6.0,我的毕业设计就是用它来做的,这东西多简单啊!拖拽几个控件,一个界面就好了,双击下按钮,就可以编写它的点击处理方法,而对应的Visual C++ 6.0咋就这么难用呢?我觉得一定是我努力不够,难学,就意味着里边学问深,需要花更多的力气,就这样,我艰难的啃着书,指望有天能成为传说中的大神。
这种学习无疑是低效的(当然我领悟出这个道理时已经是数年后的事情了),为啥?想想看我学VC++的动机是什么?想学点难(牛逼)的东西,然后找份更Exciting的工作,我缺乏明确的方向,我其实并不知道什么时候应当使用VC++,什么时候应当用C,也不去了解对一个问题是否还有更优的解决方案,闷头闷脑一味看书学,这样的学习,用武侠小说的套路来说,就是走火入魔的节奏。但现实毕竟是现实,和武侠小说还是有挺大差别,我的努力虽然低效,却并非无用,在04年的一个炎热的夏日里,我离开了那家外包公司,原因嘛,一半是被逼,另一半是我确实很想走了,而下一份工作便是真正地使用牛X的Visual C++做牛X的开发!
在新的环境中,我长进很快,一个人瞎折腾和有明确的工作目标真是完全两个不同的世界。事实上,在那家公司的很长一段时间里,我并没主要在做VC++,而是在做Linux的C++,程序运行在服务器上,领导之所以这么安排主要是看中我之前做过服务器端的C开发,且也是运行在类似的UNIX环境上的吧,再就是我做事情比较仔细,在那个时候,Linux C++并没有集成开发环境,写程序的方式就是用CVS(没错,SVN还没起来)把代码拿下来,用UltraEdit之类的文本编辑器改好,用SSH上传至服务器,然后Make一下,根本不会设置断点调试之类的,程序有问题怎么办?靠日志,以及崩溃出错之后去靠gdb检查dump文件,现在回想起来这么落后的方式我居然能把程序做出来还真是个奇迹……也许也正因为这样,我对Linux的C++开发并不看好,所以在后面说服了领导把我们的服务器也换成Windows的,这样天下就太平了,领导同意了。
在之后的日子里,我就大部分时候都在用VC++了,VC++6的那个看似简陋无比的界面,一度是我装逼的利器,我得意地宣称它简陋的背后埋藏着高深的技术,而且运行速度飞快,而微软新出的VS2003、VS2005之流慢得跟个蜗牛似的,面对公司那些做Java开发的同事,我表现得挺不屑,因为我的工具很难用(牛逼),他们搞不定,而他们做的JSP(我之前有接触过),我要认真学的话很快就能学会了……人生有许多的“轮回”,特别是对一件事情的看法,每个人在不同的时期往往差别很大,甚至截然相反。几年后我回想起当初这些想法,真是后悔不已,因为在后面的职业生涯中,VC++的使用场景越来越少,而能搞Linux C++开发的人待遇却很不错,做Java的人路子更广。
2006年我跳了一次槽,2007年又跳了一次,在这两家公司里,我都是比较纯粹的VC++6的用户,直到2010年我再次跳槽的时候,距离VC++6推出的时间,已经有11年了,在这些年里,我尝试着去挖掘VC++的各种威力:
- 学习COM开发
- 深入学习Windows SDK,尝遍各个函数的调用
- 了解Windows内核机制,折腾各种工具
- 自学图形学,OpenGL,尝试全面优化公司软件的图表显示效果
- 尝试过做驱动开发(DDK),以能把电脑搞蓝屏为荣
- 居然还学过Windows汇编,写出过尺寸只有几个K却拥有强(废)大(柴)功能的小程序
- 吐槽MFC,尝试开发一套更实用、简洁和漂亮的UI框架
- 等等等……
但遗憾的是,这些东西工作中都用不太到,后来都忘记差不多了,除了一些DEMO之外就没产生过什么真正能派上用场的产品,工作对我来说大多数时候还是编写应用程序。那话怎么说来着?闭上眼看到无数的路,睁开眼还是走老路。也许你想知道我用来取代MFC框架的那套东西后来做得怎么样了,呵呵……弄了一段时间之后放弃了,因为做着做着发觉其实自己就是完完全全的重复造轮子啊,再弄下去一定是走MFC的老路,而且以我的水平,代码质量肯定远不如MFC的。
我不再使用VC++6是2010年,一来是VC++6确实太旧了,微软早就抛弃了它,而我想如果我再不做出一些改变,也是要被世界抛弃的了;二来是因为我接下来要从事的Windows Mobile的开发,根本没法用VC++6来做,Windows Mobile的开发和Windows开发有些差别,但大致上体验一致,Windows Mobile SDK只支持Visual Studio 2005和Visual Studio 2008,我果断选择了2008。一开始觉得它慢,各种不适,但适应这东西其实也就个时间的问题,有时候“觉得不适”甚至是妨碍自己前进的一种借口,听没听说过“要想进步,就不要总是活在自己的心里舒适区”这个道理?
Windows Mobile这个项目注定不能成功,因为这是个急速走向没落的平台,这是一起严重的押宝事故,我们在2011年11月停止了这个项目,然后我转入做.NET开发,如今想想这真是个好的转机,从那时候起,我涉猎范围渐渐变得宽广,眼界也渐渐开阔。用Windows C++做应用开发,这无疑是性价比很低的,引用别人的一句话:“你扶不正老人砌的墙,填不平新人挖的坑”,通常只用于一些比较特殊的领域了,如图形、游戏引擎、追求极致的基础算法以及驱动(准确说驱动开发用的是DDK而不是原生Windows SDK)。
一个做技术的人如何提高自己比较好?我觉得还是要跟公司保持一致比较好,公司要做什么,你就去做什么,针对业务问题,去寻找最妥当的解决方案,把这些问题都解决了,你的技术水平也就牛逼了。就像这个博客的副标题所说的那样:技术为解决问题而生!难度大的技术不等于牛逼的技术,看上去酷炫的技术也不意味着很有前途,而个人的喜好更加无关紧要,最关键的还是要解决公司的问题,我长期以来所走的弯路大多也是因为自己没能与公司的步伐保持一致。
回到本文开始提到的那个小工具,我用最新的VS2015打开它,更新了一些代码,发觉自己写起代码来真是很费劲,C++太难用了,而VS2015默认情况下居然不带安装C++,最新的Windows 10 SDK也默认不安装,也许微软觉得这些东西都已经很小众了。我把编译好的程序发给同事用,发现她的Windows XP系统运行不了,后来我才知道要把项目选项中的“Platform Toolset”改为“v140_xp”方可,至于更早以前的Windows 2000,那是根本没有办法了,除非使用更低版本的Visual Studio去开发了,当初的我总是想编写那种短小精悍零依赖的牛逼程序,如今的我早就不这么想了,很多旧的东西,该淘汰就淘汰了。
本文标题“再见Windows C++”中的“再见”,其实不是“告别”的意思,而是“再次见到”,如BEYOND的那首《再见理想》所表达的那样,Windows C++就像一把旧吉他,曾经陪伴我走过很长的路,后来不再用了,觉得已经不再适合,但偶尔我也会重拾情怀,回想起它一下,所以“再见”,但情怀归情怀,生活归生活,用和不用,那得看看要解决的是什么问题。
最后发布一下这个小工具的最新版,也藉此纪念Windows C++陪我走过的那些青葱岁月。
SysInfoDetector_exe.zip (可执行文件)
SysInfoDetector_src.zip (源代码, VS2015)