Solução de problemas de BadImageFormatException

107

Tenho um serviço do Windows escrito em C # usando o Visual Studio 2010 e direcionado ao .NET Framework 4. completo. Quando executo a partir de uma compilação de depuração, o serviço é executado conforme o esperado. No entanto, quando eu o executo a partir de uma versão Release, recebo uma System.BadImageFormatException (detalhes abaixo). Tenho pesquisado na Internet por uma solução, mas até agora tudo o que encontrei não me ajudou a encontrar uma solução.

O problema existe nos sistemas Windows 7 de 64 bits (dev) e Windows XP SP3 de 32 bits (destino).

Aqui está o que tentei até agora:

  • As configurações de compilação verificadas, como Platform Target, são todas iguais (x86).
  • Usei peverify com a opção / verbose para garantir que os binários do assembly eram válidos.
  • Usa fuslogvw para procurar problemas de carregamento.
  • Use o CheckAsm para procurar arquivos ausentes ou assembiles.

Todas essas verificações não mudaram nada. Incluí o texto completo das informações de exceção abaixo, com alguns dos nomes alterados para proteger os segredos de meus senhores corporativos.

System.BadImageFormatException não foi tratada
  Message = Não foi possível carregar o arquivo ou assembly 'XxxDevices, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null' ou uma de suas dependências. Foi feita uma tentativa de carregar um programa com um formato incorreto.
  Source = XxxDevicesService
  FileName = XxxDevices, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null
  FusionLog = Gerenciador de montagem carregado de: C: \ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ clr.dll
Executando sob o executável c: \ Dev \ TeamE \ bin \ Release \ XxxDevicesService.vshost.exe
--- Segue um registro de erros detalhado. 

=== Informação de estado de pré-ligação ===
LOG: Usuário = XXX
LOG: DisplayName = XxxDevices, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null
 (Totalmente especificado)
LOG: Appbase = file: /// c: / Dev / TeamE / bin / Release /
LOG: PrivatePath inicial = NULL
Chamando assembly: XxxDevicesService, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null.
===
LOG: Este vínculo começa no contexto de carregamento padrão.
LOG: Usando o arquivo de configuração do aplicativo: c: \ TeamE \ bin \ Release \ XxxDevicesService.vshost.exe.Config
LOG: Usando o arquivo de configuração do host: 
LOG: Usando o arquivo de configuração da máquina de C: \ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ config \ machine.config.
LOG: Política que não está sendo aplicada à referência neste momento (associação de assembly privada, personalizada, parcial ou baseada em localização).
LOG: Tentando baixar o novo arquivo URL: /// c: /TeamE/bin/Release/XxxDevices.DLL.
ERR: Falha ao concluir a configuração da montagem (hr = 0x8007000b). Sondagem encerrada.

  StackTrace:
       em XxxDevicesService.Program.Main (String [] args)
       em System.AppDomain._nExecuteAssembly (montagem RuntimeAssembly, String [] args)
       em Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly ()
       em System.Threading.ExecutionContext.Run (ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       em System.Threading.ExecutionContext.Run (ExecutionContext executionContext, ContextCallback callback, Object state)
       em System.Threading.ThreadHelper.ThreadStart ()
  InnerException: 

fonte
você está misturando código nativo / .net?
Keith Nicholas
1
Você está no caminho certo: essa exceção está associada às diferenças de bits x86 / x64. Presumo que este não seja um aplicativo da web, certo? Além disso, que tipo de montagem é XxxDevicesService? É compilado para uma plataforma específica (por exemplo, 32 bits)? Nesse caso, você deve compilar sua plataforma para 32 bits.
Reddog

Respostas:

121

As configurações de compilação verificadas, como Platform Target, são todas iguais (x86).

Não é isso que o log de travamento diz:

Gerenciador de montagem carregado de: C: \ Windows \ Microsoft.NET \ Framework64

Observe o 64 no nome, que é o lar da versão de 64 bits da estrutura. Defina a configuração da plataforma de destino em seu projeto EXE , não seu projeto de biblioteca de classes. O projeto XxxDevicesService EXE determina o número de bits do processo.

Hans Passant
fonte
6
E enquanto você está verificando o projeto EXE, verifique Debug e Release. : /
Chris
44

Depois que parei de bater minha cabeça na mesa pensando na semana inteira que passei tentando resolver esse problema, estou compartilhando o que funcionou para mim. Eu tenho o cliente Oracle Win7 de 64 bits e 32 bits e tenho meu projeto MVC 5 definido para rodar na plataforma x86 por causa da bitness do Oracle. Continuei recebendo os mesmos erros:

Não foi possível carregar o arquivo ou assembly 'Oracle.DataAccess' ou uma de suas dependências. Foi feita uma tentativa de carregar um programa com um formato incorreto.

Recarreguei os pacotes NuGet, usei cópias das DLLs que funcionaram para outras pessoas em aplicativos diferentes, configurei a base de código no assembly dependente para apontar para a pasta bin do meu projeto, tentei CopyLocal como verdadeiro ou falso, tentei de tudo. Finalmente, eu tinha feito o suficiente, queria verificar meu código e, como um novo contratante, não tinha o Subversion configurado. Enquanto procurava uma maneira de conectá-lo ao VS, tropecei na resposta. O que descobri que funcionou foi desmarcar a opção "Usar a versão de 64 bits do IIS Express para sites e projetos" na seção Projetos e soluções => Projetos da Web no menu Ferramentas => Opções.

Joey Morgan
fonte
3
Que salva-vidas !! Obrigado. Para mim, eu realmente tive que verificar isso, já que meu projeto é efetivamente x64. Obrigado novamente!!!
viper
Depois de toda a ajuda que recebi aqui, estou muito feliz por ter podido pagar parte dela adiante!
Joseph Morgan de
3
Para aqueles que usam o IIS local, certifique-se de que o "Ativar aplicativos de 32 bits" do pool de aplicativos (em Configurações avançadas) esteja definido como Verdadeiro .
Eric Eskildsen,
Um adendo ao comentário de @Eskildsen acima sobre "habilitar aplicativos de 32 bits" no pool de aplicativos, mesmo se você não quiser fazer isso no ambiente ao vivo, girar essa chave pode fornecer pistas adicionais sobre se você está enfrentando um 32 -bit / problema de 64 bits ou outra coisa.
um CVn
Estrondo! Foi isso.
itslittlejohn
21

O que descobri que funcionou foi marcar a opção "Usar a versão de 64 bits do IIS Express para sites e projetos" na seção Projetos e soluções => Projetos da Web no menu Ferramentas => Opções.

Lucy Zhang
fonte
você é o salvador. +1
Amit Kumar,
Reinstalei o VS e estava resolvendo esse problema (obrigado - essa solução funcionou). A moral da história para mim é que, se eu sei que não alterei nenhum código para começar, talvez deva olhar primeiro a configuração do VS.
taylorswiftfan
A caixa de seleção @Lucy 'Usar a versão de 64 bits do IIS Express para sites e projetos' está desabilitada
k_kumar
Diga a Lucy
k_kumar
12

Normalmente, isso pode ocorrer quando você alterou a estrutura de destino de .csproj e a reverteu para o estado inicial.

Certifique-se de 1 if supportedRuntime version = "um runtime diferente do destino do projeto cs" na tag de inicialização em app.config.

Certifique-se de 2 Isso também significa verificar outros arquivos gerados automaticamente ou outros na pasta de propriedades para ver se não há mais incompatibilidade de tempo de execução entre esses arquivos e aquele definido no arquivo .csproj.

Isso pode poupar muito tempo antes de você começar a tentar coisas diferentes com as propriedades do projeto para superar o erro.

Purvin
fonte
Me deparei com um problema semelhante e sua resposta foi a solução para a minha. Meu app.config tinha diferentes tempos de execução suportados.
Krisztián Kis
9

Tive o mesmo problema, embora tenha o Windows 7 de 64 bits e estivesse carregando uma DLL de 64 bits b / c nas propriedades do projeto | Compilação Eu marquei "Preferir 32 bits". (Não sei por que isso é definido como padrão). Depois de desmarcar isso, tudo funcionou bem

SN
fonte
1
O mesmo aqui. Isso funcionou. Referenciou um assembly de 64 bits e a configuração de compilação ativa foi definida como Any CPU, mas por causa dessa configuração "preferir 32 bits", presumivelmente, 32 bits foi usado para executar o aplicativo e causou os problemas.
Bernoulli IT
Escolha qualquer CPU em vez de x86 no modo de depuração e funcionou perfeitamente.
Cardi DeMonaco Jr
7

Você também pode obter essa exceção quando seu aplicativo for direcionado ao .NET Framework 4.5 (por exemplo) e você tiver o seguinte app.config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <startup>
    <supportedRuntime version="v2.0.50727" />
    <supportedRuntime version="v4.0" />
  </startup>
</configuration>

Ao tentar iniciar a depuração do aplicativo, você obterá a BadImageFormatException.

Remover a linha que declara a versão v2.0 limpará o erro.

Tive esse problema recentemente quando tentei alterar a plataforma de destino de um projeto antigo do .NET 2.0 para o .NET 4.5.

Cédric V
fonte
6

fundo

Começamos a receber isso hoje, quando mudamos nosso serviço WCF de AnyCPU para x64 em um servidor Windows 2012 R2 executando IIS 6.2.

Primeiro, verificamos o único assembly referenciado 10 vezes, para garantir que não era realmente uma dll x86. Em seguida, verificamos o pool de aplicativos várias vezes para garantir que não estava habilitando aplicativos de 32 bits.

Por capricho, tentei alternar a configuração. Acontece que os pools de aplicativos no IIS estavam sendo padronizados para um valor de Habilitar aplicativos de 32 bits igual a False, mas o IIS o estava ignorando em nosso servidor por algum motivo e sempre executou nosso serviço no modo x86.

Solução

  • Selecione o pool de aplicativos.
  • Escolha Definir padrões de pool de aplicativos ... ou Configurações avançadas ... .
  • Altere Ativar aplicativos de 32 bits para Verdadeiro.
  • Clique OK .
  • Escolha Definir padrões do pool de aplicativos ... ou Configurações avançadas ... novamente.
  • Altere Habilitar aplicativos de 32 bits de volta para Falso.
  • Clique OK .
JoelC
fonte
4

Corrigi esse problema alterando o aplicativo da web para usar um "Pool de aplicativos" diferente.

Cocu_1012
fonte
4

Para quem vier mais tarde ... Nada funcionou para mim. Todas as minhas assembleias foram bem. Eu tinha uma configuração de aplicativo em um dos meus projetos do Visual Studio que não deveria estar lá. Portanto, certifique-se de que o arquivo de configuração do seu aplicativo seja necessário.

Excluí a configuração extra do aplicativo e funcionou.

McSick
fonte
Consertou para mim. Meu App.config estava configurando meu aplicativo .NET 4.5.1 para 2.0 CLR!
Jared Thirsk
4

Versão de destino x64 Servidor de destino Hospedando IIS de 64 bits

Se a compilação do aplicativo tiver como alvo o SO de 64 bits, no servidor de 64 bits que hospeda o IIS, defina a ativação do aplicativo de 32 bits no pool de aplicativos que executa o site / aplicativo da web como falso.

insira a descrição da imagem aqui

VK_217
fonte
2

Determine o pool de aplicativos usado pelo aplicativo e defina a propriedade configurando Habilitar aplicativos de 32 bits como Verdadeiro. Isso pode ser feito por meio de configurações avançadas do pool de aplicativos.

Anand
fonte
2

Ao criar aplicativos para plataformas de 32 ou 64 bits (minha experiência é com o Visual Studio 2010), não conte com o Gerenciador de Configurações para definir a plataforma correta para o executável. Mesmo se o CM tiver x86 selecionado para o aplicativo, verifique as propriedades do projeto (guia Build): ainda pode dizer "Any CPU" lá. E se você executar um executável "Any CPU" em uma plataforma de 64 bits, ele será executado no modo de 64 bits e se recusará a carregar as DLLs que o acompanham, criadas para a plataforma x86.

Jeremy Tinkler
fonte
1

Remova sua dependência de System.Runtime em seu Web.Config, funcionou para mim:

<dependentAssembly>
        <assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" />
</dependentAssembly>
Nicolas
fonte
Para mim foi o System.Net.Http. Obrigado por isso.
Snickbrack
1

Para .NET Core , há um bug do Visual Studio 2017 que pode fazer com que a página Build de propriedades do projeto mostre o destino de plataforma incorreto. Depois de descobrir que o problema é, as soluções alternativas são muito fáceis. Você pode alterar o alvo para algum outro valor e depois alterá-lo de volta.

Como alternativa, você pode adicionar um identificador de tempo de execução ao .csproj. Se você precisa que seu .exe seja executado como x86 para poder carregar uma DLL nativa x86, adicione este elemento em PropertyGroup:

<RuntimeIdentifier>win-x86</RuntimeIdentifier>

Um bom lugar para colocá-lo é logo após o elemento TargetFrameworkou TargetFrameworks.

Edward Brey
fonte
1

Estou surpreso que ninguém mais tenha mencionado isso, então estou compartilhando caso nenhuma das opções acima ajude (meu caso).

O que estava acontecendo era que uma instância do VBCSCompiler.exe estava de alguma forma travada e de fato não estava liberando os identificadores de arquivo para permitir que novas instâncias gravassem corretamente os novos arquivos e estava causando o problema. Isso se tornou aparente quando tentei excluir a pasta "bin" e ele estava reclamando que outro processo estava usando arquivos lá.

VS fechado, gerenciador de tarefas aberto, olhou e encerrou todas as instâncias do VBCSCompiler e excluiu a pasta "bin" para voltar para onde eu estava.

Referência: https://developercommunity.visualstudio.com/content/problem/117596/vbcscompilerexe-process-stays-runing-after-exiting.html

George
fonte
Minha solução também foi deletar todos os diretórios bin e debug.
gabnaim de
0

Para quem vier mais tarde ...
Para a solução Desktop, tive uma BadImageFormatExceptionexceção.
Todas as opções de construção do projeto estavam boas (todas x86). Mas o projeto de solução StartUp foi alterado para algum outro projeto (projeto de biblioteca de classes).

Alterar o projeto de inicialização para o original (projeto de aplicativo .exe) foi uma solução no meu caso

Fabio
fonte
0

Quando enfrentei esse problema, o seguinte resolveu para mim:

Eu estava chamando uma dll OpenCV de dentro de outro exe, minha dll não continha as dlls opencv já necessárias, como highgui, features2d e etc disponíveis na pasta do meu arquivo exe. Copiei tudo isso para o diretório do meu projeto exe e de repente funcionou.

Ali Nejad
fonte
0

Este erro "Não foi possível carregar o arquivo ou assembly 'exemplo' ou uma de suas dependências. Foi feita uma tentativa de carregar um programa com um formato incorreto" normalmente é causado por uma configuração incorreta do pool de aplicativos.

  1. Certifique-se de que o AppPool em que seu site está sendo executado possui "Ativar aplicativos de 32 bits" definido como False.
  2. Certifique-se de usar a versão correta para sua plataforma.
  3. Se você estiver recebendo este erro em um site, certifique-se de que seu pool de aplicativos esteja configurado para ser executado no modo correto (sites 3.0 devem ser executados no modo de 64 bits)
  4. Você também deve se certificar de que a referência a essa montagem no visual studio está apontando para o arquivo correto na pasta de pacotes.
  5. Certifique-se de ter a versão correta da dll instalada nos sites GAC para 2.0.
  6. Isso também pode ser causado por WSODLibs sendo promovidos com o projeto da web.
Ben Petersen
fonte