2008-09-21 40 views
3

从2005年开始,我发现无法简单地针对MS运行时构建DLL并将它们部署在一起(http://www.ddj.com/windows/184406482)。我对表单SxS和co深感困惑:MSDN文档非常差,带有循环引用;特别是因为我更像是一个Unix家伙,我发现所有这些都不具有信息性。我的核心问题是将DLL链接到msvc9或msvc8:由于这些运行时不是可重新分发的,因此链接和部署此类DLL的步骤是什么?特别是,如何生成清单(我不需要mt.exe,我希望在编译器中可移植的东西),它们是如何嵌入,使用的?并排组装意味着什么?在windows上构建和部署dll:SxS,清单和所有爵士乐

基本上,我在哪里可以找到任何类型的规范而不是MS术语?

谢谢大家谁回答,这是真正有用的,

回答

3

我们用一个简单的包含文件在我们所有的应用程序& DLL的,vcmanifest.h,然后将所有项目嵌入清单文件。

vcmanifest.h

/*----------------------------------------------------------------------------*/ 

#if _MSC_VER >= 1400 

/*----------------------------------------------------------------------------*/ 

#pragma message ("Setting up manifest...") 

/*----------------------------------------------------------------------------*/ 

#ifndef _CRT_ASSEMBLY_VERSION 
#include <crtassem.h> 
#endif 

/*----------------------------------------------------------------------------*/ 

#ifdef WIN64 
    #pragma message ("processorArchitecture=amd64") 
    #define MF_PROCESSORARCHITECTURE "amd64" 
#else 
    #pragma message ("processorArchitecture=x86") 
    #define MF_PROCESSORARCHITECTURE "x86" 
#endif 

/*----------------------------------------------------------------------------*/ 

#pragma message ("Microsoft.Windows.Common-Controls=6.0.0.0") 
#pragma comment (linker,"/manifestdependency:\"type='win32' " \ 
        "name='Microsoft.Windows.Common-Controls' " \ 
        "version='6.0.0.0' " \ 
        "processorArchitecture='" MF_PROCESSORARCHITECTURE "' " \ 
        "publicKeyToken='6595b64144ccf1df'\"") 

/*----------------------------------------------------------------------------*/ 

#ifdef _DEBUG 
    #pragma message (__LIBRARIES_ASSEMBLY_NAME_PREFIX ".DebugCRT=" _CRT_ASSEMBLY_VERSION) 
    #pragma comment(linker,"/manifestdependency:\"type='win32' "   \ 
      "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".DebugCRT' "   \ 
      "version='" _CRT_ASSEMBLY_VERSION "' "       \ 
      "processorArchitecture='" MF_PROCESSORARCHITECTURE "' "   \ 
      "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"") 
#else 
    #pragma message (__LIBRARIES_ASSEMBLY_NAME_PREFIX ".CRT=" _CRT_ASSEMBLY_VERSION) 
    #pragma comment(linker,"/manifestdependency:\"type='win32' "   \ 
      "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".CRT' "    \ 
      "version='" _CRT_ASSEMBLY_VERSION "' "       \ 
      "processorArchitecture='" MF_PROCESSORARCHITECTURE "' "   \ 
      "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"") 
#endif 

/*----------------------------------------------------------------------------*/ 

#ifdef _MFC_ASSEMBLY_VERSION 
    #ifdef _DEBUG 
     #pragma message (__LIBRARIES_ASSEMBLY_NAME_PREFIX ".MFC=" _CRT_ASSEMBLY_VERSION) 
     #pragma comment(linker,"/manifestdependency:\"type='win32' "   \ 
       "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".MFC' "    \ 
       "version='" _MFC_ASSEMBLY_VERSION "' "       \ 
       "processorArchitecture='" MF_PROCESSORARCHITECTURE "' "   \ 
       "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"") 
    #else 
     #pragma message (__LIBRARIES_ASSEMBLY_NAME_PREFIX ".MFC=" _CRT_ASSEMBLY_VERSION) 
     #pragma comment(linker,"/manifestdependency:\"type='win32' "   \ 
       "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".MFC' "    \ 
       "version='" _MFC_ASSEMBLY_VERSION "' "       \ 
       "processorArchitecture='" MF_PROCESSORARCHITECTURE "' "   \ 
       "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"") 
    #endif 
#endif /* _MFC_ASSEMBLY_VERSION */ 

/*----------------------------------------------------------------------------*/ 

#endif /* _MSC_VER */ 

/*----------------------------------------------------------------------------*/ 
2

嗯,我遇到一些问题,所以也许我的一些评论会有所帮助。

  1. 清单是一个xml文件。虽然VS可以并且会在编译时为您制作一个,但另一种解决方案是使用VS中包含的资源编译器(rc.exe)生成资源文件(.rc)并将其编译为已编译的资源文件(.res) 。您需要从工具菜单运行VS命令行,这会导致rc在路径中,并正确设置各种环境变量。然后编译你的资源。生成的.res文件可以被其他编译器使用。
  2. 确保您的清单xml文件的大小可以被4整除。如果需要,请在其中间添加空格以实现此目的。尽量避免在openning xml标签之前或关闭xml标签之后有任何字符。我有时会遇到这方面的问题。如果您错误地执行了第2步,则希望得到并排的配置错误。您可以通过在资源编辑器(例如devenv.exe)中打开exe并检查清单资源来检查这是否是您的错误。您也可以通过打开构建的文件来查看正确清单的示例,但请注意dll和exes在资源应该提供的id上略有差异。

您可能想要在Vista上进行测试以确保其正常工作。

1

它们可以重新发布,并且您在msvs目录中有可重新发布的软件包。

使用您选择的运行时进行构建,将相应的软件包添加到您的安装程序中,不用担心 - 它会起作用。所不同的是 - 他们现在在不同的地方安装了(但这也是您的应用程序要查找库的位置)。

否则,MSDN或基本上任何不太老书上的Windows C编程。

+0

呵呵,奇怪,我可以发誓我在MSDN上看到过你不能重新发布这些内容,但现在我找不到链接了,我一定有误读。不过,使用可再发行组件包不是一种选择(我不使用MSI)。 – 2008-09-21 08:26:02

+0

你不能重新分配* debug * CRT。发行版旨在重新分发。 – 2013-08-09 01:16:58

0

感谢您的回答。对于部署本身,我可以看到3个选项,然后:

  • 使用.msi合并指令。
  • 使用可再发行组件包VS和我自己的安装
  • 复制可再发行文件沿着我自己的应用程序之前运行它。但在这种情况下,我如何在文件系统层次结构中引用它(例如,bar/foo1/foo1.dll和bar/foo2/foo2.dll是指bar /中的msvcr90.dll)?我的意思是除了明显的和丑陋的“复制DLL在每一个地方,你有DLL取决于它)目录。
+0

如果您将redist文件(按照我的回复)捆绑到您的应用中,请将它们放在与exe相同的文件夹中。值得庆幸的是,在尝试查找dll时,fusion loader仍然首先查找exe文件夹。 – 2008-10-22 14:24:36

0

您不能使用VC++ 8 SP1/9 CRT作为Vista和Windows Server 2008上的合并模块,如果你有你的服务想在MSI中的“InstallFinalize”操作之前启动或运行您想要运行的程序。

这是因为dll安装在WinSXS的“InstallFinalize”操作中。

但是MSI“ServiceStart”动作在此之前。

所以使用一个引导程序“http://www.davidguyer.us/bmg/publish.htm

或可考虑使用安装程序在安装4.5 chainging。但是,这意味着你需要一个引导程序安装4.5这样似乎有点毫无意义..

3

最简单的事情: 假设默认安装VS2005的,你就会有这样的路径:

C:\Program Files\Microsoft Visual Studio 8\VC\redist\x86\Microsoft.VC80.CRT 

转到,抓住这个redist文件夹中的文件,并将.manifest和msvcr80.dll(至少)放在应用程序的.exe文件夹中。 这些文件存在于您的安装根目录中,它们应该能够使您的exe和所有与它们链接的dll无懈可击地工作,而无需诉诸合并模块,MSI或任何种类的运行时未安装的即时检测。

0

如果您打算部署Microsoft DLLs/.manifest文件并使用Java JNI,那么您需要将它们放在JDK/JRE的bin目录中。

如果您在JBoss中运行应用程序,那么您需要将它们放在JBoss/bin目录中。

你可以把你的JNI DLL放在适合你的应用的地方。