2013-03-05 24 views
7

Questo problema mi ha causato un mal di testa per alcuni giorni e non riesco a trovarne un motivo. Sono abbastanza sicuro che questo sia un problema ambientale in particolare per la mia macchina, ma continua a causarmi problemi con i test.Libreria di tipi a 64 bit e librerie di tipi a 32 bit fuori sincrono

Sto creando una DLL in C# utilizzando Visual Studio 2010 Professional. La prima versione è sotto;

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 

namespace TestCOM 
{ 
    [ClassInterface(ClassInterfaceType.AutoDual)] 
    [System.Runtime.InteropServices.ComVisible(true)] 
    [System.Runtime.InteropServices.ProgId("TestCOM.Class1")] 
    [System.Runtime.InteropServices.Guid("803A1B2F-1CDA-4571-9084-87500388693B")] 
    public class Class1 
    { 
     public void showMessage() 
     { 
      MessageBox.Show("Hello from TextCom"); 
     } 

    } 
} 

Questo assemblaggio va bene e tutto va bene. Eseguo il seguente script per registrarlo come oggetto COM (prima per 32-bit, poi per 64-bit);

C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm.exe TestCOM.dll /codebase /nologo /tlb:TestCOM32.tlb 
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm.exe TestCOM.dll /codebase /nologo /tlb:TestCOM64.tlb 

E quindi utilizzare il seguente script per testarlo;

dim tc 
set tc = CreateObject("TestCOM.Class1") 
tc.showMessage() 

che uso csript per verificare lo script, così posso controllare quali profondità di bit utilizza - I provarlo una volta con 32 bit e una volta con 64 bit. Fin qui tutto è buono.

Ora, quando modifico il gruppo originale per aggiungere una funzione, come segue

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 

namespace TestCOM 
{ 
    [ClassInterface(ClassInterfaceType.AutoDual)] 
    [System.Runtime.InteropServices.ComVisible(true)] 
    [System.Runtime.InteropServices.ProgId("TestCOM.Class1")] 
    [System.Runtime.InteropServices.Guid("803A1B2F-1CDA-4571-9084-87500388693B")] 
    public class Class1 
    { 
     public void showMessage() 
     { 
      MessageBox.Show("Hello from TextCom"); 
     } 

     public void HelloWorld() 
     { 
      MessageBox.Show("Hello World!!"); 
     } 

    } 
} 

prima della modifica, io non registrati la libreria con "regasm/unregister" e ha riferito tutti i tipi non registrato con successo.

Quando registro la libreria, ora con le modifiche, lo script di test originale funziona perfettamente. Se estendo lo script di test per chiamare la nuova funzione HelloWorld;

In script a 32 bit, funziona perfettamente. In script a 64 bit, si lamenta che non esiste alcuna funzione di questo tipo per l'oggetto TestCOM.Class1

Ho provato questo in ogni modo possibile, ma non riesco a identificare perché la nuova funzione è disponibile per il 32-bit chiamanti, ma non le chiamate a 64 bit.

Cosa sto sbagliando? c'è una cache da qualche parte per le cose a 64 bit di cui non sono a conoscenza, o un'impostazione di registro che deve essere cambiata?

Per essere chiari; 1. assemblaggio Corporatura 2. Registrarsi utilizzando regasm, una volta per 32 e una volta per 64 3. test utilizzando lo script - tutto funziona 4. Annullare la registrazione biblioteca 5. apportare modifiche, ricostruire 6. Registra come da Fase 2 7 I test funzionano a 32-bit, ma non a 64. Wtf?

risposta

2

Ovviamente si soffre di DLL Hell, sempre in giro con COM, si sta caricando una vecchia versione della DLL. Il tuo GAC potrebbe essere stato contaminato da esperimenti precedenti, troverà per prima cosa la versione GACed. Stai peggiorando la situazione specificando [Guid], rendendo la tua nuova classe simile a quella precedente, anche se non è identica. Impedendo a COM di dirti che non riesce a trovare la nuova versione della classe.

Il modo più affidabile, anche se rumoroso, per vedere da dove proviene la DLL è utilizzando l'utilità ProcMon di SysInterals. Lo vedrai leggendo la chiave di registro e caricando la DLL. Puoi vedere da quale directory proviene. Assicurati che non sia il GAC, rimuovilo con gacutil/u se questo è il caso, e assicurati di averlo ricostruito controllando il timestamp del file.

+0

Legenda assoluta. Sembra che per qualche motivo, una copia della versione precedente della dll fosse in c: \ windows \ system32 Eliminando quella copia si risolvono immediatamente i problemi, non è necessario registrare nuovamente nulla, ecc. Grazie - non mi è mai venuto in mente di usare procmon per vedere cosa stava succedendo. Un'ultima domanda: stai dicendo che non dovrei specificare un GUID? Mi è sempre stato detto che dovevi? – DFriend

Problemi correlati