2013-03-05 11 views
7

Ten problem powodował ból głowy przez kilka dni i nie mogę znaleźć powodu. Jestem pewien, że jest to problem środowiskowy związany z moją maszyną, ale nadal powoduje problemy z testowaniem.Biblioteka typu 64-bitowego i biblioteki typu 32-bitowego poza Synchronizacją

Tworzę bibliotekę DLL w języku C# przy użyciu programu Visual Studio 2010 Professional. Wersja pierwsza znajduje się poniżej;

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"); 
     } 

    } 
} 

Ten zestaw świetnie się komponuje i wszystko jest dobrze. Uruchom następujący skrypt, aby zarejestrować go jako obiekt COM (najpierw dla wersji 32-bitowej, a następnie dla wersji 64-bitowej);

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 

Następnie użyj poniższego skryptu, aby go przetestować;

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

użyć csript przetestować scenariusz, dzięki czemu można kontrolować głębokość nieco, które wykorzystuje - testować je raz z 32-bitowym i raz 64 bitów. Jak dotąd wszystko jest dobrze.

Teraz, kiedy zmodyfikować oryginalny zespół, aby dodać funkcję, co następuje

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!!"); 
     } 

    } 
} 

Przed modyfikacją, że wyrejestrowany z biblioteki używając „regasm/unregister” i poinformował wszystkich rodzajów niezarejestrowany pomyślnie.

Kiedy rejestruję bibliotekę, teraz ze zmianami, oryginalny skrypt testowy działa idealnie. Jeśli rozszerzę skrypt testowy, aby wywołać nową funkcję HelloWorld;

W 32-bitowych skryptach działa idealnie. W skryptach 64-bitowych narzeka, że ​​taka funkcja nie istnieje dla obiektu TestCOM.Class1

Próbowałem tego w każdy możliwy sposób, ale nie mogę określić, dlaczego nowa funkcja jest dostępna dla 32-bitowych wywołujące, ale nie 64-bitowe.

Co robię źle? czy jest gdzieś cache dla 64-bitowych rzeczy, których nie znam, czy ustawienia rejestru, które wymagają zmiany?

Aby było jasne; 1. Zespół Budowa 2. Rejestracja użyciu regasm, raz 32 i raz na 64 3. Test z użyciem skryptu - wszystko działa 4. Wyrejestrowanie biblioteki 5. Dokonaj modyfikacji, przebudowy 6. Rejestr zgodnie Krok 2 7 Testy działają w wersji 32-bitowej, ale nie 64. Wtf?

Odpowiedz

2

Najwyraźniej cierpisz z powodu DLL DLL, zawsze z COM, ładuje starą wersję biblioteki DLL. Twój GAC mógłby zostać zanieczyszczony przez wcześniejsze eksperymenty, zawsze znajdzie pierwszą wersję GACed. Robisz to gorzej, określając [Guid], dzięki czemu twoja nowa klasa wygląda tak samo jak stara, nawet jeśli nie jest identyczna. Zapobieganie COM z informacją, że nie może znaleźć nowej wersji klasy.

Najbardziej wiarygodnym, choć hałaśliwym sposobem sprawdzenia, skąd się wzięła biblioteka DLL, jest użycie narzędzia ProcMon firmy SysInterals. Zobaczysz go czytając klucz rejestru i ładując bibliotekę DLL. Możesz zobaczyć, z którego katalogu pochodzi. Upewnij się, że to nie GAC, usuń go za pomocą gacutil/u, jeśli tak jest, i upewnij się, że został on przebudowany, sprawdzając znacznik czasu w pliku.

+0

Jesteś absolutną legendą. Wygląda na to, że z jakiegoś powodu kopia wcześniejszej wersji biblioteki DLL była w katalogu c: \ windows \ system32 Usunięcie tej kopii rozwiązuje problemy od razu, nie trzeba ponownie rejestrować niczego, itp. Dziękuję - nigdy nie przyszło mi do głowy, aby użyć procmon, aby zobaczyć, co się dzieje. Ostatnie pytanie - czy chcesz powiedzieć, że nie powinieneś określać identyfikatora GUID? Zawsze mówiono mi, że musisz? – DFriend