什么是WINSXS文件夹 关于VS2005程序发布的问题

来源:互联网 发布:java应用服务器开发 编辑:程序博客网 时间:2024/04/30 12:07

 

什么是WINSXS文件夹

分类: 计算机知识库 649人阅读 评论(0) 收藏 举报
windows磁盘cmd工具linuxc

转自:http://blog.163.com/yuan_haoliang/blog/static/81198320097178431691/

 

从WINDOWS 98用到现在的7,自VISTA开始就出现了个莫名的winsxs文件夹,既不知道有什么用,也不能删除,想必很多坛友有此疑问吧,那我说说啥是winsxs。

谈到winsxs,就要从微软效仿linux而引进的一种新的文件储存方式,链接式(英文叫HARDLINK,不知汉语怎么翻译)。就是说比如我有一个文件,通常我要复制它,就要用到复制粘贴,储存空间加倍。但是用HARDLINK,通俗点讲,复制的仅仅只是一个索引而已,就是说有两个文件,但是共用一个储存空间。你删除其中任意一个,另一个都可以正常使用,而且只占用一份的空间。你改变其中任意一个,另一个随之改变。你粘贴时选择覆盖,另一个内容随之覆盖。

但是注意,如果你查看文件或者文件夹的属性,他们都会占空间。但是你查看磁盘的空间,你会发现不管HARDLINK多少次,都只占用一份空间,这也就是说连操作系统都无法分清是HARDLINK,还是真实的单独文件。比如你D盘10G文件,用hardlink把这10G的文件又做了一份,你查看磁盘属性,占用空间为10G,但是全选里面所有的文件,显示为20G。所以你装完Win7查看系统盘属性和全选系统文件后看属性他们显示的空间占用是不一致的

是不是很方便?

在VISTA/7下,可以用MKLINK这个命令创建这种HARDLINK,具体用法,你可以参考系统自带的MKLINK提示。

当然现在也有一个方便的可供批量使用的HARDLINK工具,集成在了右键菜单中,我放到附件里了,感兴趣的可以自己去下载。

安装了这个工具后,你再打开windows目录,看看有什么不一样?好多的系统文件左下角多了个红色的小箭头(快捷方式是蓝色的),用以标记被hardlink过的文件。你再看看他的属性,多了一项吧?

 

上面写着他的另一个副本在哪里呢!天哪,原来都在winsxs文件夹里。明白了吧!系统部署的时候,其实在install.wim里只有winsxs占用空间,其他都只是hardlink(原来是否奇怪过imagex的压缩比怎么这么大?),部署时先复制winsxs,然后将所需的系统文件用hardlink的方式部署到确定路径,一来达到统一管理的目的,二来方便误操作删除了系统文件后的自动恢复。

如果你升级系统补丁,他是先将文件放进winsxs,然后再部署到相应路径。在你使用“关闭windows的功能”时,也只是移除了系统文件的副本而已,系统文件本身还在winsxs中,并没有省空间。

在回头看看winsxs文件夹,好多人删除它了发现没有问题,呵呵,那是因为hardlink删除任意一个都不影响另一个。但当你安装新硬件的时候系统想从winsxs里部署驱动程序,于是他傻了!没有了winsxs自然也就不能自动更新了,总之一切的莫名的问题都来了。

现在清楚winsxs的作用了吧?

那么hardlink能为我们所用吗?答案是肯定的

应用举例一

列举一个hardlink的日常用法。比如玩魔兽争霸的朋友清楚,切换版本最麻烦了。但是用hardlink却可以很方便的解决这一问题,一劳永逸。先安装1.20版,将文件夹命名为1.20(最好删除那些无用的垃圾文件,不删除也无所谓,就是图个眼睛干净)。在别处(最好和1.20放在同一个文件夹里)建立4个文件夹,命名为1.21,1.22,1.23,1.24。然后安装附件中的工具,右键拖动1.20里所有的文件到1.21,松开右键,选择hardlink clone

 

然后就出现了魔兽争霸所有文件的hardlink,其中的文件夹是真实的,其他的文件都是hardlink。然后删除game.dll  ijl15.dll  storm.dll  war3.exe   War3Patch.mpq   worldedit.exe 这7个文件(因为版本的不同就取决与这7个文件)。下载1.21补丁,把其中的这7个文件拷到1.21文件夹中,OK,1.21的做好了,如法炮制,制作1.22,1.23,1.24,然后只需要运行各个目录下的魔兽就是所需版本了。如果你记下原来磁盘的空间,你会发现只占用了一个1.20的空间,添加了其他4个版本只多了那些不同的文件的空间,嘻嘻。(还有个技巧,删除其中4个MAPS文件夹,然后依次用右键中的JUNCTION复制MAPS到刚刚删除的4个目录中,这样就是对文件夹做了LINK,而不是文件,达到了所有版本的地图都一样的效果。神奇吧!

应用举例二

很多人都在苦恼不断增长的系统盘,可随着使用,系统盘增长是不可避免的,于是动起了USERS文件夹的注意。如果能把users文件夹移到其他盘,既方便了管理,也将这个日益增大的负担移除了系统盘。注意在资源管理器中是看不到users文件夹的,他的名字被映射成了“用户”,你用cmd的dir命令就可以看到他的真实名称。

先假设系统装在C盘,然后其他的文件放在了D盘,先用WIN7的光盘引导进PE(在PE里移动系统文件不会破坏他的权限),打开CMD(这个就不一步步的说了)然后随便运行一个程序,比如regedit,选择文件-导入。这里并不是要动注册表,只是利用了他的资源管理器而已。找到那个c:/users文件夹,右键移动到D盘,确保C盘已经没有users文件夹了。然后在CMD里输入mklink c:/users d:/users /j,这就为那个d:/USERS在C:/USERS创建了一个junction link,此后虽然在C盘由一个users文件夹,但是其内容的空间确实占在了D盘,呵呵

Vista/win7 32:

http://schinagl.priv.at/nt/hardlinkshellext/HardLinkShellExt_win32.exe

Vista/win7 64:

http://schinagl.priv.at/nt/hardlinkshellext/HardLinkShellExt_X64.exe



“应用程序配置不正确...”&Visual C++ 2005/2008程序发布的终极解决方法

分类: VC知识库 1486人阅读 评论(0) 收藏 举报
c++多线程x86encodingmfcxml

转自:http://hi.baidu.com/_%E2d_%B7%B3_%DE%B2%C2%D2/blog/item/966d62db05519263d1164e3c.html

 

 

方法一:

!!“由于应用程序的配置不正确,应用程序未能启动,重新安装应用程序可能会纠正这个问题”的解决方案

 

第一步,什么设置都不用改,什么静态链接还是动态链接都不管了,什么多线程调试什么多线程也不管了,就用默认的配置属性。

第二步,找到你要发布的程序,COPY出来,相关度的资源也COPY到恰当的位置。

第三步,找到D:/Program Files/Microsoft Visual Studio 9.0/VC/redist/x86/Microsoft.VC90.CRT下面的四个文件,三个dll,一个manifest文件。。。我这里用2008来说,2005就自己推。。。,COPY他们四个到你的程序目录下面。

第四步,准备一个辅助包,

Visual Studio 2008的用户下这个:

http://download.microsoft.com/download/7/5/0/7502f4e9-1f90-4895-9259-1bde67b8b9a1/vcredist_x86.exe

Visual Studio 2005 sp1的用户下这个:

http://download.microsoft.com/download/7/9/8/798325b7-8993-4ef9-9148-8db9ff4187fc/vcredist_x86.exe

然后也放在你的程序目录下面。

第五步,拷贝这些所有东西到目标机器上,然后先安装第四步下载的玩意,再运行你的程序,Over。。。

如果不放心的话还可以多拷贝点东西,到时候再决定看哪些是不需要的,到时候再删除被,反正是学习,不要怕犯错误。。。

至于MFC啥的我没试,总之我的程序是成功了的。

 

 

方法二:

这很让人恼火,可是怎么解决这个问题呢?配置不正确,想办法让它配置正确了不就行了。于是逐个研究vs2005产生的文件,就找到了exe.manifest,不知道微软弄这个东西做什么的。
打开一看原来是一个xml文件,如下所示:
<code>
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type='win32' name='Microsoft.VC80.CRT' version='8.0.50727.762' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' />
    </dependentAssembly>
  </dependency>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type='win32' name='Microsoft.VC80.MFC' version='8.0.50727.762' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' />
    </dependentAssembly>
  </dependency>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*' />
    </dependentAssembly>
  </dependency>
</assembly>
</code>
乱糟糟的一堆,但是这个name比较有趣,似乎是应用程序所依赖的一些库的名字。
好,搜索一下,果然,找到了这些东西。这些依赖文件位于:
C:/Program Files/Microsoft Visual Studio 8/VC/redist/x86
这个目录下面,你会找到上面xml的item中列出来的Microsoft.VC80.CRT和Microsoft.VC80.MFC这两个目录。剩下的那个Microsoft.Windows.Common-Controls应该是所有win32环境都有的。
现在需要做的就是建立一个目录,把上面的Microsoft.VC80.CRT和Microsoft.VC80.MFC目录下的的所有文件都拷贝进去,然后把你的release版的应用程序也拷贝进去。然后把整个目录压缩一下拷贝到没有安装过vs2005的机器上,解压缩,运行。
这次应该就不会出现“应用程序配置不正确,无法运行”的错误了。通过查看exe.mainifest文件的方法拷贝必要的库,制作“绿色”软件,虽然第一次麻烦一些,但总体上,比再生成个setup要快得多。
不知道微软是如何思考这个问题的,为什么每次都要把明明很简单的工作给复杂化,让人郁闷。

目前 硬件配置在提高,软件开发环境也在不停的升级,vs2008 beta2 Enterprise Edition已经发布,使用的结果感觉非常满意,比vs2005进步不少,首先在IDE环境的启动速度上比05要快,MFC的空间数量上也增加了几个,最重要的是vs2008应该是windows vista内核开发的主要工具,微软的东西向下兼容肯定是没有问题了,如果能够熟练使用vs2005那么vs2008应该一点问题都没有的,下面说下vs2005、vs2008程序发布的方法:

alt+F7->配置属性->C/C++->Code Generation->Runtime Library 属性一般在发布的时候要进行静态发布,因为目前的操作系统正在换代,平台比较多,所以debug:Multi-threaded Debug(MTd)、release:Multi-threaded(MT),当然如果工程里边需要依赖很多的dll,每个dll又不一定是静态发布,尤其是MFC extension DLL,必须为动态发布这时工程里肯定要包含MFC的运行库,所以这好似所有的工程就可以采用动态运行库的方法,debug:Multi-threaded Debug DLL(MDd)、release:Multi-threaded DLL(MD),这时可以采用共享MFC库的方式即alt+F7->配置属性->General->Project Defaults->Use of MFC->use mfc in a shared dll
vs2005
Debug 发行版 所依赖的库为:mfc80d.dll、Microsoft.VC80.DebugMFC.manifest、Microsoft.VC80.DebugMFC.manifest、msvcm80d.dll、msvcp80d.dll、msvcr80d.dll
Release 发布版  所依赖的库为:mfc80.dll、Microsoft.VC80.MFC.manifest、Microsoft.VC80.MFC.manifest、msvcm80.dll、msvcp80.dll、msvcr80.dll

vs2008
Debug 发行版 所依赖的库为:mfc90d.dll、Microsoft.VC90.DebugMFC.manifest、Microsoft.VC90.DebugMFC.manifest、msvcm90d.dll、msvcp90d.dll、msvcr90d.dll
Release 发布版  所依赖的库为:mfc90.dll、Microsoft.VC90.MFC.manifest、Microsoft.VC90.MFC.manifest、msvcm90.dll、msvcp90.dll、msvcr90.dll

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/guanchanghui/archive/2007/10/14/1824036.aspx



关于VS2005程序发布的问题

分类: WINDOWS和MFC程序设计 3916人阅读 评论(0) 收藏 举报
dllexex86mergec

关于VS2005程序发布的问题:其实就是程序能否找到运行时所需要的DLL的问题。

注意VS2003与VS2005的不同:
VS2003程序产生时可以选择产生manifest文件也可以选择不产生,但VS2005必须产生。manifest文件可以
是内嵌到程序的二进制资源文件中,也可以只产生一个外部的.manifest文件。
因为VS2005生成的程序运行时需要根据它的manifest文件来获取程序运行时需要哪些DLL文件,因此VS2005
程序必须生成manifest文件,如果manifest文件选择内嵌,则只需要把目标程序(exe文件或dll文件)发布
(复制)到目标机器即可,但如果manifest文件没有选择内嵌,则发布目标程序时还必须将目标程序的
manifest文件一起发布(复制)到目标机器上。

1.发布的前提条件:
  只有Release版本才能发布,DEBUG版本不能发布。
  对于这一点我存在疑问,我认为只要在目标机器上正确的位置安装了程序必须的文件(DLL,manifest)
  程序就可以正确的运行。
  而且我试过:将Debug版本DLL直接COPY到目标机器上注册,这一般不行(除非目标机器已经安装了程序
  运行需要的DLL和manifest),如果注册失败,可以运行vcredist_x86(vcredist_x64),然后再注册
  肯定能够成功。
  其实vcredist_x86只不过是安装VS2005所有的库文件而已(包括在winsxs文件夹中安装所有的manifest
  文件和DLL文件)。

2.EXE程序的发布和DLL的发布不同:
  EXE程序只要是静态链接的,可以直接发布到目标机器(COPY到目标机器)运行。如果不是静态链接的
  则目标机器上必须安装EXE程序所依赖的DLL和manifest文件(VS2005的manifest文件,不是程序的,
  程序的manifest文件已经内嵌在程序中拉)。
  DLL文件的路径:SYSTEMDIR/WINSxS
  VS2005 Manifest文件路径: SYSTEMDIR/WINSxS/Manifest
  但DLL程序即使是静态链接的,也需要DLL的支持才能够成功注册,不知道是什么原因(好像需要
  msvcr80.dll,否则注册时提示应用程序配置不正确的错误),如果不是静态链接的,就还需要其它
  一些DLL的支持,在DLL程序的manifest文件中会说明需要哪些VS2005系统manifest的支持,这些系统
  manifest文件内包含有一些DLL名称,这些DLL中包含有DLL程序所依赖的。


  利用Dependency程序查看程序所依赖的DLL。


3.不要混淆VS2005系统manifest文件和程序manifest文件。

4.注意DLL和Manifest都有系统和版本之分,例如系统有x86系统和amd64系统之分,32位系统选择x86,64

位系统选择amd64的,还要选择程序所需要的版本,例如762或其它。

5.msm文件(Merge modules文件)也可以用来发布程序。

  文件路径:program files/common files/merge modules
  
6.最后的做法:

  本来想利用vcredist_x86来完成发布,但用IS将它和程序一起打包后发现:vcredist_x86不能正确
  的安装(手动执行vcredist_x86是可以的哦~~~),因此还是不能注册DLL,听网上的一位朋友说:
  是因为IS安装过程中不能控制其它安装程序和可执行文件(当然也不能控制vcredist_x86的安装,
  想想也是~~),他还建议我最好不要在IS中调用其它安装程序和可执行文件(一个很好的建议,因为
  在安装程序安装过程中调用另一个安装程序或可执行文件确实不是一种好的方法),只好改用其它的
  方法实现。
  原本想把程序manifest文件中提到的VS2005系统manifest文件及其系统manifest文件中提到的DLL分别
  COPY(拷贝、发布)到目标机器的SYSTEMDIR/WINSxS/Manifest和SYSTEMDIR/WINSxS路径下,采用共享
  程序集的方式来实现,但觉得太繁琐,所以决定采用私有程序集方式实现,即把程序需要依赖的DLL及
  程序manifest文件提到的系统manifest文件都拷贝到目标机器上与程序相同文件夹中,并把系统
  manifest文件的名称改为程序manifest文件中提到的名称即可。


7.示例步骤:
  假设现在有一个名为test.dll的DLL需要发布到目标机器的X文件夹,具体步骤如下:
 

  a。用VS打开编译test.dll过程中所产生的manifest资源文件,或者直接用记事本打开
     manifest文件,查看需要用来支持test.dll的VS2005系统manifest文件。
  b。在SYSTEMDIR/WINSxS/Manifest目录下面查找上一步中得到的VS2005系统manifest文件,
     并根据test.dll的manifest文件中的名字将它名字改为类似Microsoft.VC80.CRT.manifest
     的形式,将test.dll和改名后的manifest文件一起拷贝到目标机器的X文件夹。
  c。用Dependency查看test.dll需要哪些DLL的支持。
  d。在SYSTEMDIR/WINSxS目录下面查找上一步中的DLL,找到后也将这些DLL拷贝到目标机器的
     X文件夹中。

现在再注册test.dll将成功。

改正:改正一个错误的认识,本以为exe程序只要是静态编译的就可以直接发布,后来发现错啦,有的

exe程序确实可以直接发布,有的则不可以。如果不可以,可以按照上面发布DLL的方法进行。

也可以直接这样做:

 将编译产生dll和manifest文件一起拷贝到目标机器上,试着注册dll,如果不可以注册成功,看提示
信息,如果是应用程序配置不正确,则肯定是系统目录中winsxs---manifest文件夹中缺乏程序需要
的manifest文件,还有可能提示缺少dll,都可以通过拷贝相应的manifest或dll文件到目标机器上解决

注意要拷贝到正确的目录,manifest要拷贝到manifest文件夹下,dll可以拷贝到程序所在目录,或系统
文件夹中

从上面我们可以看出程序查找DLL的方法:
1.如果将编译产生的程序和manifest文件放在一起,那么程序根据下面的步骤进行dll查找:
根据manifest文件在系统manifest文件夹中查找所需要的系统manifest文件,再根据找到的系统manifest
文件查找dll。因此如果系统manifest文件夹中没有所对应的manifest文件将出错。

2.如果将编译产生的程序和改名后的系统manifest文件放在一起,那么程序直接根据和它在同一个目录下的
系统manifest文件查找dll,使用这种方法即使系统manifest文件夹中没有所对应的manifest文件也不会
出错,因为程序根本不会对系统manifest文件夹进行查找。

3.如果将编译产生的程序和manifest文件以及改名后的系统manifest文件三者放在一起,程序还是根据1方法
进行dll查找。


原创粉丝点击