背景

  问题源自论坛用户反馈,他用管家有几年了,之前使用IE都很正常,没有任何问题,但是最近突然发现,启动IE时,就会出现系统错误提示:无法启动此程序,因为计算机中丢失 api-ms-win-core-path-l1-1-0.dll。尝试重新安装该程序以解决此问题。点确定之后,IE依然可以使用,但是中途或者新建Tab的时候可能还会弹出来。

  

  看到这个DLL的名字,突然想起了一年前,lorne跟过的一个问题,微软Office2016函数转发器的bug(参考[1]),但是从这个提示来看,并不是同一个问题,但是可能跟Office2016有关系,问了下用户,果然在最近安装了最新的Office2016。

  但是据用户说,退出管家之后,就没有问题了,在用户的机器上面实验,确实如此,这就奇怪了,管家的模块并不依赖这个特殊的DLL,而且从弹框来看,应该是某个模块的导入表里面有这个DLL的依赖。

跟进

  最近用户刚好有时间,机器是闲置的,因此抽出时间看看这个问题的原因是什么。

  1、首先在用户的机器上面全盘搜索了一下,确实没有api-ms-win-core-path-l1-1-0.dll这个模块,看来系统也不是瞎提示o(∩_∩)o 。那到底是哪个模块依赖这个DLL呢,先取了一个IE的dump,然后重启IE,用ProcessMonitor监控发现跟OChelper.dll有关系,十有八九是OChelper.dll静态依赖了api-ms-win-core-path-l1-1-0.dll。

  

  2、把上面抓到的dump打开看了下,发现有一个线程正在请求Com接口,请求进程内接口是需要加载DLL,线程确实卡在了Load某个动态库的地方,这个动态库就是OChelper.dll,这里也印证了上面的思路。顺便看了下接口的CLSID和接口IID,发现IE是在把OChelper.dll当成BHO进行加载,并且正在请求IObjectWithSite接口。

  0:000:x86> du 0604b5b4

  0604b5b4 "C:\Program Files (x86)\Microsoft"

  0604b5f4 " Office\root\Office16\OCHelper.d"

  0604b634 "ll"

  0:018:x86> dt 567bff94 GUID

  TSWebMon!GUID

  {fc4801a3-2ba9-11cf-a229-00aa003d7352}

    +0x000 Data1 : 0xfc4801a3

    +0x004 Data2 : 0x2ba9

    +0x006 Data3 : 0x11cf

    +0x008 Data4 : [8] "???"

  0:018:x86> dt 0604c638 GUID

  TSWebMon!GUID

  {31d09ba0-12f5-4cce-be8a-2923e76605da}

    +0x000 Data1 : 0x31d09ba0

    +0x004 Data2 : 0x12f5

     +0x006 Data3 : 0x4cce

    +0x008 Data4 : [8] "???"

  

  

  3、OChelper.dll到底是何方神圣,从目录来看,它应该是Office2016的组件,而且还是一个BHO组件(参考[4]),到用户的注册表浏览了一下,确实被注册成了BHO,但是用户机器上面,默认是不加载这个BHO的。结合用户最近刚装的Office2016,问题逐渐明了。检查了OCHelperd.ll的导入表,静态依赖了api-ms-win-core-path-l1-1-0.dll,但是用户机器上面肯定是没有这个DLL的,也就是说,任何进程(不管什么原因)加载OCHelperd.ll,实际上都会报错的。

  

  

   4、回到最开始的问题,为什么用户把管家退出就不报错了呢?后来通过管家的注入模块(注入到IE里面)的逻辑,发现管家有两个模块的BHO加载逻辑会触发IE去加载其它的BHO,导致IE去拉起OCHelper.dll。而退出管家之后,因为注入模块不注入IE了,因此问题就不暴露了。但是管家注入模块使用的BHO加载逻辑并不是非常特殊的操作,而且整个逻辑使用了多年,因为这个问题去修改得不偿失。

  5、那么禁掉用户的OCHelper.dll是否可行呢?试了下不管是干掉OCHelper.dll的组件注册表还是把OCHelper.dll删掉或者改名,都可以解决这个问题。而且用户使用Office2016也没有什么影响(也不应该有什么影响,否则早就出问题了),后来在网上查了下,这个OCHelper模块跟微软Office2016发布时同步的一个新技术有关系——ClickToRun,其实也不算什么新技术,国内的一些游戏厂商在几年前就出过边下边玩的功能,基本原理就是让用户尽快得体验到必要功能,因此只下载必要的模块(需要啥下载啥),其它的模块在后台慢慢再下载。这里微软的思想也一样,就是不需要用户一口气把几百M上G的安装包下载下来再安装个2-30分钟,而且几分钟之类就可以使用基本功能(依赖高速带宽,譬如你想快点打开一个word文档,可能几分钟就可以看到word文档的内容了,但是呢编辑等高级功能还得再等等)。

  6、从这个技术的特点来看,有可能是用户在下载组件之后,运行时库没有下载成功,或者运行库的安装包没有下载成功,或者是,因为当时用不到这个组件,因此一直没有去加载安装运行时库。后来找了几个Office2016的环境看了下,并没有这个用户的问题,看看可能是极个别的个例。

解决方案

  1、微软的推荐方案是安装VS2015的运行时库(参考[3]),这个没有让用户试,但是应该也是可以解决的,把所有缺失的DLL都补齐肯定是可以解决的,但是建议不要一个一个的去补。

  2、如果全网大面积的出现该问题,建议是排除IE不加载C:\Program Files (x86)\Microsoft Office\root\Office16\OCHelper.dll这个模块,之前管家就是使用的该方案,通过远程控制排除IE对某些模块的加载(当然这个得依赖客户端之前已经部署了该功能)。

  3、对于这个用户,经过详细询问后,其实他平时也就是用Office写写文档,PPT,没用什么高级功能,因此把他的OCHelper.dll这个文件给屏蔽了,对于这个用户来说,这其实是最简单,成本最小的方法。

坑在哪里

  总结一下,这个问题其实感觉是Office2016的新功能留的坑(标题的由来),或者叫bug也行,在这个用户这里OCHelper可能永远也没机会被加载,问题也就不会发现,但是不小心就被我们踩了!

参考文档

  [1] http://km.oa.com/group/23764/articles/show/249213 微软Office2016的惊天bug

  [2] http://answers.microsoft.com/zh-hans/ie/forum/ie8-windows_7/%E5%90%AF%E5%8A%A8ie%E6%8A%A5%E9%94%99api-ms-win/ed4c563e-51af-4704-9beb-9f45d918897b 启动IE报错api-ms-win-core-path-l1-1-0.dll 丢失

  [3] http://www.crifan.com/win7_can_not_launch_application_for_computer_missing_api_ms_win_crt_runtime_1_1_0_dll/ Win7中出错:无法启动此程序,因为计算机中丢失api-ms-win-crt-runtime-|1-1-0.dll

  [4] http://www.systemlookup.com/CLSID/72557-OCHelper_dll.html

  [5] http://soft.yesky.com/office/138/33691138.shtml 新Office安装采用Click-to-Run v2.0技术

  [6] http://searchenterprisedesktop.techtarget.com/definition/Microsoft-Click-To-Run Microsoft Click-To-Run

  [7] https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.ole.interop.iobjectwithsite.aspx IObjectWithSite Interface

MS Office2016留下的坑的更多相关文章

  1. 把之前CompletableFuture留下的坑给填上。

    你好呀,我是歪歪. 填个坑吧,把之前一直欠着的 CompletableFuture 给写了,因为后台已经收到过好几次催更的留言了. 这玩意我在之前写的这篇文章中提到过:<面试官问我知不知道异步编 ...

  2. 写个续集,填坑来了!关于“Thread.sleep(0)这一行‘看似无用’的代码”里面留下的坑。

    "我报名参加金石计划1期挑战--瓜分10万奖池,这是我的第2篇文章,点击查看活动详情" 你好呀,我是居家十三天只出了一次小区门的歪歪. 这篇文章是来填坑的,我以前写文章的时候也会去 ...

  3. 转:【iOS开发每日小笔记(十一)】iOS8更新留下的“坑” NSAttributedString设置下划线 NSUnderlineStyleAttributeName 属性必须为NSNumber

    http://www.bubuko.com/infodetail-382485.html 标签:des   class   style   代码   html   使用   问题   文件   数据 ...

  4. 更改用户host留下的坑

    前言:  我们在创建数据库用户的时候都会指定host,即一个完整的用户可描述为 'username'@'host' .创建用户时不显式指定host则默认为%,%代表所有ip段都可以使用这个用户,我们也 ...

  5. VS2015开发Android,自带模拟器无法调试、加载程序,算是坑吗

    VS2015出来后,确定变化很大,什么android.ios的,不在话下.对于我这样传统型的人,也第一时间试用了一下(vs2003->vs2008->vs2012->vs2015). ...

  6. 多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类)

    前言:刚学习了一段机器学习,最近需要重构一个java项目,又赶过来看java.大多是线程代码,没办法,那时候总觉得多线程是个很难的部分很少用到,所以一直没下决定去啃,那些年留下的坑,总是得自己跳进去填 ...

  7. react-native 踩坑记

    最近在使用react-native的时候遇到了很多坑,这里给大家分享下 一.样式 react-native 虽然支持flex布局,但是所有的样式均是css样式的一个很小的集合,尤其是在安卓机下问题尤为 ...

  8. 冒泡 MS Azure 不便宜。。。

    一直在等 MS Azure 中国开卖, 最近有消息说正式商用了... 看看去,ok 发现官方网站 很奇葩.没有购买的地方 说毛线 啊 卧槽 欺骗感情还是吊人胃口? 好看了一下VM的价格,卧槽真不便宜. ...

  9. c#调用c++ dll 入坑记录

    1.DLL引用坑 [DllImport("NetDLL.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConve ...

随机推荐

  1. C#之读写压缩文件

    在处理文件时,常常会发现文件中有许多空格,耗尽了硬盘空间,.net的类提供了GZIP/Deflate算法可以压缩文件.这里只介绍了文件的压缩,但在实际应用更多的是压缩文件夹 压缩文件 解压文件 可以使 ...

  2. SQL SERVER之查询外键及索引

    --查询表或数据库中的所有外键 select A.name as 约束名, object_name(b.parent_object_id) as 外健表, c.name as 外键列, object_ ...

  3. SocketServer源码学习(一)

    SocketServer其实是对socket更高级的封装正如官网上说的:The socketserver module simplifies the task of writing network s ...

  4. [LeetCode] Number of Distinct Islands 不同岛屿的个数

    Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) conn ...

  5. spring初学总结思路

    spring初步学习总结 总概括有四个方面:IOC,AOP,JDBC,和事务管理 ioc:实现了new类的一个权力的反转.(平时new类导致代码冗余,手动new类无法满足动态new类的需求) aop: ...

  6. 【NOIP2009】Hankson 的趣味题

    题目描述 Hanks 博士是 BT (Bio-Tech,生物技术) 领域的知名专家,他的儿子名叫 Hankson.现在,刚刚放学回家的 Hankson 正在思考一个有趣的问题. 今天在课堂上,老师讲解 ...

  7. [SDOI2010]代码拍卖会

    题目描述 随着iPig在P++语言上的造诣日益提升,他形成了自己一套完整的代码库.猪王国想参加POI的童鞋们都争先恐后问iPig索要代码库.iPig不想把代码库给所有想要的小猪,只想给其中的一部分既关 ...

  8. [BZOJ]4162: shlw loves matrix II

    Time Limit: 30 Sec  Memory Limit: 128 MB Description 给定矩阵 M,请计算 M^n,并将其中每一个元素对 1000000007 取模输出. Inpu ...

  9. [UOJ UR#16]破坏发射台

    来自FallDream的博客,未经允许,请勿转载,谢谢. 传送门 先考虑n是奇数的情况,很容易想到一个dp,f[i][0/1]表示转移到第i个数,第i个数是不是第一个数的方案数,然后用矩阵乘法优化一下 ...

  10. Linux之grep命令

    概述 所有的类linux系统都会提供一个名为grep(global regular expression print,全局正则表达式输出)的搜索工具.grep命令在对一个或多个文件的内容进行基于模式的 ...