2012-02-08 4 views
19

Mi sembra di aver colpito uno scenario in cui quando eseguo mstest su un assembly AnyCPU che fa riferimento a un assembly x64, ottengo un valore BadImageFormatException.BadImageFormatException quando l'assembly di test AnyCPU implementa l'interfaccia dall'assembly di produzione x64

Il problema si verifica quando si implementa un'interfaccia in x64Production.dll (anche se non utilizzato) dal gruppo di prova AnyCPUTestingx64Production.dll:

Unable to load the test container 'D:\AnyCPUTestingx64Production.dll' 
or one of its dependencies. error details: 
System.BadImageFormatException: 
    Could not load file or assembly 'x64Production, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. An attempt was made to load a program with an incorrect format. 
  • mstest è in esecuzione su Windows 7 a 64 bit
  • l'apparecchio di prova è costruito come AnyCPU per farlo funzionare in 64 bit su un host 64 bit (come illustrato here)
  • file testsettings specifica < Esecuzione hostProcessPlatform = "MSIL"/>
  • PEverify e corflags rivelano nulla interessante
  • questo è facilmente riproducibile in una soluzione giocattolo, cioè dove
    • x64Production
      • riferimenti altri assiemi
      • include solo un'interfaccia pubblica vuoto IExampleInterface
      • ha <PlatformTarget> impostato su x64
    • AnyCPUTestingx64Production
      • riferimenti solo x64Production.dll (vale a dire questo problema è presente anche senza un riferimento a Microsoft.VisualStudio.QualityTools.UnitTestFramework)
      • include solo un'implementazione vuota x64Production.IExampleInterface
      • ha <PlatformTarget> insieme a x64
  • nunit può caricare ed eseguire il test assembly (dopo aver convertito tutti gli attributi di test)
    • ma non è una buona soluzione a breve termine per il problema più grande (che coinvolge un numero enorme di file di progetto)
  • lo stesso problema si pone se i progetti obiettivo di 3,5 o 4,0
  • gli stessi problemi si pone se il VS2008 o VS2010 compilatore C# è usato
  • lo stesso problema si pone se mstest da VS2010 o Test Agents è utilizzato
  • è più che non riesce durante il caricamento AnyCPUTestingx64Production - cioè questo non è un problema con il tentativo di caricare l'assembly nel QTAgent sbagliato (nulla viene visualizzato in Process Monitor e rinominare QTAgent32.exe non ha alcun effetto) :
*** Assembly Binder Log Entry (09/02/2012 @ 09:44:26) *** 

    The operation failed. 
    Bind result: hr = 0x8007000b. An attempt was made to load a program with an incorrect format. 

    Assembly manager loaded from: C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll 
    Running under executable C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\MSTest.exe 
    --- A detailed error log follows. 

    === Pre-bind state information === 
    LOG: User = David 
    LOG: DisplayName = x64Production, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 
    (Fully-specified) 
    LOG: Appbase = file:///D:/ 
    LOG: Initial PrivatePath = NULL 
    LOG: Dynamic Base = NULL 
    LOG: Cache Base = NULL 
    LOG: AppName = MSTest.exe 
    Calling assembly : AnyCPUTestingx64Production, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null. 
    === 
    LOG: This bind starts in default load context. 
    LOG: Using application configuration file: C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\MSTest.exe.Config 
    LOG: Using host configuration file: 
    LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config. 
    LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind). 
    LOG: Attempting download of new URL file:///D:/x64Production.DLL. 
    LOG: Assembly download was successful. Attempting setup of file: D:\x64Production.dll 
    LOG: Entering run-from-source setup phase. 
    LOG: Assembly Name is: x64Production, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 
    ERR: Failed to complete setup of assembly (hr = 0x8007000b). Probing terminated. 

Qualcun altro ha verificato se questo è semplicemente non supportato nel VS2010?

+0

Non ha mai senso creare una DLL per il target x64, indirizzare sempre AnyCPU. L'impostazione conta solo su un progetto EXE. Mstest corre in modalità a 32 bit. –

+1

@Hans, ero sotto l'impressione ([1] (http://stackoverflow.com/a/516740/1198408), [2] (http://stackoverflow.com/a/8436574/1198408), [3 ] (http://visualstudiohacks.com/articles/visual-studio-net-platform-target-explained/)) che specifichi che il progetto dovrebbe compilare a x64 se alla fine chiama a una DLL non gestita che è a sua volta a 64 bit . Potresti fornirmi ulteriori ragionamenti su questo? – David

+0

David ha ragione su questo. – Joshua

risposta

9

Dalla lettura di questo, MSTest.exe è a 32 bit.

+6

Sei corretto. Non avendo trovato alcuna risorsa che affermasse che fosse impossibile, dovevo interpretare male interpretando in modo ottimistico ciò che stavo leggendo. "[Visual Studio Team Load Load Goes 64 bit!] (Http://blogs.msdn.com/b/lkruger/archive/2009/06/08/visual-studio-team-test-load-agent-goes- 64-bit.aspx) ") afferma " in realtà supportiamo solo gli assembly di test che prendono di mira le piattaforme "Any CPU" o "x86". Facepalm. – David

+0

E dal momento che stai per caricare una DLL x64 nativa, il passaggio a qualsiasi CPU non aiuta in realtà. Cura la COM fuori processo o qualche altra pazza idea? Io non. – Joshua

+0

Ho intenzione di seguire [questo post del blog] (http://rupertrawnsley.blogspot.com/2011/04/mstest-and-64bit.html) un po 'più da vicino e vedere se [forzando MsTest.exe a 64 -bit] (http://blogs.msdn.com/b/danielvl/archive/2009/03/28/run-mstest-exe-as-native-64-bit-process.aspx) (e copia del registro pertinente voci sopra) eseguiranno i test. – David

1

aver seguito this blog post, quanto segue, eseguito da un prompt dei comandi VS (così CorFlags.exe è nel PATH), ottiene le prove di corsa per la mia soluzione giocattolo:

@echo off 
REM remove the 32Bit flag, forcing the executable to be 64-bit when run on a 64 bit os. 
REM Expect the following output: 
REM " 
REM corflags : warning CF011 : The specified file is strong name signed. Using /Force will invalidate the signature of this image and will require the assembly to be resigned. 
REM " 
CorFlags.exe "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\MSTest.exe" /32BIT- /Force 

REM skip the strong name verification, because the 32-bit flag was modified 
reg add HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\StrongName\Verification\MSTest,b03f5f7f11d50a3a /f 

REM copy over registry keys to the 64-bit shadow registry. 
REM Without the "{13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b}\Extensions" subkey, mstest will output 
REM " 
REM File extension specified '.dll' is not a valid test extension. 
REM " 
reg copy HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\EnterpriseTools\QualityTools\TestTypes HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\10.0\EnterpriseTools\QualityTools\TestTypes /s /f 

Resta da vedere come questo andrà contro il vero codice di produzione.

+0

Contro i test reali: BadImageFormatException. Ora smetterò di fustigare questo cavallo morto. – David

+0

Mi chiedo se dovremmo usare mestest o nunit. Dalla tua esperienza pensi che la maggior parte non sia utilizzabile a 64 bit? grazie!! – AnneTheAgile

+1

@AnneTheAgile, dalla mia esperienza non è utilizzabile per il codice di produzione a 64 bit. Sembra che mentre i test possono essere eseguiti sulla piattaforma a 64 bit, non possono testare il codice a 64 bit. Mi piacerebbe molto che questo punto fosse smentito! – David

28

Sono venuto qui cercando la soluzione per un problema simile. Pubblicando questa risposta nel caso in cui la soluzione che ho trovato aiuti qualcun altro. Ciò ha risolto per me in Visual Studio (2012):

Add New Item -> Impostazioni per il test Add Test Setting Item Modificare il TestSetting Run test in 64 bit process Per default è impostato su "test di forza per l'esecuzione in processo a 32 bit"

Dal menu: Test -> Impostazioni di prova -> Seleziona file di impostazioni di prova -> Scegli il file di impostazioni di prova che hai creato.

Ora eseguire i test.

+0

Si prega di notare che questa soluzione non è disponibile in VS2010, su cui è stata posta questa domanda. – Joshua

+1

Funziona anche in VS 2015 Ultimate. – Chris

15

Ora con Visual Studio 2013 (almeno, non ho provato nel 2012) Non ho dovuto fare nulla se non scegliere Test-> Impostazioni di prova-> Architettura processore di default-> x64. È anche possibile utilizzare il file delle impostazioni di test per ottenere lo stesso risultato. Nessuno di quei vecchi klug è necessario che tu veda in altre risposte e vari post sul web. Dato che il mio materiale deve usare x64, ho aggiunto anche questi casi di test solo per ricordarmi se ho qualche impostazione sbagliata.

[TestMethod] 
    public void Running_64Bit_OS() 
    { 
     // It was determined to run only in 64 bits. 
     bool is64BitOS = System.Environment.Is64BitOperatingSystem; 
     Assert.AreEqual(is64BitOS, true); 
    } 

    [TestMethod] 
    public void Running_64Bit_Process() 
    { 
     // We have a requirement that one of the unmanaged DLL is built for 64 bits. 
     // If you are running MS Test in Visual Studio 2013 and this 
     // is failing, go to Test->Test Settings->Default Processor Architecture and 
     // chose x64, then run the tests again. This is not the only method. You 
     // could also use a test settings file. 
     bool is64BitProcess = System.Environment.Is64BitProcess; 
     Assert.AreEqual(is64BitProcess, true); 
    } 
+1

Questa funzione è disponibile anche su VS2012 – codingdave

+0

Ancora funziona a partire da VS2013 Update 4. È stato momentaneamente molto confuso quando si prova a testare un vecchio progetto, questo lo ha risolto immediatamente. –

+2

Solo per fare il pasticcio, le tue affermazioni dovrebbero avere i parametri in senso contrario, o ancora meglio usare Assert.IsTrue. –

2

Se avete installato ReSharper, fare riferimento al seguente link

In sostanza, è necessario creare un test di file di impostazioni nella soluzione, come indicato nelle altre risposte quindi aggiornare l'opzione ReSharper per MSTest a punto allo stesso file di impostazioni.

Ho riscontrato questo problema utilizzando Visual Studio 2013 Update 4 e Resharper 8.2.

3

Nel mio caso, sembrava non avere nulla a che fare con la piattaforma x86 o x64 o con le impostazioni di configurazione del test o con la versione .NET del progetto. BTW l'errore BadImageFormatException Ho anche menzionato qualcosa su 'la firma non è corretta'.

Il problema era che quando si utilizza Moq, è necessario aggiungere riferimenti mancanti al progetto di test dell'unità per le classi/interfacce che dipendono dall'oggetto che si sta tentando di deridere. Esamina i riferimenti del progetto che stai testando per avere un'idea di quali assiemi potresti perdere relativi all'oggetto che stai deridendo.

http://vibrantcode.com/2012/05/18/badimageformatexception-the-signature-is-incorrect/

0

Grazie per la punta su ReSharper, perché sottolineato il problema potrebbe essere evitato passando ad MSTest. Non riuscivo a far funzionare Resharper. Il test di una DLL a 64 bit di terze parti a 64 bit, anche se si sta solo prendendo in giro (lo deve ancora caricare) sembra funzionare solo con MsTest in modalità 64 bit. L'opzione Resharper per MSTest su "Usa questa configurazione di esecuzione prova" ha solo "Predefinito" come opzione a discesa e "Modifica" è disattivato. Anche l'altra impostazione "Usa configurazione di esecuzione del test specificata nel file di metadati" non funziona e si presume che si sappia cosa o dove si trova questo file di metadati. Resharper non funzionerebbe in modalità a 64 bit come dimostrato dalla suddetta variabile di ambiente Is64BitProcess.(VS 2013 Update 4, ReSharper 8.2)

0

Oltre alla soluzione @Anupam, il VS2013, si può andare a TEST> Test impostazioni> default Architettura del processore e il cambiamento tra X86 e X64. È quasi come selezionare un file di impostazioni di test, tranne che non è necessario il file per specificare solo la piattaforma di test.

5

Inoltre, è possibile selezionare Test-> Impostazioni di prova-> Procesor Architecture predefinito-> X64. Potrei lavorare

+0

Questo è necessario anche se il file delle impostazioni di test selezionato dichiara il testimone del processore. – StingyJack