How to call Registeration-Free COM dll?
-
Found another code snippet for COM debugging, insert this just before that failing call ..GetTypeInfo():
// insert this code right after retrieving the ITypeInfo ptr // check that GetIDsOfNames works // QString unicodeName = "Clone"; // use this one for IEventData QString unicodeName = "Deserialize"; // use this one for IErrorMessageData OLECHAR *name = reinterpret_cast<wchar_t *>(const_cast<ushort *>(unicodeName.utf16())); DISPID dispid = 0; hr = pDispatch->GetIDsOfNames(IID_NULL,&name,1,LOCALE_SYSTEM_DEFAULT,&dispid); if (FAILED(hr)) qFatal() << "Error: GetIDsOfNames() failed" << QString::number((uint) hr,16); qDebug() << "ok, dispid =" << dispid; // old code CComPtr<ITypeInfo> pTypeInfo; ...
You could try this both for the coclass ErrorMessageData or if you flip the comments: for coclass EventData.
Also: to make clear what's failing:
-
On your development PC where the DataTypesLibrary.dll is visible in the registry everything works, both my old debugging code (i.e. GetTypeInfo()) and generateDocumentation(), right?
-
On the target PC without any stuff in the registry GetTypeInfo() and generateDocumentation() both fails.
P.S. Pls have another go at ProcessMonitor, a trick I use is to insert a call to QMessageBox just before the code to trace, like this:
QMessageBox msgBox; msgBox.setText("Start Procmon now..."); msgBox.exec();
(don't forget to #include "QMessageBox" :-)
-
-
Found another code snippet for COM debugging, insert this just before that failing call ..GetTypeInfo():
// insert this code right after retrieving the ITypeInfo ptr // check that GetIDsOfNames works // QString unicodeName = "Clone"; // use this one for IEventData QString unicodeName = "Deserialize"; // use this one for IErrorMessageData OLECHAR *name = reinterpret_cast<wchar_t *>(const_cast<ushort *>(unicodeName.utf16())); DISPID dispid = 0; hr = pDispatch->GetIDsOfNames(IID_NULL,&name,1,LOCALE_SYSTEM_DEFAULT,&dispid); if (FAILED(hr)) qFatal() << "Error: GetIDsOfNames() failed" << QString::number((uint) hr,16); qDebug() << "ok, dispid =" << dispid; // old code CComPtr<ITypeInfo> pTypeInfo; ...
You could try this both for the coclass ErrorMessageData or if you flip the comments: for coclass EventData.
Also: to make clear what's failing:
-
On your development PC where the DataTypesLibrary.dll is visible in the registry everything works, both my old debugging code (i.e. GetTypeInfo()) and generateDocumentation(), right?
-
On the target PC without any stuff in the registry GetTypeInfo() and generateDocumentation() both fails.
P.S. Pls have another go at ProcessMonitor, a trick I use is to insert a call to QMessageBox just before the code to trace, like this:
QMessageBox msgBox; msgBox.setText("Start Procmon now..."); msgBox.exec();
(don't forget to #include "QMessageBox" :-)
@hskoglund I tried the below steps on my PC.
First, I added the code and it still failed with 0x8002801D error.
Below is the log from Process Monitor when exec this line of code:
hr = pDispatch->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_SYSTEM_DEFAULT, &dispid);
I add filter operation must starts with "Reg"
5:29:48.3317575 PM TestRegFreeCOM.exe 18844 RegOpenKey HKLM\Software\Microsoft\Rpc\Extensions SUCCESS Desired Access: Read 5:29:48.3317744 PM TestRegFreeCOM.exe 18844 RegQueryValue HKLM\SOFTWARE\Microsoft\Rpc\Extensions\NdrOleExtDLL SUCCESS Type: REG_EXPAND_SZ, Length: 24, Data: combase.dll 5:29:48.3317924 PM TestRegFreeCOM.exe 18844 RegCloseKey HKLM\SOFTWARE\Microsoft\Rpc\Extensions SUCCESS 5:29:48.3318212 PM TestRegFreeCOM.exe 18844 RegQueryKey HKLM SUCCESS Query: HandleTags, HandleTags: 0x0 5:29:48.3318302 PM TestRegFreeCOM.exe 18844 RegOpenKey HKLM\Software\Microsoft\Rpc SUCCESS Desired Access: Read 5:29:48.3318419 PM TestRegFreeCOM.exe 18844 RegQueryValue HKLM\SOFTWARE\Microsoft\Rpc\MaxRpcSize NAME NOT FOUND Length: 16 5:29:48.3318539 PM TestRegFreeCOM.exe 18844 RegCloseKey HKLM\SOFTWARE\Microsoft\Rpc SUCCESS 5:29:48.3318905 PM TestRegFreeCOM.exe 18844 RegOpenKey HKLM\System\CurrentControlSet\Services\CCG REPARSE Desired Access: Read 5:29:48.3319008 PM TestRegFreeCOM.exe 18844 RegOpenKey HKLM\System\CurrentControlSet\Services\CCG NAME NOT FOUND Desired Access: Read 5:29:48.3319106 PM TestRegFreeCOM.exe 18844 RegOpenKey HKLM\System\CurrentControlSet\Services\CCG REPARSE Desired Access: Read 5:29:48.3319179 PM TestRegFreeCOM.exe 18844 RegOpenKey HKLM\System\CurrentControlSet\Services\CCG NAME NOT FOUND Desired Access: Read 5:29:48.3319285 PM TestRegFreeCOM.exe 18844 RegOpenKey HKLM\System\CurrentControlSet\Control\ComputerName\ActiveComputerName REPARSE Desired Access: Read 5:29:48.3319360 PM TestRegFreeCOM.exe 18844 RegOpenKey HKLM\System\CurrentControlSet\Control\ComputerName\ActiveComputerName SUCCESS Desired Access: Read 5:29:48.3319458 PM TestRegFreeCOM.exe 18844 RegQueryValue HKLM\System\CurrentControlSet\Control\ComputerName\ActiveComputerName\ComputerName SUCCESS Type: REG_SZ, Length: 32, Data: DESKTOP-1AJB9L5 5:29:48.3319577 PM TestRegFreeCOM.exe 18844 RegCloseKey HKLM\System\CurrentControlSet\Control\ComputerName\ActiveComputerName SUCCESS 5:29:48.3319648 PM TestRegFreeCOM.exe 18844 RegOpenKey HKLM\System\Setup SUCCESS Desired Access: Read 5:29:48.3319726 PM TestRegFreeCOM.exe 18844 RegQueryValue HKLM\SYSTEM\Setup\OOBEInProgress SUCCESS Type: REG_DWORD, Length: 4, Data: 0 5:29:48.3319826 PM TestRegFreeCOM.exe 18844 RegCloseKey HKLM\SYSTEM\Setup SUCCESS 5:29:48.3319892 PM TestRegFreeCOM.exe 18844 RegOpenKey HKLM\System\Setup SUCCESS Desired Access: Read 5:29:48.3319963 PM TestRegFreeCOM.exe 18844 RegQueryValue HKLM\SYSTEM\Setup\SystemSetupInProgress SUCCESS Type: REG_DWORD, Length: 4, Data: 0 5:29:48.3320058 PM TestRegFreeCOM.exe 18844 RegCloseKey HKLM\SYSTEM\Setup SUCCESS 5:29:48.3320151 PM TestRegFreeCOM.exe 18844 RegOpenKey HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\TestRegFreeCOM.exe NAME NOT FOUND Desired Access: Query Value, Enumerate Sub Keys 5:29:48.3320658 PM TestRegFreeCOM.exe 18844 RegQueryKey HKLM SUCCESS Query: HandleTags, HandleTags: 0x0 5:29:48.3320726 PM TestRegFreeCOM.exe 18844 RegOpenKey HKLM\Software\Policies\Microsoft\Windows NT\Rpc NAME NOT FOUND Desired Access: Read 5:29:48.3320858 PM TestRegFreeCOM.exe 18844 RegQueryKey HKLM BUFFER TOO SMALL Query: Name, Length: 0 5:29:48.3320930 PM TestRegFreeCOM.exe 18844 RegQueryKey HKLM SUCCESS Query: Name 5:29:48.3321016 PM TestRegFreeCOM.exe 18844 RegOpenKey HKLM\SOFTWARE\Microsoft\AppModel\Lookaside\machine\Software\Policies\Microsoft\Windows NT\Rpc NAME NOT FOUND Desired Access: Read 5:29:48.3321373 PM TestRegFreeCOM.exe 18844 RegQueryKey HKLM SUCCESS Query: HandleTags, HandleTags: 0x0 5:29:48.3321441 PM TestRegFreeCOM.exe 18844 RegOpenKey HKLM\Software\Microsoft\Rpc SUCCESS Desired Access: Query Value 5:29:48.3321531 PM TestRegFreeCOM.exe 18844 RegQueryValue HKLM\SOFTWARE\Microsoft\Rpc\IdleTimerWindow NAME NOT FOUND Length: 16 5:29:48.3321639 PM TestRegFreeCOM.exe 18844 RegCloseKey HKLM\SOFTWARE\Microsoft\Rpc SUCCESS 5:29:48.3322149 PM TestRegFreeCOM.exe 18844 RegOpenKey HKCU\Software\Classes SUCCESS Desired Access: Maximum Allowed, Granted Access: All Access 5:29:48.3322969 PM TestRegFreeCOM.exe 18844 RegQueryKey HKLM SUCCESS Query: HandleTags, HandleTags: 0x0 5:29:48.3323035 PM TestRegFreeCOM.exe 18844 RegOpenKey HKLM\Software\Microsoft\COM3 SUCCESS Desired Access: Read 5:29:48.3323143 PM TestRegFreeCOM.exe 18844 RegSetInfoKey HKLM\SOFTWARE\Microsoft\COM3 SUCCESS KeySetInformationClass: KeySetHandleTagsInformation, Length: 0 5:29:48.3323280 PM TestRegFreeCOM.exe 18844 RegQueryValue HKLM\SOFTWARE\Microsoft\COM3\Com+Enabled SUCCESS Type: REG_DWORD, Length: 4, Data: 1 5:29:48.3323389 PM TestRegFreeCOM.exe 18844 RegCloseKey HKLM\SOFTWARE\Microsoft\COM3 SUCCESS 5:29:48.3340202 PM TestRegFreeCOM.exe 18844 RegOpenKey HKCR\PackagedCom SUCCESS Desired Access: Read 5:29:48.3340360 PM TestRegFreeCOM.exe 18844 RegOpenKey HKCR\PackagedCom\TypeLibIndex NAME NOT FOUND Desired Access: Read 5:29:48.3340657 PM TestRegFreeCOM.exe 18844 RegOpenKey HKCU\Software\Classes SUCCESS Desired Access: Maximum Allowed, Granted Access: All Access 5:29:48.3340779 PM TestRegFreeCOM.exe 18844 RegQueryKey HKCU\Software\Classes SUCCESS Query: Name 5:29:48.3340872 PM TestRegFreeCOM.exe 18844 RegQueryKey HKCU\Software\Classes SUCCESS Query: HandleTags, HandleTags: 0x0 5:29:48.3340935 PM TestRegFreeCOM.exe 18844 RegQueryKey HKCU\Software\Classes SUCCESS Query: HandleTags, HandleTags: 0x0 5:29:48.3341005 PM TestRegFreeCOM.exe 18844 RegOpenKey HKCU\Software\Classes\TypeLib SUCCESS Desired Access: Maximum Allowed, Granted Access: All Access 5:29:48.3341120 PM TestRegFreeCOM.exe 18844 RegCloseKey HKCU\Software\Classes SUCCESS 5:29:48.3341200 PM TestRegFreeCOM.exe 18844 RegQueryKey HKCU\Software\Classes\TypeLib SUCCESS Query: Name 5:29:48.3341280 PM TestRegFreeCOM.exe 18844 RegQueryKey HKCU\Software\Classes\TypeLib SUCCESS Query: HandleTags, HandleTags: 0x0 5:29:48.3341335 PM TestRegFreeCOM.exe 18844 RegQueryKey HKCU\Software\Classes\TypeLib SUCCESS Query: HandleTags, HandleTags: 0x0 5:29:48.3341406 PM TestRegFreeCOM.exe 18844 RegOpenKey HKCU\Software\Classes\TypeLib\{A9D4AEA1-46D8-4E98-B9AA-BE93A21A58AD} NAME NOT FOUND Desired Access: Maximum Allowed 5:29:48.3341502 PM TestRegFreeCOM.exe 18844 RegOpenKey HKCR\TypeLib\{A9D4AEA1-46D8-4E98-B9AA-BE93A21A58AD} NAME NOT FOUND Desired Access: Maximum Allowed 5:29:48.3341673 PM TestRegFreeCOM.exe 18844 RegQueryKey HKCU\Software\Classes\TypeLib BUFFER TOO SMALL Query: Name, Length: 0 5:29:48.3341740 PM TestRegFreeCOM.exe 18844 RegQueryKey HKCU\Software\Classes\TypeLib SUCCESS Query: Name 5:29:48.3341847 PM TestRegFreeCOM.exe 18844 RegOpenKey HKLM\SOFTWARE\Microsoft\AppModel\Lookaside\user\software\Classes\TypeLib\{A9D4AEA1-46D8-4E98-B9AA-BE93A21A58AD} NAME NOT FOUND Desired Access: Read 5:29:48.3341984 PM TestRegFreeCOM.exe 18844 RegCloseKey HKCU\Software\Classes\TypeLib SUCCESS 5:29:48.3345887 PM TestRegFreeCOM.exe 18844 RegCloseKey HKCU\Software\Classes SUCCESS
Second, After I registered the DLL like this:
regsvr32 xxx.dll
Then everything goes fine.
-
-
Hi, I had written a post above where I more or less gave up, but I made another effort!
It turns out that that ancient Qt enhancement suggestion speaking about manifest files wasn't completely science-fiction. I found this MSDN article and of course some StackOverflow posts helped a lot.
Thanks to your ProcMon trace above we can see it haplessly looking for DataTypesLibrary.dll's type library in the registry. By adding manifest files we can provide a path to that type library.
Actually we need two manifest files. The first you'll add to your TestRegFreeCOM.exe. I'm assuming you're using MSVC 64-bits compiler and ..pro file (not CMake).
Qt already adds an .rc file to your .exe so we also need to remove that (there can only be one manifest). Add this to your TestRegFreeCOM.pro:CONFIG -= embed_manifest_exe QMAKE_MANIFEST = $$PWD/TestRegFreeCOM.exe.manifest
then create a text file TestRegFreeCOM.exe.manifest in your project dir with this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <dependency> <dependentAssembly> <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" publicKeyToken="6595b64144ccf1df" language="*" processorArchitecture="*" /> </dependentAssembly> </dependency> <dependency> <dependentAssembly> <assemblyIdentity name="DataTypesLibrary.X" version="1.0.0.0" type="win32" language="*" processorArchitecture="*" /> </dependentAssembly> </dependency> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> <security> <requestedPrivileges> <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel> </requestedPrivileges> </security> </trustInfo> </assembly>
most of the contents is because we're replacing the Qt standard manifest with our own. The relevant part is where we add a dependentAssembly for the DataTypesLibrary. I think the old MSDN article I mentioned above started this trend of suffixing an .X, don't worry it works :-)
The second manifest file is for the DataTypesLibrary.dll, create a text file called DataTypesLibrary.X.manifest with this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <assemblyIdentity name="DataTypesLibrary.X" version="1.0.0.0" type="win32" processorArchitecture="AMD64" /> <file name="DataTypesLibrary.dll"> <comClass progid="EventData" clsid="{0405e972-093d-4f16-9b4f-f9071cc8f9b2}" threadingModel = "Apartment" /> <typelib tlbid="{A9D4AEA1-46D8-4E98-B9AA-BE93A21A58AD}" version="1.0" helpdir="" /> </file> </assembly>
then put the DataTypesLibrary.X.manifest and DataTypesLibrary.dll both in the same directory as TestRegFreeCOM.exe.
To test, try something like:
auto comObject = new QAxObject("EventData"); qDebug() << comObject->generateDocumentation();
If it fails, you can trace the manifest fiddling with the SXSTrace.exe tool, step 1, start the trace in a separate CMD window:
sxstrace trace -logfile:sxstrace
irun TestRegFreeCOM.exe and press Enter to stop the trace
step 2: decode the trace
sxxtrace parse -logfile:sxstrace -outfile:trace.txt
then you can type trace.txtIf this works for you, you owe me a beer :-))
-
Hi, I had written a post above where I more or less gave up, but I made another effort!
It turns out that that ancient Qt enhancement suggestion speaking about manifest files wasn't completely science-fiction. I found this MSDN article and of course some StackOverflow posts helped a lot.
Thanks to your ProcMon trace above we can see it haplessly looking for DataTypesLibrary.dll's type library in the registry. By adding manifest files we can provide a path to that type library.
Actually we need two manifest files. The first you'll add to your TestRegFreeCOM.exe. I'm assuming you're using MSVC 64-bits compiler and ..pro file (not CMake).
Qt already adds an .rc file to your .exe so we also need to remove that (there can only be one manifest). Add this to your TestRegFreeCOM.pro:CONFIG -= embed_manifest_exe QMAKE_MANIFEST = $$PWD/TestRegFreeCOM.exe.manifest
then create a text file TestRegFreeCOM.exe.manifest in your project dir with this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <dependency> <dependentAssembly> <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" publicKeyToken="6595b64144ccf1df" language="*" processorArchitecture="*" /> </dependentAssembly> </dependency> <dependency> <dependentAssembly> <assemblyIdentity name="DataTypesLibrary.X" version="1.0.0.0" type="win32" language="*" processorArchitecture="*" /> </dependentAssembly> </dependency> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> <security> <requestedPrivileges> <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel> </requestedPrivileges> </security> </trustInfo> </assembly>
most of the contents is because we're replacing the Qt standard manifest with our own. The relevant part is where we add a dependentAssembly for the DataTypesLibrary. I think the old MSDN article I mentioned above started this trend of suffixing an .X, don't worry it works :-)
The second manifest file is for the DataTypesLibrary.dll, create a text file called DataTypesLibrary.X.manifest with this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <assemblyIdentity name="DataTypesLibrary.X" version="1.0.0.0" type="win32" processorArchitecture="AMD64" /> <file name="DataTypesLibrary.dll"> <comClass progid="EventData" clsid="{0405e972-093d-4f16-9b4f-f9071cc8f9b2}" threadingModel = "Apartment" /> <typelib tlbid="{A9D4AEA1-46D8-4E98-B9AA-BE93A21A58AD}" version="1.0" helpdir="" /> </file> </assembly>
then put the DataTypesLibrary.X.manifest and DataTypesLibrary.dll both in the same directory as TestRegFreeCOM.exe.
To test, try something like:
auto comObject = new QAxObject("EventData"); qDebug() << comObject->generateDocumentation();
If it fails, you can trace the manifest fiddling with the SXSTrace.exe tool, step 1, start the trace in a separate CMD window:
sxstrace trace -logfile:sxstrace
irun TestRegFreeCOM.exe and press Enter to stop the trace
step 2: decode the trace
sxxtrace parse -logfile:sxstrace -outfile:trace.txt
then you can type trace.txtIf this works for you, you owe me a beer :-))
@hskoglund This really works now. That's very kind of you. Pretty much thanks. I owe you a beer^_^.
-
B Bruce.Zhang has marked this topic as solved on
-
Hi, I had written a post above where I more or less gave up, but I made another effort!
It turns out that that ancient Qt enhancement suggestion speaking about manifest files wasn't completely science-fiction. I found this MSDN article and of course some StackOverflow posts helped a lot.
Thanks to your ProcMon trace above we can see it haplessly looking for DataTypesLibrary.dll's type library in the registry. By adding manifest files we can provide a path to that type library.
Actually we need two manifest files. The first you'll add to your TestRegFreeCOM.exe. I'm assuming you're using MSVC 64-bits compiler and ..pro file (not CMake).
Qt already adds an .rc file to your .exe so we also need to remove that (there can only be one manifest). Add this to your TestRegFreeCOM.pro:CONFIG -= embed_manifest_exe QMAKE_MANIFEST = $$PWD/TestRegFreeCOM.exe.manifest
then create a text file TestRegFreeCOM.exe.manifest in your project dir with this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <dependency> <dependentAssembly> <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" publicKeyToken="6595b64144ccf1df" language="*" processorArchitecture="*" /> </dependentAssembly> </dependency> <dependency> <dependentAssembly> <assemblyIdentity name="DataTypesLibrary.X" version="1.0.0.0" type="win32" language="*" processorArchitecture="*" /> </dependentAssembly> </dependency> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> <security> <requestedPrivileges> <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel> </requestedPrivileges> </security> </trustInfo> </assembly>
most of the contents is because we're replacing the Qt standard manifest with our own. The relevant part is where we add a dependentAssembly for the DataTypesLibrary. I think the old MSDN article I mentioned above started this trend of suffixing an .X, don't worry it works :-)
The second manifest file is for the DataTypesLibrary.dll, create a text file called DataTypesLibrary.X.manifest with this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <assemblyIdentity name="DataTypesLibrary.X" version="1.0.0.0" type="win32" processorArchitecture="AMD64" /> <file name="DataTypesLibrary.dll"> <comClass progid="EventData" clsid="{0405e972-093d-4f16-9b4f-f9071cc8f9b2}" threadingModel = "Apartment" /> <typelib tlbid="{A9D4AEA1-46D8-4E98-B9AA-BE93A21A58AD}" version="1.0" helpdir="" /> </file> </assembly>
then put the DataTypesLibrary.X.manifest and DataTypesLibrary.dll both in the same directory as TestRegFreeCOM.exe.
To test, try something like:
auto comObject = new QAxObject("EventData"); qDebug() << comObject->generateDocumentation();
If it fails, you can trace the manifest fiddling with the SXSTrace.exe tool, step 1, start the trace in a separate CMD window:
sxstrace trace -logfile:sxstrace
irun TestRegFreeCOM.exe and press Enter to stop the trace
step 2: decode the trace
sxxtrace parse -logfile:sxstrace -outfile:trace.txt
then you can type trace.txtIf this works for you, you owe me a beer :-))
@hskoglund Sorry for bother you again. I had other COM dlls written in CSharp. I picked one to operate via dumpcpp, but if I generate .h only using " --nometaobject", then will have link errors. but will succeed when generating both .h and cpp.
The tlb and manifest files as follows:
https://drive.google.com/file/d/1-2240-43cqiw-rmdVIJvBKnMedPGCKau/view?usp=sharinghttps://drive.google.com/file/d/1WoWapdes613jN86Eoy6EnrfXL-0fXWax/view?usp=sharing
https://drive.google.com/file/d/1p20BSfeuuFCaFUmhfRZi6lnurLlVBO3x/view?usp=sharing
-
Do you need to use dumpcpp?
I think if you just write the manifest files using the .idl and try with the usual:auto comObject = new QAxObject("RecipeManagement"); qDebug() << comObject->generateDocumentation();
then you should be able to use QAxObject's dynamicall() and setProperty() etc. instead.
-
Do you need to use dumpcpp?
I think if you just write the manifest files using the .idl and try with the usual:auto comObject = new QAxObject("RecipeManagement"); qDebug() << comObject->generateDocumentation();
then you should be able to use QAxObject's dynamicall() and setProperty() etc. instead.
@hskoglund said in How to call Registeration-Free COM dll?:
");
I choose dumpcpp just because it seems very convenient to do this, I don't need to remember each property.
As C# COM dll doesn't has "DllGetClassObject", I could only call QLibrary("RecipeManagement.dll")->Load();
After that if I exec below code, then failed.
auto comObject = new QAxObject("RecipeManagement"); qDebug() << comObject->generateDocumentation(); The outputs: onecore\com\combase\catalog\catalog.cxx(2394)\combase.dll!00007FFD5C9EEFD0: (caller: 00007FFD5C934E30) ReturnHr(1) tid(518c) 800401F3 Invalid class string onecore\com\combase\dcomrem\resolver.cxx(2299)\combase.dll!00007FFD5C8AE3BD: (caller: 00007FFD5C8AB2AE) ReturnHr(2) tid(518c) 80040154 Class not registered onecore\com\combase\dcomrem\resolver.cxx(2507)\combase.dll!00007FFD5C8AB2D6: (caller: 00007FFD5C8ADC25) ReturnHr(3) tid(518c) 80040154 Class not registered CoCreateInstance failure (Class not registered) QAxBase::setControl: requested control RecipeManagement could not be instantiated "" It was the same error if using "comObject = new QAxObject("RecipeManagement.SystemSettings");" or other name declared in manifest.
Although I can run using .h&.cpp generated by dumpcpp. but there will pop up error if I debug into it.
If I just run the exe, will not popup any error dialog, and I can get correct output of
qDebug() << recipe.GetAsJSON(); -
Hi, just to make sure, you're not still doing those calls? like
... HRESULT hr = regFreeGetDllClassObject(... // and hr = pClassFactory->CreateInstance(.. etc.
with manifest files you just need
auto comObject = new QAxObject("RecipeManagement");which should be equivalent to using the .h & .cpp files generated by dumpcpp. I.e. if new QAxObject(..) fails then .h & .cpp files from dumpcpp should fail also (and the other way around).
-
Hi, just to make sure, you're not still doing those calls? like
... HRESULT hr = regFreeGetDllClassObject(... // and hr = pClassFactory->CreateInstance(.. etc.
with manifest files you just need
auto comObject = new QAxObject("RecipeManagement");which should be equivalent to using the .h & .cpp files generated by dumpcpp. I.e. if new QAxObject(..) fails then .h & .cpp files from dumpcpp should fail also (and the other way around).
@hskoglund said in How to call Registeration-Free COM dll?:
RecipeManagement
Hi, sorry for late reply,
I didn't use below code snipet, as DllClassObject didn't exists in C# dll.HRESULT hr = regFreeGetDllClassObject(...
After I exec
auto comObject = new QAxObject("RecipeManagement"); qDebug() << comObject->generateDocumentation();
Error message as follows:
onecore\com\combase\catalog\catalog.cxx(2394)\combase.dll!00007FFF9549EFD0: (caller: 00007FFF953E4E30) ReturnHr(1) tid(1454) 800401F3 Invalid class string onecore\com\combase\dcomrem\resolver.cxx(2299)\combase.dll!00007FFF9535E3BD: (caller: 00007FFF9535B2AE) ReturnHr(2) tid(1454) 80040154 Class not registered onecore\com\combase\dcomrem\resolver.cxx(2507)\combase.dll!00007FFF9535B2D6: (caller: 00007FFF9535DC25) ReturnHr(3) tid(1454) 80040154 Class not registered CoCreateInstance failure (Class not registered) QAxBase::setControl: requested control RecipeManagement could not be instantiated ""
-
Hi, I looked at your RecipeManagement.manifest file, at the top I think it lacks the processorArchitecture, i.e. try changing to this:
... <assemblyIdentity name="RecipeManagement" version="1.0.0.0" processorArchitecture="msil" /> ...
and make sure the manifest file is linked/embedded into the RecipeManagement.dll (you can use mt.exe to check).
Also, you can always use sxstrace to trace, place a QMessageBox just before
auto comObject = new QAxObject("RecipeManagement")
;
(see my sxstrace instructions above) -
Hi, I looked at your RecipeManagement.manifest file, at the top I think it lacks the processorArchitecture, i.e. try changing to this:
... <assemblyIdentity name="RecipeManagement" version="1.0.0.0" processorArchitecture="msil" /> ...
and make sure the manifest file is linked/embedded into the RecipeManagement.dll (you can use mt.exe to check).
Also, you can always use sxstrace to trace, place a QMessageBox just before
auto comObject = new QAxObject("RecipeManagement")
;
(see my sxstrace instructions above)@hskoglund The error code still the same.
The output file of sxstrace parse is empty.and here is the XML of exe:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <dependency> <dependentAssembly> <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" publicKeyToken="6595b64144ccf1df" language="*" processorArchitecture="*"></assemblyIdentity> </dependentAssembly> </dependency> <dependency> <dependentAssembly> <assemblyIdentity name="DataTypesLibrary" version="1.0.0.0" type="win32" language="*"></assemblyIdentity> </dependentAssembly> </dependency> <dependency> <dependentAssembly> <assemblyIdentity name="RecipeManagement" version="1.0.0.0" type="win32" language="*"></assemblyIdentity> </dependentAssembly> </dependency> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> <security> <requestedPrivileges> <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel> </requestedPrivileges> </security> </trustInfo> </assembly>
-
Hi, the XML/manifest for the .exe, you forgot the "X" - suffix, it is necessary for reg-free COM to work, try change the XML to:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <dependency> <dependentAssembly> <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" publicKeyToken="6595b64144ccf1df" language="*" processorArchitecture="*"></assemblyIdentity> </dependentAssembly> </dependency> <dependency> <dependentAssembly> <assemblyIdentity name="DataTypesLibrary.X" version="1.0.0.0" type="win32" language="*" processorArchitecture="*"></assemblyIdentity> </dependentAssembly> </dependency> <dependency> <dependentAssembly> <assemblyIdentity name="RecipeManagement.X" version="1.0.0.0" type="win32" language="*" processorArchitecture="*"></assemblyIdentity> </dependentAssembly> </dependency> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> <security> <requestedPrivileges> <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel> </requestedPrivileges> </security> </trustInfo> </assembly>
You already have a DataTypesLibrary.X.manifest file that works the DataTypesLibrary.dll written in C++
I think you should try the same with your C# RecipeManagement.dll, i.e. create a RecipeManagement.X.manifest file with something like this in it:<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <assemblyIdentity name="RecipeManagement.X" version="1.0.0.0" type="win32" processorArchitecture="msil" /> <file name="RecipeManagement.dll"> <clrClass clsid="{B0AFB6EB-67CB-457E-8709-B6384B02558B}" threadingModel="Both" name="RecipeManagement.SystemSettings" runtimeVersion="v4.0.30319" /> <comClass progid="RecipeManagement.SystemSettings" clsid="{B0AFB6EB-67CB-457E-8709-B6384B02558B}" threadingModel = "Apartment" /> </file> </assembly>
I'm just guessing, but try first with a separate RecipeManagement.X.manifest file (not embedded in the .dll) with the above contents. Also I don't know if <clrClass> should be inside or outside the <filename XML line, you could try both.
Note that you also need the <typelib tlibid=xxx XML inside the <file.. (see my example above for the DataTypesLibrary.X.manifest) but that you can do a later step.About the empty sxstrace trace.txt log file, yes sometimes it doesn't work and gives an empty log file, try logging in/out or rebooting your PC. When it works it will show traces for other ,exe files like edge,exe as well so you'll have to scroll/search for your file.
Note: there's a typing error above, here are the commands again:sxstrace trace -logfile:sxstrace sxstrace parse -logfile:sxstrace -outfile:trace.txt