这边记录解决一个问题的过程和感受。这种感觉每个搞IT的人或多或少都感受过,是程序人独有的快乐之一。只是大部分人没有将这种感觉记录下来。但是当你记录时,这种感觉也早已消失。

    需求:通过程序抓取outlook中的寻呼栏位

       获取outlook联系人寻呼字段-LMLPHP

    当然这个需求被我简化了,实际上这个栏位记录的是员工的工号。之前通过IIS我可以抓取域用户名。在我的概念里,我以为这工号信息也该是域管控的信息之一。因此便朝着域的方向

  查找了些资料,发现.net中有程序集可以抓取域中信息

       获取outlook联系人寻呼字段-LMLPHP

    编写了如下代码:

      获取outlook联系人寻呼字段-LMLPHP

    起初我猜UserPrincipal的EmployeeId栏位可能表示工号,但是取出来发现是空的,所以我猜这个栏位并没有被利用起来,邮件地址和域用户名都取到了,我只要顺着这个

  UserPrincipal类的属性来找寻呼这个栏位。

      获取outlook联系人寻呼字段-LMLPHP

    找了半天,并没有发现UserPrincipal有这个属性。但是发现了有个GetUnderlyingObject方法,而且提供的注释似乎有点搭边

       获取outlook联系人寻呼字段-LMLPHP

    返回的object,可以转换为DirectoryEntry对象,大致看了下这个对象的属性,也没有发现寻呼这个栏位

      获取outlook联系人寻呼字段-LMLPHP

    浮躁的我在找类似paging属性的地方折腾了些许,觉得此路不通。于是换个思路,既然寻呼是出现在outlook中,本该直接从outlook入手,之前接触过最多的是Excel的程序编写,查找

  资料发现同样的outlook一样有编程API

      获取outlook联系人寻呼字段-LMLPHP

      首先就入了坑,这边很让人激动的是ContactItem,不就是联系人的信息嘛,于是下面红色框出的代码就很让人兴奋了,PagerNumber不就是寻呼号嘛,正觉得方向找对后,调试

  发现只能遍历出一个联系人?!后来发现,原来这段代码对应的是Outlook中联系人文件夹中已经维护的联系人,

  平时,我在outlook客户端没有使用过这个功能,不知啥时咋误操作添加进一个联系人,而且该人已离职。

       获取outlook联系人寻呼字段-LMLPHP获取outlook联系人寻呼字段-LMLPHP

    我立刻明白我要找的是全球通讯薄,因此又折腾了一波代码

      获取outlook联系人寻呼字段-LMLPHP

    因为我在AddressEntry接口中同样没有找到Pager这样的属性,因此发现它提供了GetContact()方法,窃以为可以通过获取ContactItem,进而获取到它的PagerNumber属性,前途

  又是一片光明啊,但是随之而来的又一次失落,就是这个GetContact()获得的ContactItem是null,没有深究为什么,只是觉得不解。

    浮躁的我似乎已经折腾够了,开始犹豫了:这个寻呼字段是某个人员维护进来的,outlook当然有数据来源,这个来源很可能是我们自己的库。我从那边抓似乎就可以。另外更简单

  的是我完全可以根据域账号到员工信息里取出工号。那我花这么多精力通过程序的方法获取工号似乎就有点舍本逐末了。

    但是仔细思考一下,发现也并不完全是这样,outlook里的信息也是经过处理过后才显示出来的,因此它过滤了些无效信息,其次,我不需要连数据库,处理数据源,很可能有多个

  数据来源,因为可能有多个域,我自己去抓,可能会面临其他的如权限和信息完整准确以及后续维护问题。

    再次可能也是比较主要的是一个虚荣心,其实大概是每个程序员心底的要强吧,不然也不会有很多重复造轮子的现象。只是如果这次抓出寻呼字段来不是为了证明自己的技术,只是

  找到一种解决问题的方法,且似乎是较优的,且似乎和技术搭点边花了些时间琢磨的,如果这样成功了,就会很开心。

    犹豫了些许后,我觉得实在搞不出来也就算了,毕竟问题不大,虽然有些不快,但是我还是会在权衡了利弊后向boss汇报不好搞,虽然心底可能认为如果有足够的时间和必要性还是

  能琢磨出来的。

    所以打算在午饭前,再次寻思寻思,也许这是最后一波团了,推不了对方基地,就GG。

    还记得上面最先尝试抓取域信息的方式中的UserPrincipal对象地GetUnderlyingObject方法吗,似乎这是个黑盒,总感觉返回object对象的方法里面提供了很多未知的可能,首先将其

  转换为DirectoryEntry对象。在网上游荡的时候,看到它有个InvokeSet方法,有个示例似乎调用了这个方法且传了一个字符串常量作为参数,我想既然可以这样玩,必然有个InvokeGet方法,

  我也传个参数,反正就试试,看看能获得啥信息。传什么参数?之前在Outlook那发现pager属性对应的是pagerNumber字段,因此我大胆地使用该字符串参数,虽然不见得outlook那的属性和这边

  的代码有啥直接关联,但既然DirectoryEntry对象没有为我们列出所有属性,也许里面的属性太多,万一这个属性存在呢!而且尝试过Outlook调用代码和域调用代码,发现里面对于联系人有些属性

  定义得非常像,没有理由不尝试。

  代码如下:

      获取outlook联系人寻呼字段-LMLPHP

    原本不抱希望的,但突然就成了的感觉似乎和糖一样甜

      获取outlook联系人寻呼字段-LMLPHP

  总结

    1,  前面没有提到的是搜索问题的能力,其实在解决问题的过程中,我在google上尝试用英文短语和关键字做了大量搜索,它的重要性在于搜索结果可能不断提示你新的尝试方向。

    2,  问题的解决实际上有几次甚至多次的迭代,一种方案不行可以迅速切换为另一种,总归有那么个时间点,你会和让你满意的解决方案邂逅。

    3,  如果确定了这个难题是非解决不可,没有其他替代方案,且你确信一定是可以解决的,那么我以为坚持还是很重要的,毕竟后天很美好,不能在明晚就缴械投降。

    4,  问题驱动或是项目驱动似乎可以让我们接触更多知识,就像这次,之前我完全没注意Outlook API的存在。

    5,  一波三折后,转角遇到了爱,这种感觉就像进了桃花源。

05-18 17:01