关于VS2005程序发布的问题

来源:互联网 发布:网络信号延长器 编辑:程序博客网 时间:2024/05/18 00:32

关于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查找。