2009-11-04 9 views
8

Tôi đã tạo một DLL trong C# bằng cách sử dụng khuôn khổ .NET 3.0.Thực thi mã .NET 3.0 từ Office 2003

Dưới đây là mã của DLL của tôi

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

Tôi đang cố gắng để có được mã này để chạy từ mã VBA Office 2003. DLL được ký bằng cách sử dụng ký Visual Studio 2008 mặc định.

tôi đã quản lý để tham khảo lắp ráp của tôi bằng cách tạo ra một tập tin .tlb sử dụng

regasm /tlb c:\CompanyName.Net.dll 

Nhưng khi tôi muốn tạo một thể hiện của đối tượng:

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 

tôi nhận được lỗi sau :

ActiveX component can't create Object

Tôi đang làm gì sai?

Máy tôi đang thử nghiệm đã cài đặt .NET lên khung .NET 3.5.

Trả lời

10

OK, sau một số ý tưởng khá hay từ Thorsten Dittmar, tôi cuối cùng cũng có được điều này để làm việc. Một số thứ xuất hiện trong cuộc thảo luận của chúng tôi và những thứ khác tôi tìm thấy trên web:

  1. Khuôn khổ .NET cần được cài đặt trên máy mục tiêu.
  2. .Net Hỗ trợ khả năng lập trình cần phải được cài đặt trên máy mục tiêu.
  3. Trong AssemblyInfo.cs chắc chắn rằng bạn thiết lập

    [assembly: ComVisible(true)]

  4. Như Thorsten chỉ ra bạn cần phải có nhà xây dựng công parameterless trong lớp Net của bạn.

  5. Đảm bảo kiểm tra "Đăng ký COM Interop" trong tab Xây dựng trên trang Thuộc tính của dự án của bạn.
  6. Đảm bảo ký dự án của bạn bằng cách sử dụng tab Ký trên trang Thuộc tính của dự án của bạn.
  7. Đăng ký DLL của bạn trên máy mục tiêu bằng cách chạy lệnh này. Thông số /codebase dường như thực hiện thủ thuật cho tôi. Đường dẫn đến thư viện kiểu (.tlb) hoặc DLL không quan trọng. Bạn có thể tìm regasm tại C: \ Windows \ Microsoft.Net \ Framework \ v2.050727 \ regasm.exe

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

  8. Reference file .tlb trong VBA Editor của bạn sử dụng Công cụ> Tài liệu tham khảo.

  9. Kéo dll từ C: \ sang GAC của bạn tại C: \ Windows \ assembly \ (Tôi đã không nhận ra điều này lúc đầu nhưng dường như Office cần tìm assembly của bạn.)

Điều đó cần thực hiện thủ thuật.

Tôi cũng đã nâng cấp lớp Webrequest của mình bằng cách thêm giao diện cho nó, do đó đã bật hỗ trợ IntelliSense trong VB6 (đủ đáng tiếc là không hoạt động trong VBA).

+0

Đây là hướng dẫn ngắn gọn và đầy đủ nhất về vấn đề này mà tôi tìm thấy sau hàng giờ cố gắng làm cho việc này hoạt động. Cảm ơn bạn. –

2

Bạn cần một hàm tạo tham số không rõ ràng trong lớp COM của bạn. Thay đổi định nghĩa lớp học của bạn thành:

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

Điều này sẽ hiệu quả.

+0

Tôi vừa thử nhưng nó vẫn cho tôi lỗi tương tự. Tôi đánh dấu dự án của tôi là "đăng ký COM Interop" nhưng không có niềm vui. Có lẽ cách tôi gọi chức năng của tôi trong VBA là sai? Tôi đang thua lỗ – Peter

+0

Bạn có đăng ký lại DLL không? –

+0

Tôi đã tạo lại tệp tlb cũng nên đăng ký lại dll. Tôi có thể thử thêm nó vào GAC một lần nữa? – Peter