2011-02-16 34 views
7

Tôi đã tạo ứng dụng khách COM sử dụng hai dll máy chủ COM; Tôi muốn ứng dụng này chạy mà không cần đăng ký COM - ví dụ: winsxs/.manifestsgỡ lỗi đăng ký miễn phí COM (C++)

Tôi nhận được thông báo (... gần như mong đợi ...) "Lớp chưa đăng ký" khi tôi cố gắng tạo một đối tượng của đối tượng COM của tôi từ ứng dụng khách của tôi.

Tôi đã thành công loại cấu hình đó trước đây nhưng tôi không thể tìm ra lý do tại sao cấu hình này không thành công.


dưới đây là một vài chi tiết:

  • các module Tôi có:
    • một khách hàng MFC mà phụ thuộc vào 2 máy chủ COM (dll1.dll và dll2.dll)
    • máy chủ COM dll1.dll phụ thuộc vào dll2.dll
    • dll2.dll không phụ thuộc COM

các đối tượng COM tôi có:

  • trong dll1.dll (ngôn ngữ .idl)

-

[ 
    object, 
    uuid(262D00FB-3B9F-4A76-98FC-3051FDCAF0A6), 
    dual, 
    nonextensible, 
    helpstring("IDialogManager Interface"), 
    pointer_default(unique) 
] 
interface IDialogManager : IDispatch{ 
}; 
[ 
     uuid(58562535-BCA5-4D04-BB92-78F90EDA201E), 
     //... 
] 
dispinterface _IDialogManagerEvents 
{ 
}; 
[ 
     uuid(D599D3F0-A4D1-44A7-87A9-16032CC613CA), 
     //... 
] 
coclass DialogManager 
{ 
     [default] interface IDialogManager; 
     [default, source] dispinterface _IDialogManagerEvents; 
}; 

-

  • trong dll2. dll

-

[ 
    object, 
    uuid(2A183A2E-A620-4E00-B657-C9D2E59201D4), 
    nonextensible, 
    helpstring("ICadWizardsManager Interface"), 
    pointer_default(unique) 
] 
interface ICadWizardsManager : IDispatch{ 
}; 
[ 
    object, 
    uuid(FE97F3FB-8930-43BC-947D-64C90F45A071), 
    nonextensible, 
    helpstring("ICadWizard Interface"), 
    pointer_default(unique) 
] 
interface ICadWizard : IDispatch{ 
}; 
[ 
    uuid(5365D4E6-ADFB-4429-9DEA-C44CC94AA3EF), 
] 
dispinterface _ICadWizardEvents 
{ 
}; 
[ 
    uuid(CAC2D0BF-AD5B-4CC8-A04D-53AB23A0CDF4), 
] 
coclass CadWizard 
{ 
    [default] interface ICadWizard; 
    [default, source] dispinterface _ICadWizardEvents; 
}; 
[ 
    uuid(3164FAC4-6F5F-4E4D-9B09-DC4115850D78), 
] 
dispinterface _ICadWizardsManagerEvents 
{ 
}; 
[ 
    uuid(707CB6C8-311E-45EC-9DCB-50477F588BAF), 
] 
coclass CadWizardsManager 
{ 
    [default] interface ICadWizardsManager; 
    [default, source] dispinterface _ICadWizardsManagerEvents; 
}; 

-

  • cuộc gọi của khách hàng

-

IDialogManagerPtr dialogManager; 
dialogManager.CreateInstance(CLSID_DialogManager); // <<< returns "Class not registered" 

-

0.123.
  • các client.exe.2.manifest

-

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 

<assemblyIdentity name="client" version="1.0.0.0" type="win32" processorArchitecture="x86"/> 
<file name="dll2.dll"> 
<comClass 
    clsid="{707CB6C8-311E-45EC-9DCB-50477F588BAF}" 
    threadingModel="apartment"> 
</comClass> 
<comClass 
    clsid="{CAC2D0BF-AD5B-4CC8-A04D-53AB23A0CDF4}" 
    threadingModel="apartment"> 
</comClass> 
</file> 

<file name="dll1.dll"> 
<comClass 
    clsid="{D599D3F0-A4D1-44A7-87A9-16032CC613CA}" 
    threadingModel="apartment"> 
</comClass> 
</file> 

</assembly> 

-


Tôi không có lỗi trong quá trình SxS hệ bối cảnh kích hoạt: - không có lỗi trong nhật ký cửa sổ (có nghĩa là cú pháp tệp kê khai của tôi là chính xác) - không phát hiện lỗi nào sxstrace (nhật ký kết thúc bằng "INFO: Tạo ngữ cảnh kích hoạt thành công."Thông điệp và không chứa lỗi hoặc thông điệp sucpicious; hơn nữa, tôi thấy rằng biểu hiện của tôi được nạp một cách chính xác)

Bất kỳ ý tưởng

là có một cách để gỡ lỗi SxS sâu hơn rằng với sxstrace nhận được danh sách các thực sự đã đăng ký? com hoặc các lớp học clr ví dụ ???

Cảm ơn bạn bởi trước

+0

Bạn đang triển khai giao diện kép? – wqw

+0

Tôi đã chỉnh sửa bài đăng của mình để thêm định nghĩa idl đầy đủ của IDialogManager, ICadWizardsManager và ICadWizard; đó là các giao diện mà tôi thực hiện – loic

Trả lời

2

Thường có - ít nhất - hai tệp kê khai có liên quan khi xây dựng bối cảnh kích hoạt để đăng ký COM miễn phí.

Có biểu thức EXE, chỉ định các cụm phụ thuộc của nó, bao gồm assembly có chứa các thành phần COM, và có tệp kê khai, mô tả dll, các lớp cửa sổ và các đối tượng COM trong assembly.

This Blog chứa thông tin về ý nghĩa của .2. Về cơ bản, khi hệ thống tìm kiếm một tệp kê khai, nó sẽ tìm kiếm modulename.exe [.resid] .manifest - Trong trường hợp số dư đó là 1, nó bị bỏ qua. Vì vậy, bạn đang sử dụng MFC, có nghĩa là DevStudio, có nghĩa là dự án của bạn đã được cấu hình để tạo ra một tài nguyên RT_MANIFEST tự động với các thiết lập c-runtime và kiểm soát chung 6 trong đó.

Visual Studio 2005 hỗ trợ cú pháp này để kết hợp các yếu tố dependentAssembly với các ứng dụng của bạn biểu hiện mà không cần phải cố gắng và kết hợp XML trực tiếp:

#pragma comment(linker, \ 
    "\"/manifestdependency:type='Win32' "\ 
    "name='client' "\ 
    "version='1.0.0.0' "\ 
    "processorArchitecture='*' "\ 
    "language='*'\"") 

Vì vậy, nếu bạn thêm rằng đến một cpp hoặc tiêu đề trong .exe của bạn, và sau đó lưu client.exe.2.manifest của bạn là "client.manifest", bạn nên là tất cả các hệ thống đi.

6

Lời giải thích đơn giản là rằng file .manifest không được sử dụng. đó là cao khả năng trong trường hợp này, bạn gần như .exe chắc chắn đã chứa một tệp kê khai, được nhúng dưới dạng tài nguyên. Rất phổ biến cho ứng dụng MFC để bật kiểu trực quan. Và đối với mã được biên dịch bởi các trình biên dịch VS2005 hoặc 2008, nhúng một tệp kê khai để tìm các tệp DLL thời gian chạy.

Để xác minh điều này, hãy sử dụng Tệp + Mở + Tệp và chọn tệp .exe đã biên dịch. Tìm nút RT_MANIFEST. Nếu Windows tìm thấy một tệp kê khai được nhúng như vậy, nó sẽ không tiếp tục tìm kiếm tệp dựa trên tệp. Bạn cần phải hợp nhất các mục COM miễn phí của bạn vào một mục nhúng. Tôi ước tôi có thể cung cấp cho bạn một liên kết Thư viện MSDN tốt nhưng các tài liệu về các tệp kê khai hút đá nghiêm trọng.

+3

+1 để có câu trả lời hữu ích; và tôi sẽ cung cấp cho 10 cho "các tài liệu về biểu hiện hút đá nghiêm trọng" :-) –

+0

Điều này có hợp lệ ngay cả khi sxstrace đăng nhập rằng tệp kê khai của tôi đã được phân tích cú pháp chính xác không? – loic

+0

Trong tâm trí của tôi, sxstrace rõ ràng chỉ ra rằng biểu hiện thực sự được sử dụng. Theo tôi hiểu khi tôi theo dõi tải ứng dụng (procmon) Có vẻ như các cửa sổ tìm kiếm client.exe.manifest __if không có RT_MANIFEST res__; nếu không, nó sẽ tìm client.exe.2.manifest. Vì vậy, trong tâm trí của tôi, biểu hiện "bên ngoài" được sử dụng ngay cả khi các tệp kê khai được nhúng tồn tại – loic

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