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ụ là 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
, DllGetClassObject
và IClassFactory::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ì GetIDsOfNames
và GetTypeInfo
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ó.
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
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
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