2009-11-04 8 views
8

Utworzyłem bibliotekę DLL w języku C# przy użyciu środowiska .NET 3.0.Wykonaj kod .NET 3.0 z pakietu Office 2003

Poniżej znajduje się kod mojego DLL

namespace CompanyName.Net 
{ 
    [Guid("F7075E8D-A6BD-4590-A3B5-7728C94E372F")] 
    [ClassInterface(ClassInterfaceType.AutoDual)] 
    [ProgId("CompanyName.Net.Webrequest")] 
    public class WebRequest 
    { 
     public string Result { get; private set; } 
     public string Url { get; set; } 
     public string StatusDescription { get; private set; } 
     public HttpStatusCode StatusCode { get; private set; } 

     public WebRequest() 
     { 
      //explicit constructor 
     }  

     public string GetResponse(string url) 
     { 
      System.Net.WebRequest webreq = System.Net.WebRequest.Create(url); 
      HttpWebResponse response = (HttpWebResponse) webreq.GetResponse(); 
      // Store the status. 
      StatusDescription = response.StatusDescription; 
      StatusCode = response.StatusCode; 
      // Get the stream containing content returned by the server. 
      Stream dataStream = response.GetResponseStream(); 
      // Open the stream using a StreamReader for easy access. 
      StreamReader reader = new StreamReader(dataStream); 
      // Read the content. 
      Result = reader.ReadToEnd(); 
      // Cleanup the streams and the response. 
      reader.Close(); 
      dataStream.Close(); 
      response.Close(); 
      //return the response 
      return Result; 
     } 
    } 
} 

Próbuję uzyskać ten kod do uruchomienia pakietu Office 2003 z kodu VBA. Biblioteka DLL została podpisana przy użyciu domyślnego podpisu programu Visual Studio 2008.

udało mi się odwołać mój zespół, tworząc plik .tlb korzystając

regasm /tlb c:\CompanyName.Net.dll 

Ale gdy chcę utworzyć instancję obiektu:

Private Sub Command0_Click() 
    Dim o As Object 
    Set o = CreateObject("CompanyName.Net.WebRequest") 
    Dim s As String 
    s = o.GetResponse("http://www.google.be") 
    MsgBox s 
End Sub 

pojawia się następujący błąd :

ActiveX component can't create Object

Co robię źle?

Maszyna, którą testuję, ma zainstalowaną platformę .NET do architektury .NET 3.5.

Odpowiedz

10

OK, po kilku niezłych pomysłach od Thorstena Dittmara, w końcu udało mi się to zrobić. Niektóre rzeczy, które pojawiły się w trakcie naszej dyskusji i innych rzeczy znalazłem w internecie:

  1. Framework musi być zainstalowany na komputerze docelowym.
  2. . Obsługa programatora .Net musi być zainstalowana na maszynie docelowej.
  3. W AssemblyInfo.cs upewnij się, że ustawiony

    [assembly: ComVisible(true)]

  4. Jak Thorsten wskazał trzeba mieć konstruktora bez parametrów publicznego w klasie .NET.

  5. Upewnij się, aby zaznaczyć opcję "Register for COM Interop" w zakładce Build na stronie Properties projektu.
  6. Należy podpisać projekt za pomocą karty Podpisywanie na stronie Właściwości projektu.
  7. Zarejestruj bibliotekę DLL na komputerze docelowym, wykonując to polecenie. Parametr /codebase wydawał mi się dla mnie skuteczny. Ścieżka do biblioteki typów (.tlb) lub DLL nie ma znaczenia. Można znaleźć regasm w katalogu C: \ Windows \ Microsoft.Net \ Framework \ v2.050727 \ regasm.exe

    regasm c:\CompanyName.Net.dll /tlb:CompanyName.Net.tlb /codebase

  8. Reference plik .tlb w edytorze VBA przy użyciu Narzędzia> Referencje.

  9. Przeciągnij bibliotekę dll z C: \ do swojego GAC w C: \ Windows \ assembly \ (Początkowo nie zdawałem sobie z tego sprawy, ale najwyraźniej konieczne jest, aby Biuro znalazło twój zestaw.)

To powinno załatwić sprawę.

Uaktualniłem także moją klasę Webrequest, dodając do niej interfejs, dzięki czemu obsługa IntelliSense obsługuje się w VB6 (co niestety nie działa w VBA).

+0

Jest to najbardziej zwięzły i jedyny kompletny przewodnik po tym problemie, który znalazłem po wielu godzinach próbowania, aby to zadziałało. Dziękuję Ci. –

2

Potrzebujesz wyraźnego konstruktora bez parametrów w swojej klasie COM. Zmień definicję klasy na:

namespace CompanyName.Net 
{ 
    [Guid("F7075E8D-A6BD-4590-A3B5-7728C94E372F")] 
    [ClassInterface(ClassInterfaceType.AutoDual)] 
    [ProgId("CompanyName.Net.Webrequest")] 
    public class WebRequest 
    { 
     public string Result { get; private set; } 
     public string Url { get; set; } 
     public string StatusDescription { get; private set; } 
     public HttpStatusCode StatusCode { get; private set; } 

     public WebRequest() 
     { 
     } 

     public string GetResponse(string url) 
     { 
      System.Net.WebRequest webreq = System.Net.WebRequest.Create(url); 
      HttpWebResponse response = (HttpWebResponse) webreq.GetResponse(); 
      // Store the status. 
      StatusDescription = response.StatusDescription; 
      StatusCode = response.StatusCode; 
      // Get the stream containing content returned by the server. 
      Stream dataStream = response.GetResponseStream(); 
      // Open the stream using a StreamReader for easy access. 
      StreamReader reader = new StreamReader(dataStream); 
      // Read the content. 
      Result = reader.ReadToEnd(); 
      // Cleanup the streams and the response. 
      reader.Close(); 
      dataStream.Close(); 
      response.Close(); 
      //return the response 
      return Result; 
     } 
    } 
} 

To powinno zadziałać.

+0

Po prostu próbowałem, ale nadal daje mi ten sam błąd. Mój projekt został oznaczony jako "register for COM Interop", ale bez radości. Być może sposób, w jaki nazywam moją funkcję w VBA jest błędny? Mam stratę – Peter

+0

Czy ponownie zarejestrujesz bibliotekę DLL? –

+0

Odtworzyłem plik tlb, który powinien również zarejestrować ponownie bibliotekę dll. Czy mogę spróbować ponownie dodać go do GAC? – Peter