Pergunta

Desde VS 2005, eu vejo que não é possível simplesmente construir uma dll contra MS tempo de execução e implantá-los juntos ( http://www.ddj.com/windows/184406482 ). Estou profundamente confuso com manifesto, SxS e co: documentação MSDN é realmente pobre, com referências circulares; especialmente desde que eu sou mais um cara Unix, acho que todos aqueles uninformative. Meu problema central está ligando uma dll contra msvc9 ou msvc8: desde os tempo de execução não são redistribuíveis, quais são os passos para a ligação e implantar tal dll? Em particular, como são o manifesto gerado (Eu não quero Mt.exe, eu quero algo que é portável entre compiladores), como eles são incorporados, usado? O que faz Lado a lado montagem média?

Basicamente, onde posso encontrar qualquer tipo de especificação, em vez de MS jargão?

Obrigado a todos que responderam, este foi realmente útil,

Foi útil?

Solução

Nós usamos um simples arquivo de inclusão em todas as nossas aplicações e DLL, vcmanifest.h, em seguida, defina todos os projetos para incorporado o arquivo de manifesto.

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

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

Outras dicas

A coisa mais simples a fazer: Assumindo uma instalação padrão do VS2005, você terá um caminho como:

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

Vá, pegue os arquivos desta pasta redist, e coloque o .manifest e msvcr80.dll (Pelo menos) em sua pasta de aplicativos .exe. Esses arquivos, presente na raiz da sua instalação, deve permitir que a sua exe e todas as DLLs ligados contra eles, para funcionar perfeitamente, sem recorrer a módulos de mesclagem, MSIs ou mesmo qualquer tipo de detecção de just-in-time que o tempo de execução não está instalado.

Aqui é a entrada do blog explicar o racional por trás dos SxS decisão CRT para VC ++ . Ele inclui explicando como é ruim para estaticamente vincular a CRT, e por que você não deveria fazer isso.

Aqui está a documentação sobre como vincular estaticamente a crt .

Bem, eu encontrei algumas destas questões, então talvez alguns dos meus comentários será útil.

  1. O manifesto é um arquivo xml. Enquanto VS pode e vai fazer um para você quando você compilar, a outra solução é produzir um arquivo de recurso (.rc) e compilá-lo em um arquivo de recurso compilado (res) usando o compilador de recursos (rc.exe) incluídos com VS . Você vai querer executar o comando VS a partir do menu Ferramentas, o que fará com rc para estar no caminho, bem como a definição de diversas variáveis ??ambientais corretamente. Em seguida, compilar o seu recurso. O arquivo res resultante pode ser utilizado por outros compiladores.
  2. Certifique-se o tamanho do seu arquivo xml manifesto é divisível por 4. Adicionar espaços em branco no meio dela para alcançar este objectivo, se necessário. Tente evitar ter quaisquer caracteres antes da tag openning xml ou depois da tag de fechamento xml. Eu tive algumas vezes problemas com isso. Se você fizer o passo 2 incorretamente, espera obter lado a erros de configuração colaterais. Você pode verificar se esse é o seu erro, abrindo o exe em um editor de recursos (por exemplo devenv.exe) e examinar o recurso de manifesto. Você também pode ver um exemplo de um manifesto correta apenas abrindo um arquivo construído, embora note que DLLs e exes têm pequenas diferenças no que id deve ser dado o recurso.

Você provavelmente vai querer teste no Vista para garantir que este está a funcionar correctamente.

Eles são redistribuíveis e você tem pacotes redistribuíveis dentro do diretório MSVS.

Construir com tempo de execução de sua escolha, adicione pacote correspondente ao seu instalador e não se preocupar - ele vai trabalhar. A diferença é -. Eles são instalar em um lugar diferente agora (mas que é também onde a sua aplicação vai olhar para bibliotecas)

Caso contrário, MSDN ou um livro basicamente qualquer não muito velho no Windows programação C ++.

Obrigado pela resposta. Para implantação per se, eu posso ver 3 opções, então:

  • Usando directiva merge .msi.
  • Usando o pacote VS redistributable e executá-lo antes do meu próprio instalador
  • Copiar o redistributable arquivos ao longo de minha própria aplicação. Mas neste caso, como faço para se referir a ele em uma hierarquia de sistema de arquivos (digamos bar / foo1 / foo1.dll e bar / foo2 / foo2.dll consulte MSVCR90.DLL em bar /)? Quero dizer além do óbvio e feio "copiar a dll em cada diretório onde você tem dll que depende dele).

Você não pode usar o VC ++ 8 SP1 / 9 CRT como um módulo de mesclagem no Vista e Windows Server 2008, se você tem serviços que deseja iniciar ou programas que você deseja executar antes da ação "InstallFinalize" no MSI.

Isso ocorre porque as DLLs são instalados em winsxs na ação "InstallFinalize".

Mas a ação MSI "ServiceStart" vem antes disso.

Assim, o uso ou um bootstrapper " http://www.davidguyer.us/bmg/publish htm "

Ou olhar em usar o instalador chainging no instalador 4.5. Mas isso significa que você precisa de um bootstrapper para instalar 4,5 por isso parece um inútil pouco ..

Se você pretende implantar os .manifest arquivos / Microsoft DLLs e estão usando Java JNI então você precisa colocá-los no diretório bin do seu JDK / JRE.

Se você estiver executando o aplicativo no JBoss, então você terá que colocá-los no diretório do JBoss / bin.

Você pode colocar seu JNI DLL sempre que adequado para a sua aplicação.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top