Partilhar via


A solução de problemas C/C++ aplicativos isolados e montagens lado a lado

Carregar um aplicativo C/C++ pode falhar se dependentes Visual C++ bibliotecas não foi encontradas. Uma lista de possíveis erros de tempo de execução pode ser encontrada em Redistribuindo arquivos do Visual C++. Nesta seção são descritas as razões mais comuns para um aplicativo C/C++ impossibilitará o carregamento, com etapas propostas para resolver os problemas.

Se um aplicativo é implantado em um computador sem o Visual C++ instalado e ele falha com mensagens de erro semelhantes àquelas listadas na Redistribuindo arquivos do Visual C++, várias coisas têm que ser verificados para entender o motivo do erro.

  1. Siga os passos descritos em Noções básicas sobre dependências de um aplicativo Visual C++. O dependency walker pode mostrar a maioria das dependências para qualquer aplicativo específico ou uma DLL. Se você vir que algumas DLLs estão faltando, instale as DLLs no computador no qual você está tentando executar o aplicativo.

  2. Um manifesto é usado pelo carregador do sistema operacional para carregar assemblies depende do seu aplicativo. Ele pode ser incorporado dentro do binário como um recurso, ou salva como um arquivo externo na pasta de local do aplicativo. Para verificar se o manifesto é incorporado dentro do binário, abra o binário no Visual Studio e procurar os recursos do binário. Você deve ser capaz de encontrar um recurso chamado RT_MANIFEST. Se você não encontrar um manifesto incorporado dentro do binário, procurar um arquivo externo denominado algo como <binary_name>. <extension> manifest.

  3. Se um manifesto não estiver presente, você precisará garantir que o vinculador gera um manifesto para o seu projeto. Você precisa verificar a opção de vinculador gerar manifesto na Propriedades do projeto caixa de diálogo para este projeto.

    ObservaçãoObservação

    Criando Visual C++ projetos sem geração de manifesto não é suportada. Qualquer programa do C/C++ criado em Visual C++ tem que incluir um manifesto descrevendo suas dependências em Visual C++ bibliotecas.

  4. Se o manifesto é incorporado dentro do binário, certifique-se de que o ID de RT_MANIFEST é correto para esse tipo de binário. Para aplicativos, o ID deve ser igual a 1, para a maioria das ID de DLLs deve ser igual a 2. Se o manifesto em um arquivo externo, abra-o em um editor XML ou um editor de texto. Para obter mais informações sobre manifestos e regras para implantação, consulte manifestos.

    ObservaçãoObservação

    No Windows XP, se um manifesto externo está presente na pasta de local do aplicativo, o carregador do sistema operacional usa esse manifesto em vez de um manifesto incorporado dentro de binário. Em Windows Server 2003 e versões posteriores do Windows, o oposto é verdadeiro — o manifesto externo será ignorado e o manifesto incorporado é usado quando presente.

  5. É recomendável que todas as DLLs têm um manifesto incorporado dentro de binário. Manifestos externos são ignorados quando uma DLL é carregada, embora um LoadLibrary chamada. Para obter mais informações, consulte Assembly manifestos.

  6. Verifique se todos os assemblies enumerados no manifesto corretamente estão instalados no computador. Cada assembly especificado no manifesto pelo seu nome, arquitetura de processador e o número de versão. Se seu aplicativo depende de conjuntos de módulos lado a lado, verifique se esses assemblies estão instalados no computador corretamente, para que eles podem ser encontrados pelo carregador do sistema operacional usando as etapas especificadas em A seqüência de pesquisa de Assembly. Lembre-se de que os assemblies de 64 bits não podem ser carregados em processos de 32 bits e não podem ser executados em sistemas operacionais de 32 bits.

Exemplo

Suponha que temos um aplicativo, appl.exe, que é criado com Visual C++. Este aplicativo tem seu manifesto incorporado dentro de appl.exe como um recurso binário RT_MANIFEST com appl.exe.manifest igual a 1 ou armazenado como um arquivo externo, de identificação. O conteúdo do manifesto pode ser algo assim:

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.xxxxx.y" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
    </dependentAssembly>
  </dependency>
</assembly>

Para o sistema operacional o carregador que esse manifesto diz que appl.exe depende de um assembly chamado Microsoft.VC90.CRT, versão 9.0.xxxxx.y e desenvolvido para a arquitetura de processador x86 de 32 bits.

O assembly dependente do lado a lado pode ser instalado como um assembly compartilhado ou como um assembly particular. Por exemplo, o Visual Studio de 2008 instala o assembly de CRT como um assembly lado a lado compartilhado, que pode ser encontrado em %WINDIR%\WinSxS\x86_Microsoft.VC90.CRT_ o diretório<version> quando executando o Windows XP ou o diretório %WINDIR%\winsxs\x86_microsoft.vc90.crt_<version> quando executando o Windows Vista.

O assembly manifest para um CRT de C++ Visual compartilhada assembly também é instalado em %WINDIR%\WinSxS\Manifests\x86_microsoft.vc90.crt_<version>. manifest quando executando o Windows XP ou no %WINDIR%\winsxs\Manifests\x86_microsoft.vc90.crt_<version>. manifest quando executando o Windows Vista e identifica este assembly e lista seu conteúdo (DLLs que fazem parte deste assembly):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Copyright © 1981-2001 Microsoft Corporation -->
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
   <noInheritable/>
   <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.xxxxx.yy" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"/>
   <file name="msvcr90.dll" hash="3ca5156e8212449db6c622c3d10f37d9adb12c66" hashalg="SHA1"/>
   <file name="msvcp90.dll" hash="92cf8a9bb066aea821d324ca4695c69e55b27cff" hashalg="SHA1"/>
   <file name="msvcm90.dll" hash="7daa93e1195940502491c987ff372190bf199395" hashalg="SHA1"/>
</assembly>

Os assemblies lado a lado também podem usar os arquivos de configuração do publisher, também chamados arquivos de diretiva para redirecionar globalmente os aplicativos e assemblies usando uma versão de um assembly lado a lado para outra versão do mesmo assembly. Você pode verificar as diretivas para o assembly compartilhado do CRT do Visual C++ em %WINDIR%\WinSxS\Policies\x86_policy.9.0.Microsoft.VC90.CRT_<version>.policy ao executar o Windows XP ou no %WINDIR%\winsxs\Manifests\x86_policy.9.0.microsoft.vc90.crt_<version>. manifest quando executando o Windows Vista, que contém algo assim:

</assembly>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Copyright © 1981-2001 Microsoft Corporation -->
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

   <assemblyIdentity type="win32-policy" name="policy.9.0.Microsoft.VC90.CRT" version="9.0.xxxxx.yy" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"/>
   <dependency>
      <dependentAssembly>
         <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"/>
         <bindingRedirect oldVersion="9.0.aaaaa.bbb-9.0.ccccc.d" newVersion="9.0.xxxxx.yy"/>
      </dependentAssembly>
   </dependency>
</assembly>

A diretiva acima Especifica que qualquer aplicativo ou assembly pede a 9.0.aaaaa.bbb de versão deste assembly em vez disso, deve usar a versão 9.0.xxxxx.yy deste assembly, que é a versão atual instalada no sistema. Se uma versão do assembly mencionado no manifesto do aplicativo é especificada no arquivo de diretiva, o carregador de procura de uma versão deste assembly especificado no manifesto na pasta WinSxS e se esta versão não estiver instalada, o carregamento falhar. E se um 9.0.xxxxx.yy de versão do assembly não estiver instalado, bem, o carregamento falhar para aplicativos que pedem a 9.0.aaaaa.bbb de versão do assembly.

No entanto, o assembly de CRT também pode ser instalado como um assembly privado de lado a lado na pasta de local do aplicativo. Se o sistema operacional não conseguir localizar a CRT ou qualquer outro conjunto como um assembly compartilhado, ele começa procurando o conjunto como um assembly particular. Ele procura os conjuntos privados na seguinte ordem:

  1. Verifique a pasta local do aplicativo para um arquivo de manifesto. manifest de nome <assemblyName>. Neste exemplo, o carregador tenta encontrar o Microsoft.VC90.CRT.manifest na mesma pasta do appl.exe. Se o manifesto for encontrado, o carregador de carrega a DLL do CRT da pasta de aplicativo. Se a DLL do CRT não for encontrada, o carregamento falhar.

  2. Tente abrir a pasta <assemblyName> na pasta do appl.exe local e se ele existe, carrega o arquivo de manifesto <assemblyName> manifest desta pasta. Se o manifesto for encontrado, o carregador carrega a DLL de CRT do <assemblyName> pasta. Se a DLL do CRT não for encontrada, o carregamento falhar.

Consulte A seqüência de pesquisa de Assembly para obter uma descrição mais detalhada de como o carregador de procura de assemblies dependentes. Se o loader falhar para localizar um assembly dependente como um assembly particular, o carregamento falhar e "O sistema não pode executar o programa especificado" é exibida. Para resolver esse erro, assemblies dependentes e DLLs que são parte deles devem ser instaladas no computador como assemblies particulares ou compartilhados.

Consulte também

Conceitos

Conceitos de aplicativos isolados e montagens lado a lado

Outros recursos

A criação de C/C++ aplicativos isolados e montagens lado a lado