Is it possible to use regfree COM from registered COM? - com

I've been trying to implement following scenario:
Application [C++] uses CoCreateInstance on registered COM class (CReg/Reg.dll)
CReg class uses CoCreateInstance on regfree/SxS COM class (CFree/Free.dll).
CoCreateInstance returns REGDB_E_CLASSNOTREG.
Problem doesn't seem to be with manifests, because if I try to instantiate CFree directly via application, object is created with no problem.
I have checked and scenario above triggers Activation Context of CReg (I have checked with sxstrace) and even manifest of the CFree is loaded successfully (!) which should effect in correct regfree COM. If I change manifest of the CFree then Activation Contexts fails (which I believe is proof for me that it was correctly triggered and loaded before the change).
Is scenario with using registered COM [CReg] not possible to access CFree object? If it is possible, are there some special work in order to load it properly?
EDIT
With Joe's help, we worked out that the problem is where Free.dll is located.
Main application is (for example) in C:\Proj\App, both Reg.dll and Free.dll are in C:\Proj\Libs. Is there possibility to load regfree Free.dll which is in different location than application? Problem is that I can't place it in application directory or in application child directory (it has to be in external location).
I have tried to use ISOLATION_AWARE_ENABLED preprocessor definition on Reg.dll project, to trigger Activation context from Reg.dll directory. Manifest from Free.dll is loaded properly (sxstrace logs that) but CoCreateInstance call is still returning REGDB_E_CLASSNOTREG. This blog article points that it may be possible with this definition (but is not giving definite answer on this matter).
Anyone can help me solve this problem or at least point to the documentation that may give me an answer, whether it is possible or not, to load regfree dll from an external location?

Related

My registered COM object cannot be ran as InProc

I am using pywin32 to register a COM object. The COM object get registered and it is avaialable in the registry editor at Computer\HKEY_CLASSES_ROOT\CLSID{B7B60366-B784-451F-BD6A-E7E733DB4E63}.
The problem is that the path in InProc32 includes only pythoncom37.dll. The only way can make the object work is to rename the inproc folder, so that it searches for LocalServer by default.
I believe several problems in the behavior of this object are connected to it not being ran as inproc, hence I really want to get it to run as inproc.
Any Ideas why this is the case? What can I do to change it?

Failure in creation of feature class: Unable to create object class extension COM component

I am working with ArcGIS 10.5, installed on-premise, and are developing our feature class in .NET.
I have an issue with registering feature classes. We have created a Feature Class and registered the DLL through “ESRIRegAsm.exe”, and it appears in ArcCatalog:
Trigger appearing image
But when I try to create the Feature Class, I get the following error:
Failed to create feature class. Unable to create object class extension COM Component
Which isn't very helpful, unfortunately.
The odd thing is, that we have another trigger registered on another Feature Class, that works as expected. And the new trigger is based on a copy of the old trigger's code (with changed GUID's).
The steps I have done so far:
I have tried to add the feature class to the component category using categories.exe.
Registered it using ESRIRegAsm.exe for both Desktop and Engine.
Checked that there are .ecfg config files - and there are.
Checked that the CLSID's appear in the windows registry.
The essential parts of our trigger source-code can be found here: here.
Any help would be greatly appreciated, as we are stuck on this.
Our issue was that our ID's were wrong in the code.
The ClassExtensionCLSID should return the same ID as TriggerExtension has.
Moreover, InstanceCLSID should always return 52353152-891A-11D0-BEC6-00805F7C4268, and should hence not get a new ID.

How to register a Property Handler on folders?

I built a virtual filesystem (not a namespace extension) for Windows which acts as a frontend of our document management server consisting of files and folders. In order to be able to display some metadata of the DMS objects in Windows Explorer as additional selectable columns, I successfully provided properties to the Windows Property System by implementing a COM Property Handler. Wheras normal property handlers focus on specific file types for which they feel responsible, my Property Handler adds properties to all files regardless of their type. Because Property Handlers can only be registered on the file type level, I registered my handler for about 30 types under
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\PropertySystem\PropertyHandlers\<.Extension>
However, I did not manage to register the Property Handler for folder objects. Since all objects in our file system are virtual I build the property store (IPropertyStore) by implementing IInitializeWithFile instead of IInitializeWithStream. The properties are requested from our DMS with the path of IInitializeWithFile acting as key and were not read from an objects content. This concept would work for folders as well.
For getting called on folders I tried to associate the handler by registering under different well known identifiers like Folder, Directory, AllFileSystemObjects and * instead of the file extension without success.
I also didn’t find anything in the MSDN documentation regarding this aspect.
Is there a way to register a Windows Property Handler on folders? Or is there some other way to add custom columns to folders in Windows Explorer?
I'm not sure if it is possible to do this.
Property handlers are clearly not the right approach, they are system wide and there can only be one per file extension. They should only be implemented by the software that "owns" the file extension and can parse the file to extract properties.
The old column handlers would have been your best bet (IMHO) but they are officially dead and you already said you can't use them.
Have you considered creating a namespace extension? Either as a root item somewhere (Desktop or My Computer) the way My Documents used to work in 2000/XP or maybe something more along the lines of how OneDrive works?
I'm not sure if desktop.ini files work in the root of a drive but it might be worth looking into. You would then find yourself in the poorly documented land of [.ShellClassInfo] and its CLSID, CLSID2 and UICLSID members. The general idea would be to act as a IShellFolder proxy on top of the "real" IShellFolder so you could create a multiplex property store. I think there are some (undocumented?) property keys you can override to change the folders default columns and tooltips as well.
There is also something called a delegated folder that allows you to play with nested PIDLs but the documentation is once again pretty useless so I'm not sure if this is something worth looking into.
A 3rd option is to pretend to be a cloud storage provider. I don't know if this gets you any closer to your goal and you would still have to implement some NSE bits to get to the point where you can layer yourself on top of the underlying IShellFolder. This feature is rather new and only documented to work on Windows 10.
The inner workings of how Explorer/IShellBrowser is connected to the IShellFolder/IShellView is one of the least documented parts of Windows. There are hundreds of undocumented interfaces. Explorer gives DefView special treatment leaving other 3rd-party implementations out in the cold.
My feeling is that there is no clean solution to implement this on top of a drive letter but you might get lucky, if Raymond Chen drops by he might have some tips for you...

EntLib 5 Wrap Handler Message Localization

I have been asked, at very short notice of course, to implement exception logging to the Windows Application event Log in one of our products (vb.Net, framework 3.5, WinForms) using EntLib 5. In and of itself this is fine - I can get that working. However, this is for a client who wants messages in Chinese. Certain parts of the app have language resource files and I found a couple of sentences in my MS EntLib Developers Guide book which suggested that I could use an external resource to provide a localised 'friendly' message in a wrap handler within the Exception Handling Block.
Unfortunately there was no mention of how to actually achieve this but it seemed straightforward enough. I added a new resource to a resx file which lives at the project level for the project which is common to all areas of the application and re-built to project so that the satellite assemblies were built. I then specified the name of the resource in the 'Message Resource Name' field within the EntLib configuration console. the problem arises when I try and specify the 'Message Resource Type'.
I clicked on the search button and found the satellite assembly I needed, but it did not get added to the list of loaded assemblies and therefore I couldn't select it. The problem is that none of the places where I've seen this feature mentioned actually demonstrate how to get it working so I'm not sure where I'm going wrong. The search for the assembly will only let me select a dll or exe so I assume I am supposed to reference the satellite assembly somehow but how do I do this if it won't add it to the list of loaded assemblies?
One point to note is that we have a main executable which then calls numerous class libraries to load areas of functionality as required, and the config file we use throughout is the one which belongs to the main executable. Is it the case that you can only use satellite assemblies which are related to the assembly that the config file belongs to?
I haven't yet fully utilized this feature yet but just something to check, are you using the fully qualified name of the assembly?
EDIT: A potentially applicable link - http://entlib.codeplex.com/discussions/67460

Tracking COM object error in application

I was using an application and it was working perfect. After some months of not using it, I tried to run it and it doesn't work. It shows a message box saying that it cannot instance a COM object.
Do any know how to track errors in COM objects?
You can use ProcessMonitor and try to find the registry key that may be incorrect.
The other option is to use http://www.moduleanalyzer.com, it intercepts CoCreateInstance showing all created COM objects and the return values.
Run Depends tool on COM object DLL to verify it has all the necessary dlls, re-register the COM dll/exe.
Any HRESULTS from debugging/logs? Any changes in apartment models?
You cannot change the apartment type once you've set one. So if the object cannot use one of the models and you try to CoCreate it, it will fail. That's why you never call CoInit from inside DLL main thread.