2008-09-21 44 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放在適合你的應用的地方。