Partilhar via


Resolução de problemas de aplicações C/C++ isoladas e assemblies justapostas

O carregamento de um aplicativo C/C++ pode falhar se as bibliotecas dependentes não puderem ser encontradas. Este artigo descreve algumas razões comuns pelas quais um aplicativo C/C++ falha ao carregar e sugere etapas para resolver os problemas.

Se uma aplicação falhar ao carregar porque possui um manifesto que especifica uma dependência de um assembly lado a lado, e o assembly não estiver instalado como um assembly privado na mesma pasta do executável nem no cache de assembly nativo na pasta \WinSxS\ %WINDIR%, uma das seguintes mensagens de erro pode ser exibida, dependendo da versão do Windows em que tenta executar a aplicação.

  • O aplicativo falhou ao inicializar corretamente (0xc0000135).

  • Este aplicativo falhou ao iniciar porque a configuração do aplicativo está incorreta. Reinstalar o aplicativo pode corrigir esse problema.

  • O sistema não pode executar o programa especificado.

Se o seu aplicativo não tiver manifesto e depender de uma DLL que o Windows não consegue encontrar nos locais de pesquisa típicos, uma mensagem de erro semelhante a esta pode ser exibida:

  • Este aplicativo falhou ao iniciar porque uma DLL necessária não foi encontrada. Reinstalar o aplicativo pode corrigir esse problema.

Se seu aplicativo for implantado em um computador que não tenha o Visual Studio e falhar com mensagens de erro semelhantes às anteriores, verifique o seguinte:

  1. Siga as etapas descritas em Noções básicas sobre as dependências de um aplicativo Microsoft C++. O verificador de dependências pode mostrar a maioria das dependências de um aplicativo ou DLL. Se você observar que algumas DLLs estão faltando, instale-as no computador no qual você está tentando executar seu aplicativo.

  2. O carregador do sistema operacional usa o manifesto do aplicativo para carregar assemblies dos quais o aplicativo depende. O manifesto pode ser incorporado no binário como um recurso ou instalado como um arquivo separado na pasta do aplicativo. Para verificar se o manifesto está incorporado no binário, abra o binário no Visual Studio e procure RT_MANIFEST em sua lista de recursos. Se não conseguir encontrar um manifesto incorporado, procure na pasta da aplicação um ficheiro com o nome de algo como <binary_name>.<extensão.manifest>.

  3. Se seu aplicativo depende de assemblies lado a lado e um manifesto não está presente, você precisa garantir que o vinculador gere um manifesto para seu projeto. Marque a opção do vinculador Gerar manifesto na caixa de diálogo Propriedades do projeto para o projeto.

  4. Se o manifesto estiver incorporado no binário, verifique se a ID do RT_MANIFEST está correta para esse tipo de binário. Para mais informações sobre qual ID de recurso utilizar, consulte Utilizar assemblies lado a lado como recurso (Windows). Se o manifesto estiver em um arquivo separado, abra-o em um editor XML ou editor de texto. Para obter mais informações sobre manifestos e regras de implantação, consulte Manifestos.

    Observação

    Se um manifesto incorporado e um arquivo de manifesto separado estiverem presentes, o carregador do sistema operacional usará o manifesto incorporado e ignorará o arquivo separado. No entanto, no Windows XP, o oposto é verdadeiro: o arquivo de manifesto separado é usado e o manifesto incorporado é ignorado.

  5. Recomendamos que você incorpore um manifesto em cada DLL porque os manifestos externos são ignorados quando uma DLL é carregada por meio de uma LoadLibrary chamada. Para obter mais informações, consulte Manifestos de assemblagem.

  6. Verifique se todos os assemblies enumerados no manifesto estão instalados corretamente no computador. Cada assembly é especificado no manifesto por seu nome, número de versão e arquitetura do processador. Se a sua aplicação depender de assemblies lado-a-lado, verifique se esses assemblies estão instalados corretamente no computador para que o carregador do sistema possa localizá-los, conforme descrito em Sequência de Pesquisa de Assemblies. Lembre-se de que 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 usando o Microsoft C++ Build Tools. O manifesto do aplicativo é incorporado em appl.exe como o recurso binário RT_MANIFEST, que tem uma ID igual a 1, ou é armazenado como o arquivo separado appl.exe.manifest. O conteúdo deste manifesto assemelha-se a isto:

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Fabrikam.SxS.Library" version="2.0.20121.0" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3e"></assemblyIdentity>
    </dependentAssembly>
  </dependency>
</assembly>

Para o carregador do sistema operacional, esse manifesto diz que appl.exe depende de um assembly chamado Fabrikam.SxS.Library, versão 2.0.20121.0, criado para uma arquitetura de processador x86 de 32 bits. A assemblagem lado a lado dependente pode ser instalada como uma assemblagem partilhada ou como uma assemblagem privada.

O manifesto de assemblagem de uma assemblagem partilhada é instalado na pasta %WINDIR%\WinSxS\Manifests\. Ele identifica o assembly e lista seu conteúdo, ou seja, as DLLs que fazem parte do assembly:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
   <noInheritable/>
   <assemblyIdentity type="win32" name="Fabrikam.SxS.Library" version="2.0.20121.0" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3e"/>
   <file name="Fabrikam.Main.dll" hash="3ca5156e8212449db6c622c3d10f37d9adb1ab12" hashalg="SHA1"/>
   <file name="Fabrikam.Helper.dll" hash="92cf8a9bb066aea821d324ca4695c69e55b2d1c2" hashalg="SHA1"/>
</assembly>

Os conjuntos lado a lado também podem usar ficheiros de configuração do editor—também conhecidos como ficheiros de política—para redirecionar globalmente aplicações e conjuntos para usar uma versão de um conjunto lado a lado em vez de outra versão do mesmo conjunto. Você pode verificar as políticas para um assembly compartilhado na pasta %WINDIR%\WinSxS\Policies\. Aqui está um arquivo de política de exemplo:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

   <assemblyIdentity type="win32-policy" name="policy.2.0.Fabrikam.SxS.Library" version="2.0.20121.0" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3e"/>
   <dependency>
      <dependentAssembly>
         <assemblyIdentity type="win32" name="Fabrikam.SxS.Library" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3e"/>
         <bindingRedirect oldVersion="2.0.10000.0-2.0.20120.99" newVersion="2.0.20121.0"/>
      </dependentAssembly>
   </dependency>
</assembly>

Este arquivo de política especifica que qualquer aplicativo ou assembly que solicite a versão 2.0.10000.0 desse assembly deve, em vez disso, usar a versão 2.0.20121.0, que é a versão atual instalada no sistema. Se uma versão do assembly mencionada no manifesto da aplicação estiver especificada no ficheiro de política, o carregador procurará uma versão deste assembly indicada no manifesto, na pasta \WinSxS\ do %WINDIR%e, caso essa versão não esteja instalada, o carregamento falhará. E se a versão de assembly 2.0.20121.0 não estiver instalada, o carregamento falhará para aplicativos que solicitam a versão de assembly 2.0.10000.0.

No entanto, o assembly pode também ser instalado como um assembly lado a lado privado na pasta da aplicação instalada. Se o sistema operacional não conseguir localizar o assembly como um assembly compartilhado, ele o procurará como um assembly privado, na seguinte ordem:

  1. Verifique a pasta do aplicativo para um arquivo de manifesto que tem o nome <assemblyName.manifest>. Neste exemplo, o carregador tenta localizar Fabrikam.SxS.Library.manifest na pasta que contém appl.exe. Se encontrar o manifesto, o carregador carregará o assembly da pasta do aplicativo. Se o assembly não for encontrado, o carregamento falhará.

  2. Tente abrir o \<assemblyName>\ folder in the folder that contains appl.exee, se \<assemblyName>\ existir, tente carregar um arquivo de manifesto com o nome <assemblyName.manifest> dessa pasta. Se o manifesto for encontrado, o carregador carregará o assembly da pasta \<assemblyName>\. Se o assembly não for encontrado, o carregamento falhará.

Para obter mais informações sobre como o carregador procura assemblies dependentes, consulte Assembly Searching Sequence. Se o carregador não conseguir encontrar uma assembly dependente como uma assembly privada, o carregamento falhará e a mensagem "O sistema não pode executar o programa especificado" será exibida. Para resolver esse erro, certifique-se de que os assemblies dependentes — e as DLLs que fazem parte deles — estejam instalados no computador como assemblies privados ou compartilhados.

Ver também

Conceitos de aplicações isoladas e montagens lado a lado
Criando aplicativos isolados C/C++ e montagens lado a lado