2009-05-12 29 views
8

Tôi đã thực hiện một đơn giản C# DLL (đó là một phần của một dự án lớn hơn nhiều) bằng cách sử dụng VS2005. Tôi cần phải sử dụng DLL trong Excel thông qua mã VBA vì vậy tôi đang sử dụng COM Interop trên lắp ráp. Tôi đang cố gắng để làm cho quá trình xây dựng tự động tạo ra các tập tin TLB cần thiết vì vậy mà tôi không cần phải đi đến dòng lệnh và sử dụng regasm sau mỗi xây dựng.cảnh báo MSB3391: <DLL> không chứa bất kỳ loại nào có thể được đăng ký cho COM Interop

Vấn đề của tôi là mặc dù DLL biên dịch và xây dựng tốt, nó không tạo ra tệp TLB. Thay vào đó, lỗi trong tiêu đề in ra trong hộp đầu ra.

Tôi đã nhận các tệp DLL khác để xây dựng tệp TLB bằng cách truy cập thuộc tính của dự án trong VS2005 -> Xây dựng -> Đầu ra -> Kiểm tra "Đăng ký COM interop". Ngoài ra tôi có [assembly: ComVisible (true)] trong AssemblyInfo.cs.

Dưới đây là tóm tắt các nguồn cho các vấn đề DLL và DLL mà nó tham chiếu cho một kiểu trả về:

using System; 
using System.IO; 
using System.Runtime.InteropServices; 
using SymbolTable; 

namespace ProblemLibrary 
{ 
    public class Foo 
    {  
     public Foo(string filename) 
     { 
      ... 
     } 

     // method to read a text file into a SymbolTable 
     public SymbolTable BuildDataSet(string[] selected) 
     { 
      ... 
     } 
    } 
} 

Dưới đây là một bản tóm tắt của SymbolTable.dll. Nó chứa một kiểu trả về mà ProblemLibrary sử dụng.

using System; 
using System.Collections.Generic; 

namespace SymbolTable 
{ 
    public class SymbolTable 
    { 
     readonly Dictionary<SymbolInfoStub, string> _symbols = new Dictionary<SymbolInfoStub, string>(); 

     /*methods that interact with Dictionary snipped*/ 
    } 
} 
+0

Tại sao bạn cần COM interop? Tôi không thấy bất kỳ COM ở đó. Bạn có muốn truy cập C# Assembly qua COM sau này không? – codeulike

+0

Có, tôi cần phải sử dụng DLL này trong Excel VBA. –

Trả lời

18
  1. Bạn cần có ctor mà không có bất kỳ thông số nào.
  2. Bạn cần có GuidAttributeProgIdAttribute xung quanh các lớp học.
  3. Tốt hơn là đánh dấu hội đồng là ComVisible (false) và đánh dấu rõ ràng các lớp cần xuất.
  4. Sử dụng giao diện cho các lớp học của bạn.
  5. Đảm bảo bạn có GuidAttribute ở cấp độ lắp ráp.

    [Guid("<PUT-GUID-HERE-1>")] 
    [ComVisible(true)] 
    interface IFoo 
    { 
        void DoFoo(); 
    } 
    
    [Guid("<PUT-GUID-HERE-2>")] 
    [ComVisible(true)] 
    [ProgId("ProgId.Foo")] 
    class Foo : IFoo 
    { 
        public void DoFoo() 
        { 
        } 
    } 
    
+1

Tuyệt vời, Constructor mà không có bất kỳ tham số nào đã làm các trick. Cảm ơn rất nhiều! –

+0

Constructor rỗng. Đó là bugging tôi mãi mãi! Cảm ơn. –

+0

Đó là một chút câm cho một lớp mà cũng nên có thể sử dụng theo cách điển hình .NET. Hãy tưởng tượng một lớp định dạng tệp cụ thể, trong đó có một hàm tạo chấp nhận tên tệp - cách điển hình để khởi tạo nó trong .NET. Bây giờ chỉ để làm cho lớp đó có thể nhìn thấy được, tôi loại bỏ hàm khởi tạo và tôi phải gọi phương thức "Load" tĩnh cho .NET. Và sau đó vẫn có phương thức "Load" không công khai/tĩnh để tạo nó chỉ dành cho COM. Điều đó có vẻ hơi bẩn, phải không? –

1

Trong tập tin AssemblyInfo.cs, chắc chắn rằng bạn có những điều sau đây:

// Setting ComVisible to false makes the types in this assembly not visible 
// to COM components. If you need to access a type in this assembly from 
// COM, set the ComVisible attribute to true on that type. 
[assembly: ComVisible(true)] 

UPDATE:

đọc: How can I make use of .NET objects from within Excel VBA?

nào liên kết đến: http://richnewman.wordpress.com/2007/04/15/a-beginner%E2%80%99s-guide-to-calling-a-net-library-from-excel/

+0

Cảm ơn thông tin, nhưng tôi đã viết trong mô tả của tôi rằng tôi đã có điều đó. –

+0

Tôi đã nhận được các C# DLL khác để làm việc trong COM trước đây. Mặc dù các liên kết đã không giúp tôi với vấn đề của tôi, tôi đã tìm hiểu về liên kết giữa COM client intellisense và [ClassInterface (ClassInterfaceType.AutoDual)] trong C# từ chúng. Cảm ơn vì điều đó. –

2

tôi thấy một vấn đề tương tự. Tôi đã nhận ra lỗi như: MSB3391

cảnh báo: không chứa bất kỳ loại mà có thể đăng ký cho COM Interop .

Tôi đã tuân thủ tất cả các quy tắc (ComVisible, v.v.) nhưng không có gì hiệu quả.

Giải pháp: Tôi phải đặt thứ gì đó trong hàm dựng mặc định để nó không được tối ưu hóa. Thời điểm tôi đã có một cái gì đó ở đó, đăng ký kết thúc với không có thông báo và thành phần đã được nhìn thấy trong sổ đăng ký.

Lưu ý thú vị: một người bạn của tôi đã quản lý đăng ký DLL gốc với hàm tạo mặc định trống trên máy của mình (64-bit Windows-7, VS2008-Professional, như của tôi). Tuy nhiên, regasm.exe của ông là:

C: \ Windows \ Microsoft.NET \ Framework64 \ v2.0.50727 \ regasm.exe

trong khi tôi là:

C: \ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ RegAsm.exe

Vì vậy, có thể có sự khác biệt giữa các phiên bản của khung công tác .NET - có thể phiên bản mới hơn là tối ưu hóa quá m uch và REGASM không tính đến điều đó.

Các vấn đề liên quan