PDA

View Full Version : SOLUTION : ActiveX EXE registration FAILS in Basic MSI project



Ih8stupidrules
01-28-2015, 02:33 PM
In a new version of our msi install kit, our ActiveX EXE would not register properly, neither using the COM Extract method, nor the SelfReg method.

I've found the solution to these problems and thought it might be useful for others to know what I now know about this, without having to muck around like I did.

First issue: Failure to register an Active X EXE using Self Reg, with Error 1904 Module failed to register, HRESULT -2147024769 during install.


This was caused by having selected, in Tools/Options/Preferences/Self-Registration, "Windows Installer Self-Registration table (SelfReg)" instead of "InstallShield Self-Registration table (ISSelfReg)".
Fix: Select "InstallShield Self-Registration table (ISSelfReg)".
Cause: the native Windows Installer SelfReg method does not handle EXE files, only DLL/OCX files.
It would have been a major timesaver if the IS2014 IDE warned of such an issue when selecting the self-reg option on a file... :mad:


Second issue: Using COM Extract at build on same ActiveX EXE results in unusable component - the application crashes when trying to use it.


This was caused by building the msi package on a 32 bit OS, and installing that package on a 64 bit OS. (Presumably, installing on a 32 bit OS would work).
Fix: build msi package on 64 bit OS.
Cause: When building on a 32 bit OS, the resulting COM Extraction is missing ONE critical registry key for each public interface (class) :
Under "[HKEY_CLASSES_ROOT\Interface\{your interface GUID}\TypeLib]", the default value is missing.
Under a 64 bit OS, that default value is a GUID referring to [HKEY_CLASSES_ROOT\TypeLib\{your component TypelibGUID}], and it seems to trigger the required registry 32/64 reflection required for the component to work.


Manually maintaining those registration entries would be completely unfeasible as we have hundreds of ActiveX components and many change at every build, hence we need to use the COM Extract at build option - trying the Self-Reg method was a last resort to try to solve this issue. Strangely, these problems affect only ActiveX EXEs, but not DLLs or OCXs.

I hope this information will save some time for others!

NeilHayes
01-29-2015, 05:34 AM
If you're using these controls in your own application a better way to manage this (In my view) is not to ever register the ActiveX controls but rather manifest them in your main executable.

Obviously I have no knowledge of your application and it might not be possible.

Benefits......no hassles doing the install you just put the files down, make sure you mark them in your install as not COM so you don't get a COM extraction (or an attempt at one).
You keep the registry nice and clean.

You can use MT.EXE to inject a manifest into an executable. Just google MT.EXE MSDN.

Just an idea!

Neil

Ih8stupidrules
01-29-2015, 11:10 AM
I had considered trying the "Reg free" approach, but it got complicated quickly.

With several hundreds EXE/DLL/OCX, trying to get our main (entry point) application Reg free did not work, and automating the entire process seemed complicated too, so I did not pursue that solution. Admittedly, I was the only one trying to Reg free our app, and I had no previous Reg free knowledge, it's quite possible I goofed up.

It's something I'd like to reconsider sometime in the future though. TBH, I'd rather we migrate our application to C# and not have to deal with COM anymore, but re-coding and re-engineering our entire application to C# is unfortunately not possible...

What are the downsides to going Reg free? Any performance hit? What happens if some ActiveXs get registered, does it break the Reg free?

NeilHayes
01-29-2015, 11:20 PM
First manifesting your application has nothing to changing your code to C# and you don't just want to start converting your code to C# for only a year later to still have exactly the same functionality as you did before. If your code base is working for you then stay with it.

There is no downside.......only an upside.

I have to manifest controls made by codejock into our executables, so how do I go about it?

I use Visual Studio (You could use the Express Version) and create a dummy Winform project, onto the form I drag the required OCX controls but mark them as "isolated", this tells Visual Studio to create a manifest. SO you start hunting down your project sub folder to locate it.

I then edit the manifest, for example the codejock control I want the exe to use are in the applications subfolder called controls.I also take out the checksum information as on occasion we have had a fixed version of the codejock control where the version number has not been changed but the file size has.

</file>
<file name=".\Controls\Codejock.PropertyGrid.v16.3.1.ocx">
<typelib tlbid="{5b44ec52-b95b-45cf-98ff-a49dfeed5a92}" version="16.3" helpdir="" resourceid="0" flags="CONTROL,HASDISKIMAGE" />
<comClass clsid="{e541bb93-7da8-4565-877a-cf6954c36239}" threadingModel="Apartment" tlbid="{5b44ec52-b95b-45cf-98ff-a49dfeed5a92}" progid="Codejock.PropertyGrid.16.3.1" description="Xtreme PropertyGrid Control" />
<comClass clsid="{0ab9571e-4cad-4392-b3af-14bd813398b2}" tlbid="{5b44ec52-b95b-45cf-98ff-a49dfeed5a92}" progid="Codejock.PropertyGridGlobalSettings.16.3.1" description="PropertyGrid Global Settings" />
</file>


Once I have a complete manifest it's then built into the executable. NON of the testers or QA staff are allowed to have the Codejock controls registered on their machines.....then we test the applications. I implemented this when Visa was released and UAC introduced.

It's still worthwhile you pursuing this technique, it would allow you to have different versions of your product running on the same machine (if COM was the limiting factor).

I also have certain DLLS where COM extraction does not work in InstallShield or other tools and I resorted to handcrafting the manifest at great pain.....but its worth it.