2012-02-09 42 views
5

Trong một dự án của tôi, tôi có ứng dụng C# đang sử dụng C++ DLL. Hiện tại máy khách, chúng tôi đang đăng ký C++ DLLS tại các thành phần COM trong registry để chúng tôi sẽ sử dụng chúng trong C#.Làm thế nào để sử dụng Đăng ký miễn phí COM dll trong dot net

tôi học trên NET rằng có một giải pháp miễn phí Reg sẵn từ microsoft tại liên kết http://msdn.microsoft.com/en-us/library/ms973913.aspx

Nhưng sau khi đọc tôi đã không nhận được nhiều đầu mối vì kiến ​​trúc ứng dụng của tôi là khác nhau như sau

  1. tôi đang có 2 C + + dlls LET SAY CPForms.dll và Rules.dll.
  2. Rule.dll là bao gồm trong CPForms.dll
  3. Tôi đã 1 C# dll để nói ConsumeForm.dll được sử dụng CPForms.DLL
  4. Tôi có một C# Exe mà đang sử dụng ConsumeForm.dll

Khách hàng của tôi chỉ mở C# Exe mà lần lượt là gọi ConsumeForm.dll mà tiếp tục gọi CPForms.dll cho thấy hình thức C++ (UI), có nút xác nhận, khi người dùng nhấp vào nút đó nội bộ bằng cách sử dụng C++ Rules.dll. Hiện tại tôi đang đăng ký cả hai C++ dlls trong registry.

Bây giờ, khách hàng chỉ muốn Rule.dll được tham chiếu là cài đặt RegFree, vì Rule.dll thay đổi thường xuyên và khách hàng không muốn hủy đăng ký và đăng ký lại bằng tài khoản quản trị viên.

Sau đó, ứng dụng khách đó OK với đăng ký CPForms.dll.

Câu hỏi của tôi là cách chúng tôi có thể tạo tệp kê khai? Và nó sẽ hoạt động như thế nào trong kịch bản của tôi?

+0

Bài viết cung cấp nhiều chi tiết, bạn cần thêm những gì? Bạn đã thử cái gì? Bạn đang gặp phải lỗi gì? – Polyfun

+0

Tôi đoán bạn cần phải biết liệu tệp kê khai có được đính kèm với tệp .exe hoặc một trong các tệp DLL không - tôi đoán tệp .exe vì nó thiết lập quy trình. Ngoài ra, cú pháp XML không rõ ràng phải không? – Rup

+1

Thực ra, có cần phải đăng ký miễn phí không? Miễn là rules.dll được cài đặt trong cùng một vị trí (mà sẽ yêu cầu quyền quản trị anyway, chính xác?) Và thực hiện các đối tượng và giao diện tương tự CPForms.dll được xây dựng chống lại, tại sao nó cần phải được đăng ký và đăng ký lại mọi thời gian? (Tuy nhiên, câu hỏi tự do đăng ký rất thú vị.) – Rup

Trả lời

8

Lưu ý: Xem xét sử dụng một biểu hiện như trong câu trả lời ở đây cho một giải pháp tốt hơn:

Làm thế nào để làm điều đó mà không có một biểu hiện

COM đăng ký là một dịch vụ opti onal cho máy chủ inproc.

Một lần nữa: Bạn không phải đăng ký một đối tượng để tạo đối tượng đó. Nếu nó không được đăng ký, (và không phải trong một biểu hiện) bạn không thể tạo nó với CoCreateInstance, bởi vì sổ đăng ký (hoặc biểu hiện) là những gì yêu cầu CoCreateInstance tải DLL.

Tuy nhiên bạn có thể tạo nó với LoadLibrary, GetProcAddress, DllGetClassObjectIClassFactory::CreateInstance.

(Lưu ý bạn sẽ không nhận được bất kỳ dịch vụ COM + nào và bạn không thể tạo đối tượng quá trình theo cách này hoặc đối tượng có mô hình luồng không tương thích với chuỗi tạo. làm điều đó cho bạn những điều này trở thành vấn đề của bạn).

Dịch vụ mà CoCreateInstance cung cấp là tìm đúng DLL cho cuộc gọi tới LoadLibrary và chỉ cần gọi các chức năng khác cho bạn. (Và kiểm tra các mô hình luồng tương thích, tạo ra trên các chủ đề thích hợp, và sử dụng CoMarshalInterthreadInterfaceInStream/CoUnmarshalInterfaceAndReleaseStream để sắp xếp lại giao diện nếu chúng không giống như vậy. . các vấn đề)

Something như thế này nên làm như lừa:

// Really you should break this up int GetClassFactoryFromDLL, then reuse the class factory. 
// But this is all from memory... 
// Load CLSID_MyID, from DLL pszMyDllPath 
typedef HRESULT __stdcall (*_PFNDLLGETCLASSOBJECT)(
    __in REFCLSID rclsid, 
    __in REFIID riid, 
    __out LPVOID *ppv 
) PFNDLLGETCLASSOBJECT; 

HRESULT CreateInstanceFromDll(LPCTSTR pszMyDllPath, CLSID clsidMyClass, IUknown** ppunkRet) 
{ 
    // Handle bad callers 
    *ppunkRet = NULL; 
    HANDLE hDLL = LoadLibrary(pszMyDllPath); 
    if(hDLL == NULL) 
    { 
     // Failed to load 
     return HRESULT_FROM_NTSTATUS(GetLastError()); 
    } 
    PFNDLLGETCLASSOBJECT pfnDllGetClassObject = GetProcAddress(hDLL); 
    if(pfnDllGetClassObject == NULL) 
    { 
     // Not a COM dll 
     HRESULT hrRet = HRESULT_FROM_NTSTATUS(GetLastError()); 
     FreeLibrary(hDLL);hDLL = NULL; 
     return hrRet; 
    } 
    IClassFactory* pClassFactory = NULL; 
    HRESULT hr = pfnDllGetClassObject(clsidMyClass, IID_IClassFactory, &pClassFactory); 
    if(FAILED(hr)){ 
     FreeLibrary(hDLL);hDLL = NULL; 
     return hr; 
    } 
    hr = pClassFactory->CreateInstance(NULL, IID_IUnknown, &ppunkRet); 
    pClassFactory->Release(); 
    if(FAILED(hr)) 
    { 
     *ppunkRet = NULL; 
     FreeLibrary(hDLL); 
     return hr; 
    } 
    return hr; 
} 

Lưu ý: Điều này sẽ cho phép bạn tạo đối tượng. Tuy nhiên, nếu đối tượng bạn gọi là chính nó phụ thuộc vào việc đăng ký, nó sẽ không hoạt động chính xác.

Cụ thể, nhiều triển khai IDispatch dựa vào thư viện kiểu. Nếu đó là trường hợp của một đối tượng cụ thể, thì GetIDsOfNamesGetTypeInfo sẽ không thành công và bạn sẽ không thể sử dụng các phương pháp bị ràng buộc trễ với đối tượng. Điều này bao gồm việc sử dụng dynamic trong C# và các ngôn ngữ động như Python.

Các phương pháp khác như giao diện kép và giao diện không kế thừa từ IDispatch cũng có thể hoạt động tuy nhiên ngay cả khi phương pháp IDispatch không.

Dòng dưới cùng: Để đăng ký COM miễn phí hoạt động, đối tượng được khởi tạo không được dựa vào đăng ký của riêng nó.

+0

Tôi đã theo dõi trường hợp này (AutoItX.dll). Đối tượng thực sự đã được tạo. Nhưng tôi không thể gọi nó không thông qua interop lib không thông qua sự phản ánh. Khi tôi đăng ký C++ lib tất cả bắt đầu làm việc. –

+0

@DzmitryLahoda, bạn không thể đăng ký tệp C++ * .lib. Tôi giả sử bạn có nghĩa là bạn đã đăng ký dll COM? Làm thế nào bạn đăng ký nó? – Ben

+0

Xin lỗi vì đã gây hiểu lầm. Tôi nói về dll. Khi tôi làm 'regsvr32 AutoItX3.dll/u 'thì tôi không thể gọi bất kỳ phương thức nào trên đối tượng đã tạo. Nó không sử dụng được. Khi tôi 'regsvr32 AutoItX3.dll' tất cả các công trình. Nhưng trong trường hợp này tôi không cần mã được cung cấp trong ý nghĩa rằng mã không phải là câu trả lời "Làm thế nào để sử dụng đăng ký miễn phí COM dll trong dot net" cho đối tượng COM hoàn toàn hợp lệ. –

2

Đối với những người sẽ chuyển sang câu hỏi này trong tìm kiếm Registration free COM dll in dot net, tôi đã có thể sử dụng đối tượng AutoItX COM theo cách thức Reg miễn phí từ C# trong câu trả lời https://stackoverflow.com/a/19996424/173073. Tạo và sử dụng các đối tượng Reg miễn phí khác sẽ tương tự.

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