WinSxS 混乱导致的应用程序不能启动
2008-12-16 18:04
211 查看
本文转自 http://blogs.itecn.net/blogs/smallfrogs/
有人看过下面的MessageBox提示信息吗:
---------------------------
C:/dllsxstest.exe
---------------------------
C:/dllsxstest.exe
由于应用程序配置不正确,应用程序未能启动。重新安装应用程序可能会纠正这个问题。
---------------------------
确定
---------------------------
如果看到这个错误,那么一定是因为运行库的manifest混乱或破坏导致WinSxS机制无法正常使用从而引起应用程序加载失败。
从Windows XP开始,微软引入了WinSxS机制用于解决DLL版本冲突的问题。解决方法是通过一个额外的清单文件(manifest)记录所需要的运行库的版本号等信息。进程创建的时候,CSRSS进程通过SxS.DLL模块解析manifest文件,然后加载合适的DLL版本。
今天,我这里处理了一个WinSxS版本混乱导致的应用程序无法加载的问题。
环境如下:
有一个EXE文件,不依赖任何的运行库
有很多DLL文件,分别在EXE文件目录的子目录下
EXE文件所在目录下有一套安装的VC8运行库
DLL文件需要依赖VC8运行库
因为各种原因,没有使用 vcredist_x86.exe 把VC8运行库安装到Windows/WinSxS目录下面
使用的时候发现,EXE文件加载DLL的时候,总是提示加载失败。DLL无法启动。我用 Process Monitor 监视了一下文件的读写操作,发现EXE文件在加载DLL的时候,CSRSS总是去读取 Windows/WinSxS 目录下的运行库文件,由于没有使用 vcredist_x86.exe 把VC8运行库安装到Windows/WinSxS目录下面,因此DLL加载失败了。
我很奇怪的问题是,为什么总是忽略了EXE目录下的manifest文件,而总是使用 Windows/WinSxS 目录下的文件呢?
以前知道manifest文件可以外置,也可以内置到PE文件的资源里面,难道是内置的问题吗?用Resource Hacker打开DLL文件,果然发现了内置的清单文件。把这个资源结点删除以后,保存退出,然后再使用EXE文件加载这个DLL文件,OK~问题解决了。这次使用的是EXE目录下的运行库文件而没有使用Windows/WinSxS目录下的文件了。
BTW:对于开发人员来说,自然不能编译以后再手工删除这个资源结点,解决方法很简单,把工程的manifest设置里面的 embedded manifest 功能关闭掉,这样编译以后就会出现编译生成的目标文件和一个额外的manifest文件。使用的时候,系统会首先尝试到Windows/WinSxS目录下面寻找文件,如果文件不存在,那么会在EXE文件所在目录下寻找,而不是去DLL所在目录下寻找文件。
问题解决以后,就需要想想问什么只有在部分系统上面出现这个问题了,检查发现:没有问题的系统都使用vcredist_x86.exe 把VC8运行库安装到Windows/WinSxS目录下面了,有问题的系统,发现WinSxS目录下没有运行库文件,自然不能使用了。
目前,很多软件都使用了VC8开发,而且都使用 vcredist_x86.exe 把VC8运行库安装到Windows/WinSxS目录下面,但是有某些软件在卸载的时候,又把这个运行库卸载了,结果就会导致类似提示“由于应用程序配置不正确,应用程序未能启动。重新安装应用程序可能会纠正这个问题”的错误的出现。这是最常见的一种现象。另外还有下面的几种可能会导致WinSxS混乱:
manifest文件被破坏
复制了错误的manifest文件到错误的目录,导致manifest文件里面记录的内容和实际的DLL版本不符
最后,如果你碰到提示“由于应用程序配置不正确,应用程序未能启动。重新安装应用程序可能会纠正这个问题”,最佳的操作方法是看看这个文件依赖的运行库是否齐备,如果不会看,最简单的办法就是重新安装所有的运行库版本到系统里面。
下面是所有常见的32位运行库版本的下载地址:
适用于 Visual C++ 2005 开发的程序的运行库版本:http://www.microsoft.com/downloads/details.aspx?FamilyID=32bc1bee-a3f9-4c13-9c99-220b62a191ee&displaylang=zh-cn
适用于 Visual C++ 2005 SP1 开发的程序的运行库版本:http://www.microsoft.com/downloads/details.aspx?familyid=200B2FD9-AE1A-4A14-984D-389C36F85647&displaylang=zh-cn
适用于 Visual C++ 2008 开发的程序的运行库版本:http://www.microsoft.com/downloads/details.aspx?familyid=9B2DA534-3E03-4391-8A4D-074B9F2BC1BF&displaylang=zh-cn
适用于 Visual C++ 2008 SP1 开发的运行库版本:http://www.microsoft.com/downloads/details.aspx?familyid=A5C84275-3B97-4AB7-A40D-3802B2AF5FC2&displaylang=zh-cn
如果你不知道你使用的程序是什么版本开发的,那么就全部安装吧,嘿嘿~
BTW:WinSxS 技术从 Windows XP 开始引入,一直发扬到 Windows Vista 系统里面,表现形式就是随着系统使用时间的增加,Windows/WinSxS 目录会越来越大,这一点在 Windows Vista 系统里面会特别突出,因为 Windows Vista 系统的系统文件都是使用 WinSxS 目录存放的,Windows/System32 目录下看到的大部分文件实际上是 WinSxS 目录下文件的一个 Hard Link 而已 :)
有人看过下面的MessageBox提示信息吗:
---------------------------
C:/dllsxstest.exe
---------------------------
C:/dllsxstest.exe
由于应用程序配置不正确,应用程序未能启动。重新安装应用程序可能会纠正这个问题。
---------------------------
确定
---------------------------
如果看到这个错误,那么一定是因为运行库的manifest混乱或破坏导致WinSxS机制无法正常使用从而引起应用程序加载失败。
从Windows XP开始,微软引入了WinSxS机制用于解决DLL版本冲突的问题。解决方法是通过一个额外的清单文件(manifest)记录所需要的运行库的版本号等信息。进程创建的时候,CSRSS进程通过SxS.DLL模块解析manifest文件,然后加载合适的DLL版本。
今天,我这里处理了一个WinSxS版本混乱导致的应用程序无法加载的问题。
环境如下:
有一个EXE文件,不依赖任何的运行库
有很多DLL文件,分别在EXE文件目录的子目录下
EXE文件所在目录下有一套安装的VC8运行库
DLL文件需要依赖VC8运行库
因为各种原因,没有使用 vcredist_x86.exe 把VC8运行库安装到Windows/WinSxS目录下面
使用的时候发现,EXE文件加载DLL的时候,总是提示加载失败。DLL无法启动。我用 Process Monitor 监视了一下文件的读写操作,发现EXE文件在加载DLL的时候,CSRSS总是去读取 Windows/WinSxS 目录下的运行库文件,由于没有使用 vcredist_x86.exe 把VC8运行库安装到Windows/WinSxS目录下面,因此DLL加载失败了。
我很奇怪的问题是,为什么总是忽略了EXE目录下的manifest文件,而总是使用 Windows/WinSxS 目录下的文件呢?
以前知道manifest文件可以外置,也可以内置到PE文件的资源里面,难道是内置的问题吗?用Resource Hacker打开DLL文件,果然发现了内置的清单文件。把这个资源结点删除以后,保存退出,然后再使用EXE文件加载这个DLL文件,OK~问题解决了。这次使用的是EXE目录下的运行库文件而没有使用Windows/WinSxS目录下的文件了。
BTW:对于开发人员来说,自然不能编译以后再手工删除这个资源结点,解决方法很简单,把工程的manifest设置里面的 embedded manifest 功能关闭掉,这样编译以后就会出现编译生成的目标文件和一个额外的manifest文件。使用的时候,系统会首先尝试到Windows/WinSxS目录下面寻找文件,如果文件不存在,那么会在EXE文件所在目录下寻找,而不是去DLL所在目录下寻找文件。
问题解决以后,就需要想想问什么只有在部分系统上面出现这个问题了,检查发现:没有问题的系统都使用vcredist_x86.exe 把VC8运行库安装到Windows/WinSxS目录下面了,有问题的系统,发现WinSxS目录下没有运行库文件,自然不能使用了。
目前,很多软件都使用了VC8开发,而且都使用 vcredist_x86.exe 把VC8运行库安装到Windows/WinSxS目录下面,但是有某些软件在卸载的时候,又把这个运行库卸载了,结果就会导致类似提示“由于应用程序配置不正确,应用程序未能启动。重新安装应用程序可能会纠正这个问题”的错误的出现。这是最常见的一种现象。另外还有下面的几种可能会导致WinSxS混乱:
manifest文件被破坏
复制了错误的manifest文件到错误的目录,导致manifest文件里面记录的内容和实际的DLL版本不符
最后,如果你碰到提示“由于应用程序配置不正确,应用程序未能启动。重新安装应用程序可能会纠正这个问题”,最佳的操作方法是看看这个文件依赖的运行库是否齐备,如果不会看,最简单的办法就是重新安装所有的运行库版本到系统里面。
下面是所有常见的32位运行库版本的下载地址:
适用于 Visual C++ 2005 开发的程序的运行库版本:http://www.microsoft.com/downloads/details.aspx?FamilyID=32bc1bee-a3f9-4c13-9c99-220b62a191ee&displaylang=zh-cn
适用于 Visual C++ 2005 SP1 开发的程序的运行库版本:http://www.microsoft.com/downloads/details.aspx?familyid=200B2FD9-AE1A-4A14-984D-389C36F85647&displaylang=zh-cn
适用于 Visual C++ 2008 开发的程序的运行库版本:http://www.microsoft.com/downloads/details.aspx?familyid=9B2DA534-3E03-4391-8A4D-074B9F2BC1BF&displaylang=zh-cn
适用于 Visual C++ 2008 SP1 开发的运行库版本:http://www.microsoft.com/downloads/details.aspx?familyid=A5C84275-3B97-4AB7-A40D-3802B2AF5FC2&displaylang=zh-cn
如果你不知道你使用的程序是什么版本开发的,那么就全部安装吧,嘿嘿~
BTW:WinSxS 技术从 Windows XP 开始引入,一直发扬到 Windows Vista 系统里面,表现形式就是随着系统使用时间的增加,Windows/WinSxS 目录会越来越大,这一点在 Windows Vista 系统里面会特别突出,因为 Windows Vista 系统的系统文件都是使用 WinSxS 目录存放的,Windows/System32 目录下看到的大部分文件实际上是 WinSxS 目录下文件的一个 Hard Link 而已 :)
相关文章推荐
- windows下nginx的安装、使用及80端口被占用导致nginx不能启动问题的解决
- oracle客户端监听器不能自动启动,导致连接数据库失败
- 由于修改机器名导致Oracle TNS Listener不能启动
- C++应用程序出现 0xc0150002 错误导致无法启动跟踪解决
- 网卡mtu 值不同导致rac 2节点ASM不能同时启动 ORA-27550: Target ID protocol check failed.
- 更改SQL Server最大内存大小导致不能启动的解决方法
- 解决修改错参数导致数据库不能启动问题
- 由于密码修改导致MSSQL服务不能启动
- LoadModule php5_module 参数导致apache不能启动
- ubuntu升级导致virtualbox不能启动问题
- RichEdit导致到应用程序无法启动
- Ubuntu与Win7双系统下,改变分区导致系统不能启动,进入rescue模式后恢复系统的方法
- oracle 11g 表空间的存储文件错误,导致数据库不能启动
- 80端口被Pid为4的未知程序占用导致Apache不能启动的解决方法
- Eclipse非正常关闭导致不能正常启动
- hadoop中namenode不能启动,导致浏览器不能连接
- sql2008 启动报错:应用程序的组件中发生了无法处理的异常和值不能为空 viewinfo(已解决!)
- DG不能自动mount导致数据库不能正常启动:ORA-01157、ORA-01110、ORA-17503、ORA-15001、ORA-15001
- RHEL上fstab配置错误导致不能启动的解决方法