在 Windows 上构建和部署 dll:SxS、清单和所有爵士乐

发布于 2024-07-04 22:07:21 字数 459 浏览 10 评论 0原文

从 VS 2005 开始,我发现不可能简单地针对 MS 运行时构建 dll 并将它们部署在一起 ( http://www.ddj.com/windows/184406482)。 我对manifest、SxS和co深感困惑:MSDN文档真的很差,有循环引用; 特别是因为我是一个 Unix 爱好者,所以我发现所有这些都没有提供任何信息。 我的核心问题是将 dll 链接到 msvc9 或 msvc8:由于这些运行时不可重新分发,链接和部署此类 dll 的步骤是什么? 特别是,清单是如何生成的(我不需要 mt.exe,我想要可以跨编译器移植的东西),它们是如何嵌入、使用的? 并排组装是什么意思?

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

谢谢所有回答的人,这真的很有帮助,

Since VS 2005, I see that it is not possible to simply build a dll against MS runtime and deploy them together (http://www.ddj.com/windows/184406482). I am deeply confused by manifest, SxS and co: MSDN documentation is really poor, with circular references; specially since I am more a Unix guy, I find all those uninformative. My core problem is linking a dll against msvc9 or msvc8: since those runtime are not redistributable, what are the steps to link and deploy such a dll ? In particular, how are the manifest generated (I don't want mt.exe, I want something which is portable across compilers), how are they embedded, used ? What does Side by side assembly mean ?

Basically, where can I find any kind of specification instead of MS jargon ?

Thank you to everyone who answered, this was really helpful,

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

寒江雪… 2024-07-11 22:07:21

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

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

您可以将 JNI DLL 放在适合您的应用程序的位置。

If you intend to deploy the Microsoft DLLs/.manifest files and are using Java JNI then you will need to put them in the bin directory of your JDK/JRE.

If you are running the app in JBoss, then you will need to put them in the JBoss/bin directory.

You can put your JNI DLL where appropriate for your application.

绅士风度i 2024-07-11 22:07:21

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

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

但 MSI“ServiceStart”操作在此之前发生。

因此,请使用引导程序“http://www.davidguyer.us/bmg/publish.htm< /a>"

或者研究在安装程序 4.5 中使用安装程序链接。 但这意味着你需要一个引导程序来安装 4.5,所以这似乎有点毫无意义。

You can't use the VC++8 SP1/9 CRT as a merge module on Vista and windows Server 2008 if you have services you want to start or programs that you want to run before the "InstallFinalize" action in the MSI.

This is because the dlls are installed in WinSXS in the "InstallFinalize" action.

But the MSI "ServiceStart" action comes before this.

So use either a bootstrapper "http://www.davidguyer.us/bmg/publish.htm"

Or look into using the installer chainging in the installer 4.5. But this means you need a bootstrapper to install 4.5 so it seems a bit pointless..

魂ガ小子 2024-07-11 22:07:21

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

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

Thanks for the answer. For deployment per se, I can see 3 options, then:

  • Using .msi merge directive.
  • Using the redistributable VS package and run it before my own installer
  • Copying the redistributable files along my own application. But in this case, how do I refer to it in a filesystem hierarchy (say bar/foo1/foo1.dll and bar/foo2/foo2.dll refer to msvcr90.dll in bar/) ? I mean besides the obvious and ugly "copy the dll in every directory where you have dll which depends on it).
我的痛♀有谁懂 2024-07-11 22:07:21

它们是可再发行的,并且您在 msvs 目录中有可再发行的软件包。

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

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

They are redistributable and you have redistributable packages inside msvs directory.

Build with runtime of your choice, add corresponding package to your installer and don't bother - it will work. The difference is - they are installed in a different place now (but that is also where your app is going to look for libraries).

Otherwise, MSDN or basically any not-too-old book on windows c++ programming.

濫情▎り 2024-07-11 22:07:21

最简单的事情就是:
假设默认安装 VS2005,您将拥有如下路径:

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

转到此 redist 文件夹中获取文件,然后将 .manifest 和 msvcr80.dll (至少)放入您的应用程序 .exe 文件夹中。
这些文件存在于安装的根目录中,应该使您的 exe 和所有链接到它们的 dll 能够完美地工作,而无需求助于合并模块、MSI 或任何类型的运行时未安装的即时检测。

The simplest thing to do:
Assuming a default install of VS2005, you will have a path like:

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

Go, grab the files in this redist folder, and place the .manifest AND the msvcr80.dll (At least) in your applications .exe folder.
These files, present in the root of your installation, should enable your exe and all dlls linked against them, to work flawlessly without resorting to merge modules, MSIs or indeed any kind of just-in-time detection that the runtime is not installed.

眼角的笑意。 2024-07-11 22:07:21

以下是博客条目解释了 SxS crt 决策背后的合理性VC++。 它包括解释静态链接 crt 有多么糟糕,以及为什么不应该这样做。

这是有关如何静态链接 crt 的文档。

Here is the blog entry explaining the rational behind the SxS crt decision for VC++. It includes explaining how bad it is to statically link the crt, and why you shouldn't do that.

Here is the documentation on how to statically link the crt.

一瞬间的火花 2024-07-11 22:07:21

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

  1. 清单是一个 xml 文件。 虽然 VS 可以并且会在您编译时为您生成一个,但另一种解决方案是生成一个资源文件 (.rc) 并使用 VS 附带的资源编译器 (rc.exe) 将其编译为已编译的资源文件 (.res) 。 您需要从工具菜单运行 VS 命令行,这将使 rc 位于路径中,并正确设置各种环境变量。 然后编译您的资源。 生成的 .res 文件可供其他编译器使用。
  2. 确保清单 xml 文件的大小可以被 4 整除。如果需要,可以在其中添加空格以实现此目的。 尽量避免在开始 xml 标记之前或结束 xml 标记之后出现任何字符。 我有时也遇到过这样的问题。 如果步骤 2 的操作不正确,预计会出现并列配置错误。 您可以通过在资源编辑器(例如 devenv.exe)中打开 exe 并检查清单资源来检查这是否是您的错误。 您还可以通过打开构建的文件来查看正确清单的示例,但请注意,dll 和 exe 在应指定资源的 id 方面存在微小差异。

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

Well, I've encountered some of these issues, so perhaps some of my comments will be helpful.

  1. The manifest is an xml file. While VS can and will make one for you when you compile, the other solution is to produce a resource file (.rc) and compile it into a compiled resource file (.res) using the resource compiler (rc.exe) included with VS. You'll want to run the VS commandline from the tools menu, which will cause rc to be in the path, as well as setting various environmental variables correctly. Then compile your resource. The resulting .res file can be used by other compilers.
  2. Make sure your manifest xml file's size is divisible by 4. Add whitespace in the middle of it to achieve this if needed. Try to avoid having any characters before the openning xml tag or after the closing xml tag. I've sometimes had issues with this. If you do step 2 incorrectly, expect to get side by side configuration errors. You can check if that is your mistake by openning the exe in a resource editor (e.g. devenv.exe) and examining the manifest resource. You can also see an example of a correct manifest by just opening a built file, though note that dlls and exes have tiny differences in what id the resource should be given.

You'll probably want to test on Vista to make sure this is working properly.

人疚 2024-07-11 22:07:21

我们在所有应用程序中使用一个简单的包含文件 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 */

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

We use a simple include file in all our applications & DLL's, vcmanifest.h, then set all projects to embedded the manifest file.

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 */

/*----------------------------------------------------------------------------*/
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文