[公路]绝对光年 (14)

绝光年.jpeg

   
最近写了单稍程序,用于将固态硬盘的勾勒入量等消息显示在任务栏,最开始利用Windows
API也堪实现,但是当任务栏托盘增加的当儿,会叫掩,最终利用了DeskBand来兑现,填了广大坑。

第十三段(+):大同

自以呼和浩特火车站绝续续地睡了平夜,半夜列车顶站,阵阵轰鸣声把自己吵醒,当人流像潮水般下跌去,恢复平静的上,我才能够又入睡。
自己从不带来眼罩耳塞睡觉,在火车站里,我还是时刻警醒着。
一半夜间醒过来的时光,我发现姜来人不见了,只剩余行李在本人身边,我心头咯噔了一下。
以至自己望他迷迷糊糊地起厕所里面走下,我才松一口气。
人数一连会变的,而且转移得专程快,在不久前,我还当怀念怎么摆脱姜来,可是现在,我却忽然担心他会见不辞而别。

恍如清晨,人愈来愈多,睡眠让堵塞得专程之反复,我干脆不歇了。
自我以在洗漱用品在盥洗室里草草地清洁,冷水洗了脸后,整个人口还精神爽快。
本身进了点滴瓶咖啡回去座位高达,姜来也清醒过来。刚睡醒的客,看上去呆呆的,我递他同瓶子咖啡,他拿在手上,咕噜咕噜地均喝就。
“现在几乎触及了。”他带在一样嘴咖啡味问我。
“还早吗,现在7点非交。”我抬头看正在挂在站里之大钟表,慵懒地游说。
“我们几乎接触之列车。”
“10点35分。”
“我的圣,还要等这么老。我委后悔,昨晚怎么不错过停止快捷酒店呢?这无异过夜我都没有歇好,现在一身特别难让。”他站起来,伸了单懒腰。
“后悔呢后矣。你错过洗漱一下,精神爽快点。”
“好吧。”他没法地游说。

早7点下,火车站挤满了总人口,行李堆得四处都是,我带来及耳机,看正在电子书,对斯世界不闻不问。
姜来继续看他的《在中途》,不理解,他尾随着书里的中坚去到啊地方了。
我身边的位子来回换了一点波人,他们为下来,吃着喝在说在笑着,然后还要盖直达火车,在车上继续吃着喝着说在笑着,到另外一幢城市,过在相同的生活。
到头来熬至了10触及35分,我们上上了K1278次于列车,下同样站是山西大同。
恰巧上车,姜来对自家说:“我们这次来内蒙古,都尚未亲自踏上这里的草地,有接触可惜。”
自说:“没什么可惜的,我们共臻,能顾更多的草野,去内蒙古底草原,最好的方,是自驾,我们且无见面开车,难道在草原上徒步也?”
“我们无可知骑车马吗?”姜来问。
“你晤面骑马也?”我问话。
“不会。”
“那尔要么别考虑了。”

当我们的火车徐徐往南开夺,我问姜来对山西发出什么概念不?他说,不亮,应该充满地还是煤矿吧。
自家说,你擦了,那不让煤矿,那给金矿,挖出来的,都是钱。
即句话,其实不是本身说的,这是自我一个山西的好情人——小于,告诉我之。
他家做煤矿工作,他们管煤矿为黑金。他告诉自己,小时候,几乎每一样户山西户,都有家室以及亲戚,间接或直接地从煤矿生意。
若是他家,更加疯狂,父辈整个家族,从老到少,都一门心思地投入到煤矿事业的建设,按照现行之术语,应该给煤矿产业链全覆盖,从开煤炭,煤矿器械,到煤矿运输,甚至是煤矿提炼,都当他家门之幂下,蒸蒸日上,红红火火。
他家里有着人数犹对煤矿有类似神经质的热情洋溢。
以山西从煤矿行业之人,最害怕的即使是吃上矿难,也不怕是所谓的见红,所以,吉祥的新民主主义革命,在他的家门,并无讨喜,他说她们下,从来不穿红色的行装。
转,也得以想像,他的宗,最爱的颜料,肯定是黑色。
他和我说,别人家过新春底时,挂的还是辛亥革命的春联,唯独他们家族,用底凡黑色的张,再下放上鲜亮的金漆字。
本身一筹莫展想像黑色的春联挂于家门口的典范,但自己能够设想,如果世界一样切开漆黑,那该多可怕。

低于是家族内部,唯一无从煤矿事业的食指,他为逃离家里人的律,高三回报志愿之上,他选了漫长的海南岛,毕业后,他捎到了上海办事,从此,和煤矿脱离。
当时几年,国家积极进步卫生能源,对煤矿进行控产减产,小于家里逐渐由明走向衰老,煤矿关了一个而一个。
仅次于很幸运地逃离了山西,可是,那些与煤矿相依为命的人口,则并未那幸运,他们只得无力地,和煤矿共没有获得,就像那些,曾经埋藏了不少遗体的,深不见底的煤矿坑。
这样的故事,在山西遍地都是,就如漂浮于山西氛围中之煤屑粉,每一样人数之透气,都带在淋淋的鲜血。
随即就是本身对山西,简单而强行的记忆。

我们的火车,从坪草地慢慢驶进高原地区,植被从草甸向常绿阔叶林渐变,人烟和山林一并茂盛。
打呼和浩特至大同,只待坐4独小时之列车,在车上小息一会就到达了。

大同到底是个小市,火车站等候的口耶非多,诺大的广场非常冷静。
下午的阳光将火车站广场以得滚烫,大同醒目比呼和浩特要炎热,我们出站之后,没倒多远就开冒汗,这与咱们以呼和浩特之体感全不相同。
鉴于火车站广场附近在征程维修,我们只要乘坐的公交得只要运动不行丰富之同段落路。
咱俩坐登山包,在同样长达无人穿行的征程及行走,路一侧都是把小型事业单位及不怎么个体户的门店,店主大多以缓,少数会晤三叔简单简单成团于合打牌,看到我们走过,也未会见多扣一样眼。
网上里说山西之GDP已经是全国倒数几名叫,看来也非是什么虚假消息。
自从火车站到我们已的青旅,其实不远,我们达成了公交后,姜来提问我:“你确定这家青旅不是伪旅馆为?”
本身无知底怎么对这个题材,一往被蛇咬,十年怕草绳,可是除了青旅,没别的选择。
既来之则安之,我本着姜来说:“我在大网站预约的,应该无会见发生问题,我来看其小网上评价十分高,虽然未是蛮便利,但至少安全产生保。”
“我啊便顺口一问,反正杀未了咱便止快捷酒店。”姜来说。

交了青旅,一切正常,老板娘是独好年轻的中年妇女,接待我们的时候大和善。青旅里,住客很多,六凡里,几乎已满人。这家应该是下正常的青旅,我思念。
姜来还睡在自己的上铺,他开好上了上铺,他说,在上面,空气好。
屋子不老,三摆设左右铺床占据了大部分之上空,窗户外就是大同古城的步行街,隔在玻璃为能够听见外面商户循环播放的促销广告,就比如于洗脑似。
房中只有咱少只,其他的食指犹出去玩乐了。
看日还早,我管姜来打上铺拽下,带客到青旅旁边的本年古寺庙——华严寺。

自的生证明一直派上用场,姜来每次观看自身于是借学生证明还见面为我翻白眼,他见面说这么好之丁尚为此学生证真不苟脸。
如果无若脸都是次要,最要的凡,我能望下一大笔钱。
每当入口处,工作人员让自身展示学生证,姜来看我即将被罚,幸灾乐祸地游说:“这年头,长这么一直的大学生也是可贵一见。”
本人乐着让验票员出示学生证,她圈了自我平眼,笑着说:“不老不老,这小伙长得水灵灵的,走吧,进去吧。”
走进去寺里面之后,姜来絮絮叨叨地游说:“这个一直阿姨肯定是老眼昏花,都28东的人口,还水灵灵的,阿姨对你有意思吧,谢已,要无您就于了阿姨,在山西好生活吧,说不定阿姨家是煤矿主,你之后产生福了……”

华严寺历经千年的风浪,集结了三通向之花,在辽代的地基上,清代秀美的盘挽手相连,殿院成坛,明代留下来庄严佛塑和牌匾,在万籁俱寂的殿里生生不息,寺庙经过时又一时的总人口之修补,依旧保持在佛性。
堪称国宝的重楼式壁藏就当薄伽教藏殿里。
全国孤例的重楼式壁藏,上层为佛龛,下层为收藏经柜,为了采光和通风,殿后开了同稍窗户,窗中间有一致幢小木拱桥左右连续,五间天宫楼阁从左到右分布住着不同之神佛,这是自己有史以来没有见了的殿中殿。
于殿里,还有三十一尊敬来自辽代的皇彩塑,每一样尊的神气和面貌还各不相同,身上的飘袖和衣带自然唯美,婉丽动人。他们身上的彩漆已经颓落,裸露出当的纹路,镇守着华严寺就重重单年头,看到他俩,就一定给观看了历史。
是因为历史由来,寺庙成了江山重点保护文物,为了响应政府之呼唤,不许烧香也不若功德箱,寺中所有的香炉都给杀铁板盖上,没有了功能性的香炉成为纯粹的点子装置。
姜来想烧香拜佛也从不办法了。我看这为很好的,除了给寺庙重优质干净清爽,更能被佛法显得纯粹,所谓的烧香拜佛,不过是基于欲望之下的拍。
寺庙里还来同一所华严宝塔,登塔需要穿越上鞋套,我们学上根本之鞋套,小心翼翼地活动上前塔里。
当塔底之地宫,有云冈石窟缔造者昙曜的舍利子,姜来隔着同等交汇厚厚的玻璃,仔细地搜索舍利的人影,所谓的舍利子,其实呢不怕是一样聊片白骨头。
供奉舍利子的金塔花纹繁复,华丽极致,围绕以地宫四周的,还有众多单稍佛,他们于四方看在我们,佛法全写于她们之眼底。
塔里之阶梯非常陡峭,我们大小心地为上爬,宝塔总共有五重合,其中,三交汇明,两重叠暗,明层能移动至塔外,暗层则无可知,寓意着人生明暗有经常。
咱俩算终于通过了拥堵之楼梯到宝塔顶层,大同古城的风貌尽收眼底。
我们绕在宝塔走了同一围绕,在一个稍稍角落里,还见到基督教堂就于华严寺底就近,寺庙和教堂看上去关系协调,看来佛祖和基督,应该是片只好情人。
经过在线地图,我还发现,在大同古城里,还有道教,伊斯兰教与天主教,小小的一样栋古城,居然容纳了五不行教派,这里为终于得上是宗教共和国了。
傍晚之凉风习习,姜来说他以佛祖面前许了个愿,我问他字了啊愿,他说勿可知告我,不然就不灵了。
自家说自家并未许愿。
他提问我干什么。
“三载那年,父母离异,之后的各个一样年诞辰,每一样浅去寺庙祭拜,我只许一个愿,我弗贪心,我只有盼爸妈能重归于好,就这样简单。这个意思一直陪同自己到7年份,那无异年,我爸娶了新的老小。从那后,我再为不能愿了。”我说。
“你是不再相信心愿的力量吧?”姜来咨询我。
“我不相信。那都是自欺欺人。”
“可我深信不疑。”姜来之瞳孔里倒影着夕阳,他相同眨眼眼,这个世界就是毁灭了同一不良,他同样睁眼眼睛,这个世界又重建一不善。
“你掌握我刚才许了个什么愿为?我求佛祖保佑,我们肯定能学有所成环游中国。”姜来连续游说。
“我刚刚不是暨你说过为?愿望说出就懵了。”我说。
“我才不担心吗,我明白我们定能够不负众望。”姜来信誓旦旦地说,他终究能够顶出意外的自信。
“我这辈子许的意思都并未一个兑现,你说,我要是无苟转,许一个请勿可能实现的意愿也?说不定,就真正能够兑现啊。”我说。
“你本还有什么愿望?”姜来问。
“我期望我们不能够得逞环游中国。”我笑着说。
“什么狗屁愿望,呸呸呸。”姜来向天呸了几生,不亮口水会不见面滴落至塔下路人的随身。
“这叫负负得正,懂不知晓。”
“懒得跟你扯,走吧,我们欠出了。我一旦达成城看落日!”说得了,姜来迅速地钻研进小小的阶梯,我急忙跟上去。

大同古都不是特别十分,也无到底多少,我们于华严寺出,不顶一半钟头即倒及南门城垣。
半路我们尚通过了炎黄无限古老的九龙壁,我们沾在非常巴移动进来,却偏偏发现除去同块九龙壁之外,啥啊尚未,络绎不断的旅行团把细的院子占满,我们目瞪口呆了非交五分钟就移动出去。
跟咱们一块走出去的,还有另外一个女童,她盯在姜来,上下打量了同海,脸上一脸惊呆之神气,我觉得它惦记如果说啊,结果,她回身就移动了。
姜来看这黄毛丫头莫名其妙的。
“也许人家对而有意思,女孩子总是害羞的。”我说。
“我这人口,没什么意思,而且自己本着它们一些意都没有。”姜来头也非扭转,继续朝着城墙活动。

咱们于南门上上城墙。
南城墙的瓮城,是四面城墙中极其充分之,里里外外一共三还,翁城外,还有半月形象的月城,重重叠障,拒人总里。
当和平年代,城墙只具备历史之含义,御敌防守的成效已经丧失,即便如此,新编制的大同古都墙,依旧保留在来自时光的美。
高达了城,每动几十米就是生出相同幢箭楼,箭楼及的灯笼,随着黄昏底莅临,也慢慢点亮。
城很丰富,总共发生7.24公里,要是走绕一绕,我道我会死的。
当我们发现城墙上得租赁自行车的下,我们兴奋得超过起来。
于城上骑车单车,这绝对是聪明绝顶的主。
然而,当我们达成了车,在坎坷不平底路面及骑行时,我才察觉,这未必是一个吓的主心骨,没骑车多远,我的臀部就受不了。
姜来也如出一辙,只是,他于自己聪明,他脚站于自行车的踏板上,半因为在,他说,只要屁股不沾坐垫,那就算非见面受罪。
当我们跨了大体上,我看来迎面而来一个女孩子,骑法和姜来平等找寻一样,看来它的臀部呢酷不便了。
它们圈了我们同目,转眼就起咱的身边穿,在夕阳产,我们目光短兵相接,我信服有它,是刚于九龙壁遇见的小妞。
姜来只顾着跨,都没有在意到其,我跟他说打当时事的当儿,他说:“你觉得大同死特别啊?大同就这样点大,再次相遇也殊正规。”
然自老是道,这妮子的眼光有接触未对劲,可是,哪里来题目,我还要说不出来。

因为臀部痛,我只好当姜来身后慢慢骑在。
自南往北,两度的景观各不相同,西边的旧城,颓废,残旧,阴沉,是初时代的意味;东边的新城,热闹,新颖,活泼,象征着新世界。
零星独世界中等,高耸的城像是一样道灰色屏障,或者说,一长达斑驳的问题——它用马上半单世界相互维系,相互牵连,这是平种,类似相互寄生的涉嫌,他们哪个吗缺少不了哪个。
迢迢地奔去,西边的高山上发生齐整的风力发电机在运行,他们各转动一环抱,阳光就为搅碎成稍片,落于地上的时节,已经变为了金黄色的零散,有些会于风吹移动,有些会给人捡走,大部分虽说会默默地好去,这是他俩轮回了好多全副的流年。
阳光下山后,城墙上的城楼,角楼,箭楼,统统亮起了黄彤彤的灯光,影子开始于砖墙上放。
俺们跨到了北门,发现翁城的城墙上悬挂着一个特大型的雕塑,是一个裸体的胖子,灯光打在身上,浑身发白,姜来探望下哈哈哈大笑,他认为这个雕塑其实是不过来笑了。
自己因为学的角度解析,我当就是坐超现实的不二法门对历史进行奚落,不温不火,“圆润”且适合。
姜来说任不知道。我将这话翻译成“中文”告诉他:
“这虽是瞎鸡吧扯蛋。”

骑车到西北角,正在翻修的城墙还从来不并轨,无法持续开拓进取,我们回头返回,还了车子,从东门活动下城墙。
夜间,城墙上还有游客于观光,大妈大爷在东门的广场放着音乐,整齐地跳着广场舞蹈。
自想起了在天津海河滨看到底广场舞蹈,准确地游说,也无可知为广场舞蹈,因为他们同意是定点地站于一个地方。
他们多多哀号人,排成一列,走以无比前边的人口背着音箱,用话筒指导正在后的人流,后面的丁随即他,沿着河边一边手舞足蹈一边移动在,不知情的人数还当这是呀邪教组织在练功为。
那时候姜来还他们取了单专门诗意的名——蛇舞。

夜间的旧城特别安静,小市之夜晚着力如此,没有过多之喧闹,也不见面超负荷繁华,一切所得其所。
返青旅,楼下的步行街商铺为还关门了。
姜来以床上,把咱国旅中国之故事分享给跟房子的小伙伴们,姜来讲到兴奋之时光少眼会发光,当然,也少不了加盐加醋,讲到背后的下,那就是一个天马行空的故事,我赶快从断了外,让他急匆匆睡。
其次整日还从未出示,我让醒了还当梦境被之姜来,同房子的人头尚于睡梦,有的在呻吟,还有的以说正在梦话。
咱俩到楼下快餐店吃过早餐,穿过西门,上了公交车,准备往云冈石窟,我来大同的重要目的,就是为了其。
今日天色阴沉,大地和天融为一体,都是灰蒙蒙的。
我们因为了一个大抵时的切削,终于到达了云冈石窟。

云冈石窟不深,为了让青山绿水还起可看性,在石窟外面还发掘了一个人工湖,人工湖及是相同栋新因为之庙,这些人工搭建之新景观,当年一度叫国家文物局叫停,据说是放心不下湖水蒸发,会指向石窟岩体造成不可挽回的毁伤。至于怎么还会建成,也许是政治与经济内达成的某种妥协吧。
本,若干年之后,这些新造的风光,也许又会再也成为新文物,历史嘛,本来就是一个妙不可言的大循环。

举手投足上前洞窟,我毕竟看到了古人对佛法之知情,他们呢无形的佛赐予各色各样有形的情态,用抠于石头上的故事,循循导人向善。每一样敬佛像,每一个花纹,每一样帧壁画,甚至各一个笑容,都深藏着不便言喻的神性,空气中间,除了漂浮着的煤尘,还有佛的意志。
洞窟依山而打通,从北魏暨今天,已经有一千差不多年之史,时光凝固在石上,记录了宏观年之风雨。
第二十窟之大佛在云冈石窟的无比中央,裸露在他的释迦坐像面象祥和,目光慈悲,俯视着云云众生,可是,第二十窟的大佛并无是最为可怜的。
极端深之佛,其实藏在被半座山覆盖的老三窟里,可是,唯独光明普照的第二十窟获取了无限多信徒,他们在充分佛面前烧红跪拜,认真诚恳。
姜来站在大佛面前,双手并十一贺。
“这次许了哟愿否?”我咨询。
“没有许。在华严寺许过了。”他说。“我要是是佛祖,我耶会见烦。”
我笑了。

蓦然,我看来站于姜来旁边的,是咱昨天零星坏相见的小妞,她手合十,头小低着,闭着眼睛,无声地念道,好像在念经。
自所以眼神向姜来表示,姜来回过头看了转,默默地游说了句:“都第三不行遇上这女的了,她怎么阴魂不散。好可怕。”
姜来认为自己已经低了声音,其实并没有,他的讲话被女孩子听到了。
其睁开复眼,走向前,小心翼翼地针对姜来说:“你……是姜来吗?”
姜来给吓了一跳,连忙问:“我是,你是……?”
“你果然是个非常傻逼,姜来,我是年莲,你不记得自己了为?”

逛了云冈石窟,我们并回到了城区。我们是依——我,姜来,年莲。
当返的车上,姜来及自身晾在一派,和年莲有说发生笑。
原先,年莲是姜来的小学同学,他们自小学毕业后,就再次为从没见了,十多年以后的今日,他们于长期的山西大同,以非常偶然的办法还相遇,当姜来听到年莲这个名字的时段,他触动地与其相认,这种久别重逢,看上去确实值得恭喜。
“谢已,我报你,年莲是自个儿小学的好情人,从小学五年级开始,她纵然从头追逐自己了。可自己本着她一些志趣还并未,一直拒绝她,可是,她那孜孜不倦的精神……”姜来刹车了瞬间,卖了单要点。
“…….最终或尚未能够打动自己,小学毕业后,我们虽再也为从没见面了。”姜来毫不掩饰着团结往底自豪,当着年莲的面说。
“你马上丁真的不会见讲话,哪起你这么的总人口介绍对象的。”我说。
“没关系,没提到,我从小学二年级就认姜来,他那么道,我无比明白了。”年莲长发飘飘,长得老甜蜜,说话的鸣响特别晴朗。
“所以自己说得无错吧。你啊,从小开始就无加大了我,果然就是是阴魂不散。哈哈哈。”姜来说。
“我由九龙壁出来,看到了公,那时候我还无承认你是休是姜来,我觉着自己眼花了,毕竟十差不多年从未见了,我怀疑自己拘留错了,于是,我转身就挪。”
“第二糟在城墙上面骑单车,我远远地就来看而了,你放在心上着跨自行车,没看到本人,但自凝视在公,看了生悠久很漫长,我心里面在惦记,难道他确实是姜来?但上无限暗,我或者未确定。”
“直到今天昼,第三浅相遇你,我才认准了你虽是姜来,隔了如此老,你要么那的可观,看来当年之自己,眼光还是挺据的。可你的脾气一点也无换,大白天混说别人坏话的性情还是老样子。”年莲笑着说。
“这点自己同意,他的嘴好像是得矣帕金森综合症,没法治。”我乐着说。
“嘿嘿嘿,嘿嘿嘿。”姜来尴尬地笑笑起来。
“年莲,我及你赔礼道歉,你懂得我一直是口直心快,心善嘴贱,怪我无眼光,没认出你,谁吃你本添加得这般美,换做是其他人,我相信呢认不出来。”姜来说。
随即话听上像是道歉,其实是更换着法在赞年莲,年莲听罢事后,心花怒放。
“嘴甜舌滑的军械。要是你十差不多年前应我之求偶,你现在就是可占据我之抖了。可惜现在,你现在没有会了。”年莲说话的下,不放在心上起撩起自己的发,阵阵抚媚从头发流露。
“没悟出,你长大了随后呢和自家同未设脸。对了,你怎么为来大同了?”姜来问。
“这问题,我哉要是问您呀。你怎么呢来大同了。”年莲反过来问。
“我们在出境游中国为。我们且曾出来挪了抢一个月了。”姜来骄傲地针对正在年莲说,声音亮畅快,车上的人且听见了。
“这么狠心。我是来大同散消,我刚准备离婚啊。”年莲若无其事地说道。
“离婚!离婚?”姜来又了简单尽以确认自己不曾听错。
“对,你没听错,我如果离婚。像本人如此妩媚动人之老伴,当然已结婚了,大学毕业没多久,我就结婚了,这还或多或少年前之从了。你吧?老婆孩子尚好呢?”年莲问。
“什么老婆孩子,我还从来不成家吧,老子才26寒暑好不好,”姜来骄傲地游说。
“你们男人就是是好,越老越热门,不像咱这些女人,要是了了25东尚从来不嫁出去,那即便是龙不胜之厄了。”年莲说。
“可您这么早嫁出去,现在勿呢是如离开婚么?对了,你干吗而离婚啊?”姜来问。
“说起来,很复杂。到站了,我们下车吧。”年莲主动牵在姜来手,下了车,他们之涉,难道就提高了?

回去市区就是傍晚,年莲带我们交同一寒那个理想的山西食堂吃晚饭,她接触了满桌的面食,饿了平等龙之我们,吃东西的早晚就是比如三独自饕餮,山西果然是礼仪之邦面食的犹,只有你意外,没有召开不出来的,当自身看齐灿烂的面食在自己前,我忽然想起了一致词广告词:
世界面食在炎黄,中国面食在山西。
姜来及年莲聊得生气勃勃,点了同样瓶山西最好出名的汾酒,我好奇地品尝了平等人,辣得自身全身发烫,白酒实际是最可怕了。
他们俩喝得淋漓畅快,年莲的面子都通红,据说喝酒脸红底总人口实际上最不抱喝,得咽喉癌,食道癌,胃癌的几乎率是常人的几十倍增。
自身啊是单相同喝酒就算会体面红底人数,所以我莫易于喝酒。有人用称自己专门会养生,其实,那不过大凡自个儿本着体自私的另外一栽表现方式。

“姜来,你本有女性对象为?”借着酒意,年莲尝试再度深切地问询姜来,当一个娘子问另外一个爱人发生没有出阴对象,这绝对是司马昭之心。
“没有,我当一个人格外好之。”姜来随口就报,看来他无晓女人之遐思。
随之,年莲问了一个,那恐惧自己是路人听了为最为尴尬的题材,她说:
“如果我离婚了,你肯与今底本身以同步为?”她刻意将“现在的我”这几个字说得专程重。
姜来先是呆了愣,然后哈哈哈大笑起来,餐厅里的人头都听见了。
“废话,当然是匪乐意了。这应是本身先是总碎片一致坏的不容吧。”
“姜来,你要么那讨人厌,一点还不会见迁就别人。”年莲摆起了一样适合臭脸,可眼看幅臭脸,也是讨人喜欢之贫脸。
“下次会更换个玩笑啊?从五年级到今日,你还不加大了自己哟。”姜来借着酒气,坐在年莲身边,右手搭在它底肩膀上,就如星星个好哥们。
“臭流氓,放开而的咸猪手,什么为无加大了您,我而有夫之妇。”
“可你飞就好解脱了。”
“哎,别提即破事了。来来来,喝酒喝。”年莲拿起酒杯,发现中早已远非酒,我快吃其酒杯倒满酒。
“对了,姜来,你呢从未与自己好介绍你爱人。你们是怎认识的呦。”年莲对正在姜来问道,姜来管昨晚说道为青旅小伙伴的故事复述了同等方方面面,姜来每次说话故事,都因此老各种夸张之修辞手法。
即使如其他人一样,年莲也听得入神。
“谢已,姜来,你们两独底经历足够写一本书了。我实在佩服你们。”年莲说。“可是,我究竟觉得,你们的故事,好像差了碰什么。”
“什么事物?”我及姜来异口同声地发问。
“差一个阴主角!”年莲说。
自家与姜来面面相觑,姜来及本身之想法应该是平的,这是我们最近才建之默契。
“难道,年莲,你是,想当是故事中的,女主角?你该不会见,想跟咱们同出游中国吧?”我死认真地发问其,我梦想不用被我说遭到,千万万万。
“什么啊,我才未乐意跟你们住青旅睡火车每天累得如就狗似的。我是怀念说,你们要是无使听自己之离婚故事,你们要是描摹环游中国的回忆录,我之故事,应该力所能及以里,占一座席吧。”
自我同姜来松了一如既往丁暴,原来她但想把故事分享给咱们。
中国怪特别,环游中国之道路大狭小,两丁同行,已经是终端了,三人口同行?我的御什么,我实在不敢想象。

年莲喝了一整瓶汾酒觉得还不够过瘾,提议我们换个酒店喝酒。
咱们看了产时,已经快十一点了,明天早还要等到火车,我们拒绝了它们底特约。
“年莲,今天以及您久别重逢,我特别高兴,但是,我们明天一早且出发,我真不克重新喝了,明天自我如果是自不来,那就夭折了,谢已会把自己死了。”姜来说。
年莲跟着我们倒来餐厅的大门,走路摇摇晃晃地,就比如相同才醉醺醺的企鹅,她于食堂门口拉在姜来不放,姜来同样体面无奈地圈正在自我,他在朝着自身求救,我容易从未能助。
说时迟那时快,年莲坐于地上,哭了四起,哭得撕心裂肺的。
自己跟姜来抢把其扶她交饭店外,姜来说我们错了,我们错过酒吧陪你喝,你绝不哭,你不要哭。
咱俩像哄孩子一样安慰着它们,可是它同样句子话也无说,除了安慰她,叫它无设哭之外,我们都未知底该说啊好,刚才尚好好地,怎么突然就哭起来,我跟姜来还无语了。

借着路灯,我看到长发之下的她,妆容已经哭花,泪水在眼角下开辟了一致长条流向悲伤的河道,河床下是月经与肉,她底样板,让人口专程同情。
它缓了休息,抬起峰,用早已哭肿的立着咱,她哽咽说着受丁极其惋惜的话语:
“你们会陪同自己回办离婚手续也?我一个丁,实在撑不下去了。我请求你们了。姜来,谢已,我求求你们。我…真的不可开交了……”
谈还尚无说了,年莲就昏迷在地上,准确地游说,应该是醉倒了,她同样套酒气,即使多隔三米之外,都能闻得到。
路边走过的人头,看了俺们一致眼睛,迅速地离,事不牵扯我,高高吊起于。
“现在怎么收拾?”我问姜来。
姜来将年莲的峰在自己之百般腿上,他轻轻地地摆摆了舞狮其底头,除了散落于地上的毛发在飞舞,还是没影响,她的宁静的呼吸声是唯一证明其还活着在的划痕。
“这一瞬间,我也未清楚该怎么收拾了。”姜来挺不得已地游说。
年莲的手提包被甩到路边,我倒过去,捡了回到,手提袋的扣子没有看好,往上等同提,里面东西就是全都滚出去,眉笔,粉饼,钱包,驾照,各种杂七乱八的物混杂在一块儿成为了只杂货铺,当自己还于琢磨着,为什么女人之包包会这么复杂的时段,我见到伴随在一堆化妆品一连丢掉得到于地上的,还有一样拿手掌那么丰富的刀子,哐当一信誉,清脆响亮。
人红,绝对是一个太太太有格外伤力的枪杆子,这管武器,几乎每个女人之承保里都拥有。
不过,年莲比其他的妻还扑朔迷离,我根本没有见了哪个女人会于保险里放平拿刀子。
姜来也看出从确保里遗落出来的刀子,吓了一跳。
年莲的下手垂在地上,姜来把它底手抬起来,借着路灯暖黄的无非,仔细审视,看罢以后,他同体面惶恐。
自家赶忙把地上的物一律股脑丢到管里,走及年莲的身边,姜来抬起它们的手腕,我看来姜来脸上的惊恐的出处。
年莲的手腕上,好几鸣刀割的伤痕已结了痂,鲜红的伤痕相互纠缠,如掌纹一般根植于手腕上,如果无错的话,这应该就是传说被之自杀未遂。
倘伤感是种植传染病,被染的,肯定是左。我举年莲的左边,果然,左手上面也同布满疤痕,两只有手腕,已经让百相似摧残,看无产生原先的旗帜。
而今,这种无名之传染病也飞至自身身上,自从我触碰到年莲的手,身上的每一个毛孔,就开始免停止地抖。
本人忽然想起,刚收拾东西的下,有同布置快捷酒店的房卡在自我前一闪而过。我尽快将管里之物尽数相反出在地上翻找,那把收获满血腥的刀也混在里面,姜来把刀自杂物里挑出来,翻过来翻过去羁押了几眼,然后,他拿刀扔到边的垃圾箱里,刀在空间转了几缠绕,经过了平等条圆润的抛物线,准确地获得于了垃圾桶里。
我拨一堆化妆品,找到了房卡,房卡上面写在酒店的地址,酒店的职,就于我们青旅的反面。
自身跟姜来当路边拦了一致辆出租车,把年莲抬上了车后,我于驾驶者带我们交年莲住的酒店。
大同古城不杀,出租车开始不顶5分钟就是交酒店了。
酒吧没有电梯,姜来只好坐年莲,艰难地朝上爬,酒店的房间号老奇怪,年莲的房,位于20/3/1哀号,这不是因2楼31如泣如诉房,而是因第20下子公司/3楼/1如泣如诉房,这意味,我们设爬上3楼。
尚吓年景莲不另行,姜来还是能够一鼓作气把它们背着及3楼,房间的门口悬挂在同样片请勿打扰的牌,应该是年莲出门的时段挂上失去之,我管其得到下,打开房门,重新将她挂上。
姜来把年莲丢到床上,喘了有限人数大气,我看齐他全身都于冒充着热气,像一个刚刚出炉的馒头。

开拓灯,我看出的,是一个双人房,我无绝掌握为何它一个总人口可如自然双人房,在我眼里,她并无是一个老婆,而是多独问题之集合体。
房间里之衣物到处都是,胸罩和内裤随随便便地抛弃在地上,马桶上,卫生间的地方,还有雷同片刚用了的手纸,上面得到满了鲜血,已经黑,洗手盘上面的护肤品,化妆品,堆成一幢小土丘。
一度凌晨12点了,时间吗非早了。
自问姜来:“我们只要无磨青旅吧。”
姜来没说,看在年莲,陷入了想。
“要不,我们今天夕便在此处睡吧,反正这里产生星星点点摆床铺,我们可照顾一下其。”我说。
姜来只说了一个好字。
姜来帮年莲脱掉鞋子,盖好了被,还细心地,将它头上的头发理了理,她看起来,就像童话里的睡美人,可是,这样的花,为什么而自残,我的确想不通。
姜来说他不困,让自家先睡,他拿屋子的灯关上以后,坐于沙发上,打开电视,调成静音,电视里播放着地方电视台的电视节目,中间还插播着深夜电视购物广告,广告里的召集人嘴巴张得巨大,表情甚添加,他们正声嘶力竭的叫卖着保健品,收藏品,奢侈品……
静音之后,他们还变成了哑巴,也许只有聋子才听到他们之语句。
姜来以房里接触了一样清烟,一呼一吸之间,火光或明或暗,就如相同独自萤火虫火虫,电视屏幕发出的蓝光打在烟雾及,烟雾把姜来的颜笼罩,渐渐地,我看无清姜来了。
睡在床上,眼睛盯在电视的屏幕,慢慢失去了焦点,我是同华老相机,快门和光圈都松弛了,我记忆我对肉眼拍下之终极一轴画面,是姜来偷抽烟的金科玉律。

    参考的GitHub地址:https://github.com/dsafa/CSDeskBand

第十三章(-):鱼城

绕以本人身边的,是四长条金鱼,金鱼的颜色对承诺着风,火,水,土四栽素。
代表风的金鱼是一朵云,隐约看到轮廓,在其身边有稀有风暴包裹着;
代表和的金鱼是千篇一律团火,像燃烧在的火种,火苗在它身上四处乱窜;
表示和的金鱼是一律摊海,水花源源不断地不停打它身上溅起;
代表土的金鱼是均等片泥,干枯的标上整了裂痕,碎泥成了灰纷纷扬扬。

他俩以自身的身边,就如四怪保安,形影不偏离,当自己思点碰他们的当儿,他们会火速游走,手收回来,他们又自动游回。
“你好幸运。”一个老头子走至我之身边对自己说。
外满头白发,脸上的深壑的褶子都足以混死苍蝇,黑色的前辈斑比太阳黑子还要黑,他拄着双拐,走路很缓慢,每走相同步,都如过去了一个世纪。
“为什么我是幸运的?”我反问他。
“你拥有了这个宇宙,还不够幸运吗?”
本人向四周看了羁押,我真正站于同切片荒芜的地,寸草不生,如果说自家拥有了这个宇宙,那自己之宇宙也非休太要命了。
爷们用拐杖戳了捅我身边的金鱼,他们火速地躲开,游至自身之身后,就比如四个幼童,看到陌生人,会害怕。
“死亡是者宇宙里最好自私的人事。它从不慷慨,但为无吝惜。你碰巧取了她,随之而来的,就是初的宇宙。”
“你是说,我死了?”
“不不不,在无限的大自然里,从来没有丁会真的地非常去。死亡而是独经过,不是到头来点。每一样赖弱,随之而来的,都是新的新生,而若,拥有的,就是一个属你的初的自然界。”
“这是自个儿之大自然?”我万分怀疑我自己产生没发出听错,这种话语,进了哪位之耳,都见面认为不可信。
“是的,你的,全部,都是你的。”老头子背对正值自我,把拐杖插进地里,抬起峰,举起粗糙的手,他的动作,有雷同栽宗教仪式感。
“那若干吗会出现在自我之宇宙里。”我本着正在他的背影说。
外把放下,回过头,对着我说:
“你是题材,问错了。再提问一样任何。”
自身起接触疑惑,但自身要遵循做了。
“为什么我之宇宙里,只有自身和您?”
“又错了。再来。”
身边的鲜鱼继续于上空游在,他们有望的法让自家回忆了小时候之祥和,如果一切的想还源于生死,那么,唯一的题材,也只是至于生死本身。
“为什么,你还尚无好。”我问了一个任上类似不极端礼貌的题材,可自我只好想到是题材。
“你算问到点子上了。”
外依靠着拐棍走及自身的身边,离自己只有一个拳头的相距,我们过于接近,空气受,我竟能闻到外嘴里陈年的寓意,是一亿仍历史书焚化过后的神之寓意。
“我哪怕是你创造的丁,你想我大,我就算大,你想自己生,我不怕存。”他提的弦外之音带在安静,我能够任起他谈里,那种主仆的含意,是温和的依,一心一意的尾随。
“如果当时是本身之宇宙空间,为什么这里呀都没,只有你?”我问。
“因为你的私心,现在呀还没有。”
“那若到底是谁吗?”
“我是您的教育工作者,我是你的预兆,我是若的明察秋毫,我耶是您的佣人,你创造自己之时刻,就是这么定义自己的。”
“我是什么时候,创造而的?”
“在公用自我之早晚,你便创造了自。”
“我什么还得创造?”
“对,你的金鱼会为汝创造一切,他们不怕是是世界的着力相,有了她们,你哟还好创造。”
立马话听起十分为人兴奋,创造一切?那我非就是明智了?
“我怀念如果一律长长的河流,一长条流向天空之大江。”我说。
季长达金鱼动起来,一眨眼的素养,一漫长巨大的长河就应运而生于自我的身边,河流无视着地力与天地规则,向天奔流。
老伴儿笑了笑,什么都无说。
“我想要同座结冰的火山。”
老伴笑了笑,什么都未说。
“我眷恋使加上满鱼鳞的鸟儿。”
爷们笑了笑笑,什么还非说。
“我思只要一如既往栋黄金之之城建。”
老伴儿笑了笑笑,什么还无说。
“我想要…….”

自花费了怪丰富日子,从零散至发出,把一个完的社会风气创造出,这里产生总体我眷恋要实现的诡异事物,身边的荒废早就没有,取而代之的凡一个全然陌生的世界,一个独自可存在幻想着之世界。
本人看正在他俩,却怎还乐滋滋不起。
斯世界,无论由什么角度看,都专门的违和。
长着腿的蛇在街头巷尾爬行,八独乳房的内和产生三清阴茎的先生当赤裸裸地举行容易,空中的UFO不断掉落奇形怪状的外星人,天空中飘荡着一座座山,山底还有成片的戈壁,会喷火的狗还有会好烹饪之猫,这不是一个健康的社会风气,可是,这就算是自家思念要之社会风气?
当初之好奇心已经没有,只剩余和这世界无穷无尽的忏悔,当我思念咨询老伴,有无起主意再又来之时光,他一度一去不返得没有。
“我思如果老头子重新出现。”
爷们还是没有起。四长达金鱼吧一致连没有了。这个世界,好像就改头换面了,我再为无法更改。
自家立在斯世界之尽上方,以上帝的见解看正在自创建的全体,我的子民,我之国家,我之星斗,我的自然界。
当下虽是自身的世界也?这的确是自我的世界呢?

本人恍然想起老头子的语句。
唯恐我死了,这通就好重头再来,我眷恋只要完蛋。
自我跳跳下,一心寻死,我知,自由落体运动最终见面受我带来一个新的天地。
自家坚信不移。

目录 《绝对光年》小说

未完待续,欢迎关注!(14/31)

关于作者:
aloho
。定位为一个幽伤主义的诗人。男,在大上海活,正向三字头奔赴,搞了摄影与电音,做过网金产品经理,偶尔是一个单开LOGO的平面设计师,拥有一个太连载的私诗计划[aloho的床头诗]

2016年旅游中国,回来后控制了一致年描绘以半记实半虚构的小说《绝对光年》,自诩这是相同论魔幻主义公路小说。

    DeskBand相关代码如下:

COLORREF:

// This code snippet was used by SharpShell.
//

using System.Drawing;
using System.Runtime.InteropServices;

namespace MyDiskInfo.Interop
{
    [StructLayout(LayoutKind.Sequential)]
    public struct COLORREF
    {
        public COLORREF(Color color)
        {
            Dword = (uint)color.R + (((uint)color.G) << 8) + (((uint)color.B) << 16);
        }

        public uint Dword;
        public Color Color
        {
            get
            {
                return Color.FromArgb(
                    (int)(0x000000FFU & Dword),
                    (int)(0x0000FF00U & Dword) >> 8,
                    (int)(0x00FF0000U & Dword) >> 16);
            }
        }
    }
}

View Code

DESKBANDINFO:

using System;
using System.Runtime.InteropServices;

namespace MyDiskInfo.Interop
{
    /// <summary>
    /// Receives information about a band object. This structure is used with the deprecated IDeskBand::GetBandInfo method.
    /// </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct DESKBANDINFO
    {
        /// <summary>
        /// Set of flags that determine which members of this structure are being requested. 
        /// </summary>
        /// <remarks>
        /// This will be a combination of the following values:
        ///     DBIM_MINSIZE    ptMinSize is being requested.
        ///     DBIM_MAXSIZE    ptMaxSize is being requested.
        ///     DBIM_INTEGRAL   ptIntegral is being requested.
        ///     DBIM_ACTUAL     ptActual is being requested.
        ///     DBIM_TITLE      wszTitle is being requested.
        ///     DBIM_MODEFLAGS  dwModeFlags is being requested.
        ///     DBIM_BKCOLOR    crBkgnd is being requested.
        /// </remarks>
        public DBIM dwMask;

        /// <summary>
        /// Point structure that receives the minimum size of the band object. 
        /// The minimum width is placed in the x member and the minimum height 
        /// is placed in the y member. 
        /// </summary>
        public POINT ptMinSize;

        /// <summary>
        /// Point structure that receives the maximum size of the band object. 
        /// The maximum height is placed in the y member and the x member is ignored. 
        /// If there is no limit for the maximum height, (LONG)-1 should be used. 
        /// </summary>
        public POINT ptMaxSize;

        /// <summary>
        /// Point structure that receives the sizing step value of the band object. 
        /// The vertical step value is placed in the y member, and the x member is ignored. 
        /// The step value determines in what increments the band will be resized. 
        /// </summary>
        /// <remarks>
        /// This member is ignored if dwModeFlags does not contain DBIMF_VARIABLEHEIGHT. 
        /// </remarks>
        public POINT ptIntegral;

        /// <summary>
        /// Point structure that receives the ideal size of the band object. 
        /// The ideal width is placed in the x member and the ideal height is placed in the y member. 
        /// The band container will attempt to use these values, but the band is not guaranteed to be this size.
        /// </summary>
        public POINT ptActual;

        /// <summary>
        /// The title of the band.
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)]
        public String wszTitle;

        /// <summary>
        /// A value that receives a set of flags that define the mode of operation for the band object. 
        /// </summary>
        /// <remarks>
        /// This must be one or a combination of the following values.
        ///     DBIMF_NORMAL
        ///     The band is normal in all respects. The other mode flags modify this flag.
        ///     DBIMF_VARIABLEHEIGHT
        ///     The height of the band object can be changed. The ptIntegral member defines the 
        ///     step value by which the band object can be resized. 
        ///     DBIMF_DEBOSSED
        ///     The band object is displayed with a sunken appearance.
        ///     DBIMF_BKCOLOR
        ///     The band will be displayed with the background color specified in crBkgnd.
        /// </remarks>
        public DBIMF dwModeFlags;

        /// <summary>
        /// The background color of the band.
        /// </summary>
        /// <remarks>
        /// This member is ignored if dwModeFlags does not contain the DBIMF_BKCOLOR flag. 
        /// </remarks>
        public COLORREF crBkgnd;

        /// <summary>
        /// The view mode of the band object. This is one of the following values.
        /// </summary>
        [Flags]
        public enum DBIF
        {
            /// <summary>
            /// Band object is displayed in a horizontal band.
            /// </summary>
            DBIF_VIEWMODE_NORMAL = 0x0000,

            /// <summary>
            /// Band object is displayed in a vertical band.
            /// </summary>
            DBIF_VIEWMODE_VERTICAL = 0x0001,

            /// <summary>
            /// Band object is displayed in a floating band.
            /// </summary>
            DBIF_VIEWMODE_FLOATING = 0x0002,

            /// <summary>
            /// Band object is displayed in a transparent band.
            /// </summary>
            DBIF_VIEWMODE_TRANSPARENT = 0x0004
        }

        /// <summary>
        /// The set of flags that determine which members of this structure are being requested by the caller. One or more of the following values:
        /// </summary>
        [Flags]
        public enum DBIM
        {
            /// <summary>
            /// ptMinSize is requested.
            /// </summary>
            DBIM_MINSIZE = 0x0001,

            /// <summary>
            /// ptMaxSize is requested.
            /// </summary>
            DBIM_MAXSIZE = 0x0002,

            /// <summary>
            /// ptIntegral is requested.
            /// </summary>
            DBIM_INTEGRAL = 0x0004,

            /// <summary>
            /// ptActual is requested.
            /// </summary>
            DBIM_ACTUAL = 0x0008,

            /// <summary>
            /// wszTitle is requested.
            /// </summary>
            DBIM_TITLE = 0x0010,

            /// <summary>
            /// dwModeFlags is requested.
            /// </summary>
            DBIM_MODEFLAGS = 0x0020,

            /// <summary>
            /// crBkgnd is requested.
            /// </summary>
            DBIM_BKCOLOR = 0x0040
        }

        /// <summary>
        /// A value that receives a set of flags that specify the mode of operation for the band object. One or more of the following values:
        /// </summary>
        [Flags]
        public enum DBIMF : uint
        {
            /// <summary>
            /// The band uses default properties. The other mode flags modify this flag.
            /// </summary>
            DBIMF_NORMAL = 0x0000,

            /// <summary>
            /// Windows XP and later: The band object is of a fixed sized and position. With this flag, a sizing grip is not displayed on the band object.
            /// </summary>
            DBIMF_FIXED = 0x0001,

            /// <summary>
            /// DBIMF_FIXEDBMP
            /// Windows XP and later: The band object uses a fixed bitmap (.bmp) file as its background. Note that backgrounds are not supported in all cases, so the bitmap may not be seen even when this flag is set.
            /// </summary>
            DBIMF_FIXEDBMP = 0x0004,

            /// <summary>
            /// The height of the band object can be changed. The ptIntegral member defines the step value by which the band object can be resized.
            /// </summary>
            DBIMF_VARIABLEHEIGHT = 0x0008,

            /// <summary>
            /// Windows XP and later: The band object cannot be removed from the band container.
            /// </summary>
            DBIMF_UNDELETEABLE = 0x0010,

            /// <summary>
            /// The band object is displayed with a sunken appearance.
            /// </summary>
            DBIMF_DEBOSSED = 0x0020,

            /// <summary>
            /// The band is displayed with the background color specified in crBkgnd.
            /// </summary>
            DBIMF_BKCOLOR = 0x0040,

            /// <summary>
            /// Windows XP and later: If the full band object cannot be displayed (that is, the band object is smaller than ptActual, a chevron is shown to indicate that there are more options available. These options are displayed when the chevron is clicked.
            /// </summary>
            DBIMF_USECHEVRON = 0x0080,

            /// <summary>
            /// Windows XP and later: The band object is displayed in a new row in the band container.
            /// </summary>
            DBIMF_BREAK = 0x0100,

            /// <summary>
            /// Windows XP and later: The band object is the first object in the band container.
            /// </summary>
            DBIMF_ADDTOFRONT = 0x0200,

            /// <summary>
            /// Windows XP and later: The band object is displayed in the top row of the band container.
            /// </summary>
            DBIMF_TOPALIGN = 0x0400,

            /// <summary>
            /// Windows Vista and later: No sizing grip is ever displayed to allow the user to move or resize the band object.
            /// </summary>
            DBIMF_NOGRIPPER = 0x0800,

            /// <summary>
            /// Windows Vista and later: A sizing grip that allows the user to move or resize the band object is always shown, even if that band object is the only one in the container.
            /// </summary>
            DBIMF_ALWAYSGRIPPER = 0x1000,

            /// <summary>
            /// Windows Vista and later: The band object should not display margins.
            /// </summary>
            DBIMF_NOMARGINS = 0x2000
        }
    }
}

View Code

POINT:

// This code snippet was used by SharpShell.
//
using System.Runtime.InteropServices;

namespace MyDiskInfo.Interop
{
    /// <summary>
    /// The POINT structure defines the x- and y- coordinates of a point.
    /// </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct POINT
    {
        /// <summary>
        /// The x-coordinate of the point.
        /// </summary>
        public int X;

        /// <summary>
        /// The y-coordinate of the point.
        /// </summary>
        public int Y;
    }
}

View Code

RECT:

using System.Runtime.InteropServices;

namespace MyDiskInfo.Interop
{
    [StructLayout(LayoutKind.Sequential)]
    public struct RECT
    {
        public RECT(int left, int top, int right, int bottom)
        {
            this.left = left;
            this.top = top;
            this.right = right;
            this.bottom = bottom;
        }


        public int left, top, right, bottom;

        public int Width()
        {
            return right - left;
        }

        public int Height()
        {
            return bottom - top;
        }

        public void Offset(int x, int y)
        {
            left += x;
            right += x;
            top += y;
            bottom += y;
        }

        public void Set(int left, int top, int right, int bottom)
        {
            this.left = left;
            this.top = top;
            this.right = right;
            this.bottom = bottom;
        }

        public bool IsEmpty()
        {
            return Width() == 0 && Height() == 0;
        }
    }
}

View Code

Attributes:

using System;
using System.Runtime.InteropServices;

namespace MyDiskInfo
{
    /// <summary>
    /// The display name of the extension and the description for the HelpText(displayed in status bar when menu command selected).
    /// </summary>
    [AttributeUsage(AttributeTargets.Class)]
    public class DeskBandInfoAttribute : System.Attribute
    {
        private string _displayName;
        private string _helpText;

        public string DisplayName
        {
            get { return _displayName; }
        }

        public string HelpText
        {
            get { return _helpText; }
        }

        public DeskBandInfoAttribute() { }

        public DeskBandInfoAttribute(string displayName, string helpText)
        {
            _displayName = displayName;
            _helpText = helpText;
        }
    }
}

View Code

ComImport:

using System;
using System.Runtime.InteropServices;

namespace MyDiskInfo.Interop
{
    /// <summary>
    /// Provides a simple way to support communication between an object and its site in the container.
    /// </summary>
    [ComImport]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [Guid("FC4801A3-2BA9-11CF-A229-00AA003D7352")]
    public interface IObjectWithSite
    {
        /// <summary>
        /// Enables a container to pass an object a pointer to the interface for its site.
        /// </summary>
        /// <param name="pUnkSite">A pointer to the IUnknown interface pointer of the site managing this object.
        /// If NULL, the object should call Release on any existing site at which point the object no longer knows its site.</param>
        void SetSite([In, MarshalAs(UnmanagedType.IUnknown)] Object pUnkSite);

        /// <summary>
        /// Retrieves the latest site passed using SetSite.
        /// </summary>
        /// <param name="riid">The IID of the interface pointer that should be returned in ppvSite.</param>
        /// <param name="ppvSite">Address of pointer variable that receives the interface pointer requested in riid.</param>
        void GetSite(ref Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out Object ppvSite);
    }

    /// <summary>
    /// Exposes a method that is used to communicate focus changes for a user input object contained in the Shell.
    /// </summary>
    [ComImport]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [Guid("F1DB8392-7331-11D0-8C99-00A0C92DBFE8")]
    public interface IInputObjectSite
    {
        /// <summary>
        /// Informs the browser that the focus has changed.
        /// </summary>
        /// <param name="punkObj">The address of the IUnknown interface of the object gaining or losing the focus.</param>
        /// <param name="fSetFocus">Indicates if the object has gained or lost the focus. If this value is nonzero, the object has gained the focus.
        /// If this value is zero, the object has lost the focus.</param>
        /// <returns>Returns S_OK if the method was successful, or a COM-defined error code otherwise.</returns>
        [PreserveSig]
        Int32 OnFocusChangeIS([MarshalAs(UnmanagedType.IUnknown)] Object punkObj, Int32 fSetFocus);
    }

    /// <summary>
    /// The IOleWindow interface provides methods that allow an application to obtain the handle to the various windows that participate in in-place activation, and also to enter and exit context-sensitive help mode.
    /// </summary>
    [ComImport]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [Guid("00000114-0000-0000-C000-000000000046")]
    public interface IOleWindow
    {
        /// <summary>
        /// Retrieves a handle to one of the windows participating in in-place activation (frame, document, parent, or in-place object window).
        /// </summary>
        /// <param name="phwnd">A pointer to a variable that receives the window handle.</param>
        /// <returns>This method returns S_OK on success.</returns>
        [PreserveSig]
        int GetWindow(out IntPtr phwnd);

        /// <summary>
        /// Determines whether context-sensitive help mode should be entered during an in-place activation session.
        /// </summary>
        /// <param name="fEnterMode">TRUE if help mode should be entered; FALSE if it should be exited.</param>
        /// <returns>This method returns S_OK if the help mode was entered or exited successfully, depending on the value passed in fEnterMode.</returns>
        [PreserveSig]
        int ContextSensitiveHelp(bool fEnterMode);
    }

    [ComImport]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [Guid("012DD920-7B26-11D0-8CA9-00A0C92DBFE8")]
    public interface IDockingWindow : IOleWindow
    {
        #region IOleWindow

        [PreserveSig]
        new int GetWindow(out IntPtr phwnd);

        [PreserveSig]
        new int ContextSensitiveHelp(bool fEnterMode);

        #endregion

        /// <summary>
        /// Instructs the docking window object to show or hide itself.
        /// </summary>
        /// <param name="fShow">TRUE if the docking window object should show its window.
        /// FALSE if the docking window object should hide its window and return its border space by calling SetBorderSpaceDW with zero values.</param>
        /// <returns>If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.</returns>
        [PreserveSig]
        int ShowDW([In] bool fShow);

        /// <summary>
        /// Notifies the docking window object that it is about to be removed from the frame.
        /// The docking window object should save any persistent information at this time.
        /// </summary>
        /// <param name="dwReserved">Reserved. This parameter should always be zero.</param>
        /// <returns>If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.</returns>
        [PreserveSig]
        int CloseDW([In] UInt32 dwReserved);

        /// <summary>
        /// Notifies the docking window object that the frame's border space has changed.
        /// </summary>
        /// <param name="prcBorder">Pointer to a RECT structure that contains the frame's available border space.</param>
        /// <param name="punkToolbarSite">Pointer to the site's IUnknown interface. The docking window object should call the QueryInterface method for this interface, requesting IID_IDockingWindowSite.
        /// The docking window object then uses that interface to negotiate its border space. It is the docking window object's responsibility to release this interface when it is no longer needed.</param>
        /// <param name="fReserved">Reserved. This parameter should always be zero.</param>
        /// <returns>If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.</returns>
        [PreserveSig]
        int ResizeBorderDW(RECT prcBorder, [In, MarshalAs(UnmanagedType.IUnknown)] IntPtr punkToolbarSite, bool fReserved);
    }

    /// <summary>
    /// Gets information about a band object.
    /// </summary>
    [ComImport]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [Guid("EB0FE172-1A3A-11D0-89B3-00A0C90A90AC")]
    public interface IDeskBand : IDockingWindow
    {
        #region IOleWindow

        [PreserveSig]
        new int GetWindow(out IntPtr phwnd);

        [PreserveSig]
        new int ContextSensitiveHelp(bool fEnterMode);

        #endregion

        #region IDockingWindow

        [PreserveSig]
        new int ShowDW([In] bool fShow);

        [PreserveSig]
        new int CloseDW([In] UInt32 dwReserved);

        [PreserveSig]
        new int ResizeBorderDW(RECT prcBorder, [In, MarshalAs(UnmanagedType.IUnknown)] IntPtr punkToolbarSite, bool fReserved);

        #endregion

        /// <summary>
        /// Gets state information for a band object.
        /// </summary>
        /// <param name="dwBandID">The identifier of the band, assigned by the container. The band object can retain this value if it is required.</param>
        /// <param name="dwViewMode">The view mode of the band object. One of the following values: DBIF_VIEWMODE_NORMAL, DBIF_VIEWMODE_VERTICAL, DBIF_VIEWMODE_FLOATING, DBIF_VIEWMODE_TRANSPARENT.</param>
        /// <param name="pdbi">Pointer to a DESKBANDINFO structure that receives the band information for the object. The dwMask member of this structure indicates the specific information that is being requested.</param>
        /// <returns>If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.</returns>
        [PreserveSig]
        int GetBandInfo(UInt32 dwBandID, DESKBANDINFO.DBIF dwViewMode, ref DESKBANDINFO pdbi);
    }

    /// <summary>
    /// Exposes methods to enable and query translucency effects in a deskband object.
    /// </summary>
    [ComImport]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [Guid("79D16DE4-ABEE-4021-8D9D-9169B261D657")]
    public interface IDeskBand2 : IDeskBand
    {
        #region IOleWindow

        [PreserveSig]
        new int GetWindow(out IntPtr phwnd);

        [PreserveSig]
        new int ContextSensitiveHelp(bool fEnterMode);

        #endregion

        #region IDockingWindow

        [PreserveSig]
        new int ShowDW([In] bool fShow);

        [PreserveSig]
        new int CloseDW([In] UInt32 dwReserved);

        [PreserveSig]
        new int ResizeBorderDW(RECT prcBorder, [In, MarshalAs(UnmanagedType.IUnknown)] IntPtr punkToolbarSite, bool fReserved);

        #endregion

        #region IDeskBand

        [PreserveSig]
        new int GetBandInfo(UInt32 dwBandID, DESKBANDINFO.DBIF dwViewMode, ref DESKBANDINFO pdbi);

        #endregion

        /// <summary>
        /// Indicates the deskband's ability to be displayed as translucent.
        /// </summary>
        /// <param name="pfCanRenderComposited">When this method returns, contains a BOOL indicating ability.</param>
        /// <returns>If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.</returns>
        [PreserveSig]
        int CanRenderComposited(out bool pfCanRenderComposited);

        /// <summary>
        /// Sets the composition state.
        /// </summary>
        /// <param name="fCompositionEnabled">TRUE to enable the composition state; otherwise, FALSE.</param>
        /// <returns>If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.</returns>
        [PreserveSig]
        int SetCompositionState(bool fCompositionEnabled);

        /// <summary>
        /// Gets the composition state.
        /// </summary>
        /// <param name="pfCompositionEnabled">When this method returns, contains a BOOL that indicates state.</param>
        /// <returns>If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.</returns>
        [PreserveSig]
        int GetCompositionState(out bool pfCompositionEnabled);
    }
}

View Code

DeskBand,这里与GitHub上的次序不同之是,DeskBand直接接轨的ElementHost类,GitHub上之好像是多例的,我怀念使之是单例的,所以修改了瞬间。这里粘的代码是WPF的,如果你想实现Winform的,就为DeskBand继承UserControl,DeskBand代码如下:

// Copyright(c) 2017 Patrick Becker
//
// Visit the Project page for more information.
// https://github.com/patbec/TaskbarSampleExtension


using Microsoft.Win32;
using System;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using MyDiskInfo.Interop;
using System.Windows.Forms.Integration;

namespace MyDiskInfo
{
    /// <summary>
    /// Basic class for a DeskBand object
    /// </summary>
    /// <example>
    /// [ComVisible(true)]
    /// [Guid("00000000-0000-0000-0000-000000000000")]
    /// [DeskBandInfo("Beispiel Erweiterung", "Diese ist eine Beispiel Erweiterung für die Taskleiste.")]
    /// public class SampleExtension : DeskBand
    /// { /*...*/ }
    /// </example>
    public class DeskBand : ElementHost, IObjectWithSite, IDeskBand2
    {

        private const int S_OK = 0;
        private const int E_NOTIMPL = unchecked((int)0x80004001);

        protected IInputObjectSite DeskBandSite;

        public DeskBand()
        {
            InitializeComponent();
        }

        private void InitializeComponent()
        {
            this.Name = "DeskBand";
        }

        #region Properties

        /// <summary>
        /// Title of the band object, displayed by default on the left or top of the object.
        /// </summary>
        [Browsable(true)]
        [DefaultValue("")]
        public String Title { get; set; }

        /// <summary>
        /// Minimum size of the band object. Default value of -1 sets no minimum constraint.
        /// </summary>
        [Browsable(true)]
        [DefaultValue(typeof(Size), "-1,-1")]
        public Size MinSize { get; set; }

        /// <summary>
        /// Maximum size of the band object. Default value of -1 sets no maximum constraint.
        /// </summary>
        [Browsable(true)]
        [DefaultValue(typeof(Size), "-1,-1")]
        public Size MaxSize { get; set; }

        /// <summary>
        /// Minimum vertical size of the band object. Default value of -1 sets no maximum constraint. (Used when the taskbar is aligned vertically.)
        /// </summary>
        [Browsable(true)]
        [DefaultValue(typeof(Size), "-1,-1")]
        public Size MinSizeVertical { get; set; }

        /// <summary>
        /// Says that band object's size must be multiple of this size. Defauilt value of -1 does not set this constraint.
        /// </summary>
        [Browsable(true)]
        [DefaultValue(typeof(Size), "-1,-1")]
        public Size IntegralSize { get; set; }

        #endregion

        #region IObjectWithSite

        public void SetSite([In, MarshalAs(UnmanagedType.IUnknown)] Object pUnkSite)
        {
            if (DeskBandSite != null)
                Marshal.ReleaseComObject(DeskBandSite);

            DeskBandSite = (IInputObjectSite)pUnkSite;
        }

        public void GetSite(ref Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out Object ppvSite)
        {
            ppvSite = DeskBandSite;
        }

        #endregion

        #region IDeskBand2

        public virtual int CanRenderComposited(out bool pfCanRenderComposited)
        {
            pfCanRenderComposited = true;
            return S_OK;
        }

        public int SetCompositionState(bool fCompositionEnabled)
        {
            fCompositionEnabled = true;
            return S_OK;
        }

        public int GetCompositionState(out bool pfCompositionEnabled)
        {
            pfCompositionEnabled = false;
            return S_OK;
        }

        public int GetBandInfo(uint dwBandID, DESKBANDINFO.DBIF dwViewMode, ref DESKBANDINFO pdbi)
        {
            if (pdbi.dwMask.HasFlag(DESKBANDINFO.DBIM.DBIM_MINSIZE))
            {
                // Support for a vertical taskbar
                // Most examples have no support for a vertical taskbar. Who in hell uses their taskbar vertically? Me! Very practical on a 21:9 monitor.
                if (dwViewMode.HasFlag(DESKBANDINFO.DBIF.DBIF_VIEWMODE_FLOATING) || dwViewMode.HasFlag(DESKBANDINFO.DBIF.DBIF_VIEWMODE_VERTICAL))
                {
                    pdbi.ptMinSize.Y = this.MinSizeVertical.Width;
                    pdbi.ptMinSize.X = this.MinSizeVertical.Height;
                }
                else
                {
                    pdbi.ptMinSize.X = this.MinSize.Width;
                    pdbi.ptMinSize.Y = this.MinSize.Height;
                }
            }
            if (pdbi.dwMask.HasFlag(DESKBANDINFO.DBIM.DBIM_MAXSIZE))
            {
                if (dwViewMode.HasFlag(DESKBANDINFO.DBIF.DBIF_VIEWMODE_FLOATING) || dwViewMode.HasFlag(DESKBANDINFO.DBIF.DBIF_VIEWMODE_VERTICAL))
                {
                    pdbi.ptMaxSize.Y = this.MaxSize.Width;
                    pdbi.ptMaxSize.X = this.MaxSize.Height;
                }
                else
                {
                    pdbi.ptMaxSize.X = this.MaxSize.Width;
                    pdbi.ptMaxSize.Y = this.MaxSize.Height;
                }
            }
            if (pdbi.dwMask.HasFlag(DESKBANDINFO.DBIM.DBIM_INTEGRAL))
            {
                if (dwViewMode.HasFlag(DESKBANDINFO.DBIF.DBIF_VIEWMODE_FLOATING) || dwViewMode.HasFlag(DESKBANDINFO.DBIF.DBIF_VIEWMODE_VERTICAL))
                {
                    pdbi.ptIntegral.Y = this.IntegralSize.Width;
                    pdbi.ptIntegral.X = this.IntegralSize.Height;
                }
                else
                {
                    pdbi.ptIntegral.X = this.IntegralSize.Width;
                    pdbi.ptIntegral.Y = this.IntegralSize.Height;
                }
            }

            if (pdbi.dwMask.HasFlag(DESKBANDINFO.DBIM.DBIM_ACTUAL))
            {
                if (dwViewMode.HasFlag(DESKBANDINFO.DBIF.DBIF_VIEWMODE_FLOATING) || dwViewMode.HasFlag(DESKBANDINFO.DBIF.DBIF_VIEWMODE_VERTICAL))
                {
                    pdbi.ptActual.Y = this.Size.Width;
                    pdbi.ptActual.X = this.Size.Height;
                }
                else
                {
                    pdbi.ptActual.X = this.Size.Width;
                    pdbi.ptActual.Y = this.Size.Height;
                }
            }

            if (pdbi.dwMask.HasFlag(DESKBANDINFO.DBIM.DBIM_TITLE))
            {
                pdbi.wszTitle = this.Title;
            }

            pdbi.dwModeFlags = DESKBANDINFO.DBIMF.DBIMF_ALWAYSGRIPPER | DESKBANDINFO.DBIMF.DBIMF_NORMAL | DESKBANDINFO.DBIMF.DBIMF_VARIABLEHEIGHT;
            pdbi.dwMask = pdbi.dwMask | DESKBANDINFO.DBIM.DBIM_BKCOLOR | DESKBANDINFO.DBIM.DBIM_TITLE; // Testen

            return S_OK;
        }

        public int GetWindow(out IntPtr phwnd)
        {
            phwnd = Handle;
            return S_OK;
        }

        public int ContextSensitiveHelp(bool fEnterMode)
        {
            return S_OK;
        }

        public int ShowDW([In] bool fShow)
        {
            if (fShow)
                Show();
            else
                Hide();

            return S_OK;
        }

        public virtual void ClearResources()
        {
        }

        public int CloseDW([In] uint dwReserved)
        {
            ClearResources();
            Dispose(true);
            return S_OK;
        }

        public int ResizeBorderDW(RECT prcBorder, [In, MarshalAs(UnmanagedType.IUnknown)] IntPtr punkToolbarSite, bool fReserved)
        {
            return E_NOTIMPL;
        }

        #endregion

        #region Register / Unregister

        [ComRegisterFunctionAttribute]
        public static void Register(Type t)
        {
            string guid = t.GUID.ToString("B");

            DeskBandInfoAttribute[] deskBandInfo = (DeskBandInfoAttribute[])
            t.GetCustomAttributes(typeof(DeskBandInfoAttribute), false);

            // Register only the extension if the attribute DeskBandInfo is used.
            if (deskBandInfo.Length == 1)
            {
                RegistryKey rkClass = Registry.ClassesRoot.CreateSubKey(@"CLSID\" + guid);
                RegistryKey rkCat = rkClass.CreateSubKey("Implemented Categories");

                string _displayName = t.Name;
                string _helpText = t.Name;


                if (deskBandInfo[0].DisplayName != null)
                {
                    _displayName = deskBandInfo[0].DisplayName;
                }

                if (deskBandInfo[0].HelpText != null)
                {
                    _helpText = deskBandInfo[0].HelpText;
                }

                rkClass.SetValue(null, _displayName);
                rkClass.SetValue("MenuText", _displayName);
                rkClass.SetValue("HelpText", _helpText);

                // TaskBar
                rkCat.CreateSubKey("{00021492-0000-0000-C000-000000000046}");

                Console.WriteLine(String.Format("{0} {1} {2}", guid, _displayName, "successfully registered."));
            }
            else
            {
                Console.WriteLine(guid + " has no attributes");
            }
        }

        [ComUnregisterFunctionAttribute]
        public static void Unregister(Type t)
        {
            string guid = t.GUID.ToString("B");

            DeskBandInfoAttribute[] deskBandInfo = (DeskBandInfoAttribute[])
            t.GetCustomAttributes(typeof(DeskBandInfoAttribute), false);

            if (deskBandInfo.Length == 1)
            {
                string _displayName = t.Name;

                if (deskBandInfo[0].DisplayName != null)
                {
                    _displayName = deskBandInfo[0].DisplayName;
                }

                Registry.ClassesRoot.CreateSubKey(@"CLSID").DeleteSubKeyTree(guid);

                Console.WriteLine(String.Format("{0} {1} {2}", guid, _displayName, "successfully removed."));
            }
            else
            {
                Console.WriteLine(guid + " has no attributes");
            }
        }

        #endregion
    }
}

View Code

DiskInfo,该类继承DeskBand,用于落实工作以及界面,代码如下:

using DataStruct;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using WCFServer;

namespace MyDiskInfo
{
    /// <summary>
    /// 固态硬盘信息显示控件
    /// </summary>
    public partial class DiskInfoCtrl : UserControl
    {
        #region 字段
        private Thread _thread = null;
        private IClientServer _client = new ClientServer();
        private double _width = 140;
        private double _height = 30;
        private int _interval = 60 * 1000; //刷新间隔
        private DiskModel _diskInfo = null;
        private DiskInfoViewModel _model = new DiskInfoViewModel();
        #endregion

        #region 构造函数
        public DiskInfoCtrl()
        {
            InitializeComponent();

            //尺寸
            this.Width = _width;
            this.Height = _height;

            this.DataContext = _model;

            ShowDiskInfo();

            _thread = new Thread(new ThreadStart(() =>
            {
                while (true)
                {
                    Thread.Sleep(_interval);

                    ShowDiskInfo();
                }
            }));
            _thread.Start();
        }
        #endregion

        #region 显示硬盘信息
        /// <summary>
        /// 显示硬盘信息
        /// </summary>
        private void ShowDiskInfo()
        {
            BackWork.Run(() =>
            {
                _diskInfo = _client.GetDiskInfo();
            }, () =>
            {
                _model.Info = string.Format("{0}G {1}G {2}PE", _diskInfo.LBA_TodayWrite, _diskInfo.LBA_Write, _diskInfo.PE);
            }, (ex) => { });
        }
        #endregion

        #region 释放资源
        public void ClearResources()
        {
            if (_thread != null)
            {
                _thread.Abort();
                _thread = null;
            }
        }
        #endregion

    }

    #region DiskInfoViewModel
    public class DiskInfoViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private string _Info;
        public string Info
        {
            get { return _Info; }
            set
            {
                _Info = value;
                OnPropertyChanged("Info");
            }
        }

        public void OnPropertyChanged(string name)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }
    }
    #endregion

}

View Code

心想事成工作界面的WPF用户控件:

XAML:

<UserControl x:Class="MyDiskInfo.DiskInfoCtrl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="30" d:DesignWidth="120" >
    <Grid>
        <TextBlock Text="{Binding Info}" FontFamily="微软雅黑" FontSize="12" Foreground="White" TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
    </Grid>
</UserControl>

View Code

后台代码:

using DataStruct;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using WCFServer;

namespace MyDiskInfo
{
    /// <summary>
    /// 固态硬盘信息显示控件
    /// </summary>
    public partial class DiskInfoCtrl : UserControl
    {
        #region 字段
        private Thread _thread = null;
        private IClientServer _client = new ClientServer();
        private double _width = 140;
        private double _height = 30;
        private int _interval = 60 * 1000; //刷新间隔
        private DiskModel _diskInfo = null;
        private DiskInfoViewModel _model = new DiskInfoViewModel();
        #endregion

        #region 构造函数
        public DiskInfoCtrl()
        {
            InitializeComponent();

            //尺寸
            this.Width = _width;
            this.Height = _height;

            _diskInfo = _client.GetDiskInfo();
            _model.Info = string.Format("{0}G {1}G {2}PE", _diskInfo.LBA_TodayWrite, _diskInfo.LBA_Write, _diskInfo.PE);
            this.DataContext = _model;

            _thread = new Thread(new ThreadStart(() =>
            {
                while (true)
                {
                    Thread.Sleep(_interval);

                    BackWork.Run(() =>
                    {
                        _diskInfo = _client.GetDiskInfo();
                    }, () =>
                    {
                        _model.Info = string.Format("{0}G {1}G {2}PE", _diskInfo.LBA_TodayWrite, _diskInfo.LBA_Write, _diskInfo.PE);
                    }, (ex) => { });
                }
            }));
            _thread.Start();
        }
        #endregion

        #region 释放资源
        public void ClearResources()
        {
            if (_thread != null)
            {
                _thread.Abort();
                _thread = null;
            }
        }
        #endregion

    }

    #region DiskInfoViewModel
    public class DiskInfoViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private string _Info;
        public string Info
        {
            get { return _Info; }
            set
            {
                _Info = value;
                OnPropertyChanged("Info");
            }
        }

        public void OnPropertyChanged(string name)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }
    }
    #endregion

}

View Code

    类库是要签的:

另外代码就无粘了,上面粘的代码,去丢业务代码,写个测试的界面,也足以走起,程序写好后,怎么设置为,我勾勒了个Install.bat代码如下:

@echo off

"%~dp0gacutil.exe" /if "%~dp0MyDiskInfo.dll"
"%~dp0RegAsm.exe" "%~dp0MyDiskInfo.dll"
reg import "%~dp0register.reg"

"%~dp0ServiceInstallUtil\InstallUtil.exe" "%~dp0MyDiskInfoService.exe"
sc config MyDiskInfoService start= auto
sc config MyDiskInfoService type= interact type= own
net start MyDiskInfoService

taskkill /f /im explorer.exe 
start explorer.exe 

Pause

View Code

自我是Win10系,由于GitHub上的,安装后DeskBand并不曾亮在Windows工具栏菜单中,可能是注册表写的职位不对,我勾勒了个register.reg,代码如下:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\CLSID\{C7B92F87-7E59-467F-A6FF-9518DADA1C2C}]
@="DiskInfo"
"MenuText"="DiskInfo"
"HelpText"="Show DiskInfo"

[HKEY_CLASSES_ROOT\CLSID\{C7B92F87-7E59-467F-A6FF-9518DADA1C2C}\Implemented Categories]

[HKEY_CLASSES_ROOT\CLSID\{C7B92F87-7E59-467F-A6FF-9518DADA1C2C}\Implemented Categories\{00021492-0000-0000-C000-000000000046}]

[HKEY_CLASSES_ROOT\CLSID\{C7B92F87-7E59-467F-A6FF-9518DADA1C2C}\Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}]

[HKEY_CLASSES_ROOT\CLSID\{C7B92F87-7E59-467F-A6FF-9518DADA1C2C}\InprocServer32]
@="mscoree.dll"
"ThreadingModel"="Both"
"Class"="MyDiskInfo.DiskInfo"
"Assembly"="MyDiskInfo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=bec8b29cd4c20aff"
"RuntimeVersion"="v4.0.30319"

[HKEY_CLASSES_ROOT\CLSID\{C7B92F87-7E59-467F-A6FF-9518DADA1C2C}\InprocServer32\1.0.0.0]
"Class"="MyDiskInfo.DiskInfo"
"Assembly"="MyDiskInfo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=bec8b29cd4c20aff"
"RuntimeVersion"="v4.0.30319"

[HKEY_CLASSES_ROOT\CLSID\{C7B92F87-7E59-467F-A6FF-9518DADA1C2C}\ProgId]
@="MyDiskInfo.DiskInfo"

View Code

最终效果图:

   
存在的题目:Win10网下健康,Win7操作系统下,背景无法透明,如果DeskBand修改为持续Form并且安装TransparenceKey属性为BackColor,依然无法实现透明,最后放弃了。

   
由于DeskBand没有权限读取固态硬盘信息,我写了只Windows服务来读取信息,Windows服务的安全性设置也“这是一点一滴可信的应用程序”,使用WCF实现进程之中管道通信来把数量传为DeskBand显示。

   
Windows服务登记也开机启动,但是DeskBand不是开机启动,需要自己勾选能才显示出,DeskBand的自动启动自并未实现,网上资料多是C++的,用勾子实现。

完代码如下:

MyDiskInfo_WPF版_固态硬盘写入量信息放任务栏工具栏