Register CPP DLL in COM after installation using the Wix Msi installer

I am trying to register the CPP library in COM during the installation of Msi.

I searched a lot and found many solutions here, but nothing works in my code. I do not know if there is any direct method for this. I tried using Custom Action with direct ExeCommand and with a script package.

Here is the code with the script package.

<SetProperty Id="Register" Value="&quot;[INSTALLDIR]Scripts\Register.bat&quot;" After="CostFinalize"/> <CustomAction Id="Register" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="deferred" Return="check" Impersonate="no"/> <SetProperty Id="Unregister" Value="&quot;[INSTALLDIR]Scripts\UnRegister.bat&quot;" After="CostFinalize"/> <CustomAction Id="Unregister" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="deferred" Return="check" Impersonate="no"/> 

Using this code, the installation does not show any errors, but the dll is not registered. After installation, if I run the script package separately, it will be registered.

Register.bat

cd "C: \ Windows \ System32"

regsvr32 "C: \ Program Files (x86) \ ABC \ Abc.dll"

ping -n 15 127.0.0.1> nul:

Unregister.bat

cd "C: \ Windows \ System32"

regsvr32 / u "C: \ Program Files (x86) \ ABC \ Abc.dll"

ping -n 15 127.0.0.1> nul:

With a custom action with ExeCommand, it shows an error, as well as some dll dependency. ExeCommand code is below.

 <CustomAction Id="Register" Directory="INSTALLDIR" Execute="deferred" Impersonate="no" ExeCommand="[WindowsFolder]System32\regsvr32 &quot;[INSTALLDIR]Abc.dll&quot;" Return="check" /> <CustomAction Id="Unregister" Directory="INSTALLDIR" Execute="deferred" Impersonate="no" ExeCommand="[WindowsFolder]System32\regsvr32 /u &quot;[INSTALLDIR]Abc.dll&quot;" Return="check" /> 

And InstallSequence for both cases is given below.

  <InstallExecuteSequence> <Custom Action="Register" Before="InstallFinalize" >NOT Installed</Custom> <Custom Action="Unregister" Before="RemoveFiles">Installed AND NOT UPGRADINGPRODUCTCODE</Custom> </InstallExecuteSequence> 

In both cases, I think it works with elevated privileges.

This is a mistake that I get most of the time. enter image description here

Edit

The following window displays the dependencies of the DLL.

enter image description here

I also add the heat command that I used. I added this prebuild event to create the component. After that, this component is added to the product file.

call "$ (WIX) bin \ heat.exe" file "dllPath \ Abc.dll" -dr "INSTALLDIR" -srd -gg -sfrag -suid -out "$ (SolutionDir) Installer \ ComRegisterComponent.wxs"

And the generated file is as follows.

  <Fragment> <DirectoryRef Id="INSTALLDIR"> <Component Id="Abc.dll" Guid="{1CF887DC-FE9F-44B5-8923-1F7EB6FBDAED}"> <File Id="Abc.dll" KeyPath="yes" Source="SourceDir\Abc.dll" /> </Component> </DirectoryRef> </Fragment> 

Here, this SourceDir path confuses me. I added the exact path to the heat command, even then it generates this SourceDir.

+1
c ++ dll windows-installer wix
Dec 11 '17 at 3:36 on
source share
3 answers

Short, final answer

You need to stop using batch files and user actions to register COM (untrusted) and rather extract COM registration information using the heat.exe tool from the WiX toolkit to add COM registration to your MSI database at compile time.

There are several complications for 64-bit binaries, see details below. Fortunately, it looks like you are dealing with a 32-bit component based on your installation directory shown above.

In this particular case, he helped run the heat.exe file in the COM file after deployment, when all the dependencies were in place for the COM file to load correctly. There is a lot of “debugging communication” in these answers - I will leave everything in its place in the future, but first I will try this simple solution. And maybe try the new Dependencies.exe dependency tool described below.




Long, detailed answer

Before trying to answer a question (which seems to revolve around missing dependencies or something strange in your batch file ), I want to clarify some things for you regarding best practice for registering COM.

Note : the screenshot seems to indicate something strange in your batch file, but missing dependencies can still be a problem.

Self-registration is considered harmful

Self-registration should not be used to register COM files . Here is a description of why this is so: MSI register dll - self-assessment is considered harmful . There is good news, however, to do something as provided through the built-in MSI mechanisms will be easier and more reliable after proper configuration.

There is a way to register files yourself during installation without using the user actions that you are trying to do ( table SelfReg ). Custom actions are very difficult for proper operation, but you should not use the built-in mechanism for self-registration (as described in detail in the linked answer above)

Instead of using custom actions or a SelfReg table, COM registration information should be extracted from your COM files at compile time — in other words, when you compile an MSI file from your WiX source files. The extracted registry data should be used to populate the family of MSI data tables designed to securely register and unregister the COM file during installation and uninstallation, respectively.

WiX: Command line tool "heat.exe"

Understanding the complex details of this process is not necessary - all you need to know is which tools to use. WiX provides the heat.exe tool for this purpose. This is essentially a harvester tool capable of generating valid WiX XML source files for several purposes - one of which is COM extraction. It also supports moving directories altogether - creating WiX source files that can install files encountered during crawls. Essentially, this is a very quick way to make an MSI package when you know how to use it.

Dependency evasion

So, we have found that you need to take the time to learn how to use heat.exe to generate the WiX source needed to register the COM file. however, there is another problem : missing dependencies .

In order for the COM file to be able to register independently - or for you to be able to successfully retrieve the COM registry data using heat.exe, the COM file must be able to load correctly. To make this possible, all dll dependencies must be available in the system in question in an accessible place.

Get a copy of Dependency Walker and use it to scan your COM file, for which files it depends on. Here is an example COM file that does not load because it cannot find MMUtilities.dll :

enter image description here

Most likely, you will find something similar with your dll (or any type of file, for example, OCX) when it is launched from your installation location. The required dependency files could not be found regsvr32.exe, and the registration process is not performed.

There are some reported missing dependencies that are not important . I believe that this is due to the age of the Dependency Walker tool - it has not been updated recently, as far as I know. Look for a file that you recognize as your own dependency file, or the main system file, and not very long file names that you have never heard of. Keep in mind that some DLL files have dependency libraries required for loading. For example, MMUtilities.dll requires MmUtilitiesEnglish.dll or another language library to be present in the same folder in order to be able to load correctly.

Some examples of false positive dependencies for the above file: API-MS-WIN-CORE-RTLSUPPORT-L1-1-0.DLL , API-MS-WIN-CORE-PROCESSTHREADS-L1-1-0.DLL , API-MS-WIN-CORE-REGISTRY-L1-1-0.DLL , etc. There were a lot of them. I'm sure, but I'm not sure that the main reason for these false positives is centered around problems with side-by-side components installed in the WinSxS folder, but this is another discussion - just mention it.




UPDATE : I just checked this again, and most of the false positive dependencies seen above look clearly API sets - a Windows feature introduced long before Dependency Walker was created and therefore not properly handled by the tool.

As the related answer shows (read it, the link above), now there is also a rewriting of Dependency Walker in C # called " Dependencies ", available here: https://github.com/lucasg/Dependencies (not verified by me at the time of writing, will be checked soon).




Also, quickly mention: if you have an executable file for verification (unlike dll, ocx, etc.), you can start it using the menu item Profile => Start Profiling... , after which you will also see " hidden temporary dependencies "not specified in the binary import table (where dependencies / imports are indicated). You really need to use the application, using all the functions in all dialog boxes to get all such dependencies.

The dependent hosting web page causes these hidden dependencies, explicit dependencies (dynamic or temporal dependency) and system hangs (nested dependencies). See the link above for more details.

Extract Heat.exe

Once you have determined which files are missing to do the work of extracting WiX heat.exe, you can put the appropriate files “next to” your DLL-COM so that they are found at boot time. You can test the run with regsvr32.exe to verify that the registration completed correctly. When registering manually, there should be no error messages. Remember to run the registration from the elevated command prompt .

A few other stackoverflow answers explain how to use heat.exe - I haven't used it for a long time: How to run heat.exe and register the dll on wix . Here's the official documentation for heat.exe from the WiX users themselves. It can be a somewhat frightening tool - it has many features.

In its simplest form (for regular 32-bit COM files with all the dependencies available in the path or local folder), you can run this heat.exe command line to generate a WiX source output file named YourFileName.wxs with all the required COM registry data .

 heat.exe file YourFileName.ocx -o YourFileName.wxs 

A few years ago, I wrote an answer showing how to incorporate exported WiX registry data into your main WiX source: How to reference the heat output (wxs) in a Wix (Command Line) . I believe that this is an accurate description of the procedure, but for some reason someone voted for the answer. Please let it go and see if it works for you.

Important! : heat.exe is still not correctly processing 64-bit COM files (December 2017).

I was informed that the WiX extension package ( not free ) processes 64-bit binaries and provides several other functions. I suggest that I can link it (I am not affiliated with FireGiant): https://www.firegiant.com/wix/wep-documentation/harvesting/ . Somehow people should know about these things, but I'm not sure about the stackoverflow layout method.

Are your binaries 64-bit? (it does not look like this from the installation folder, but I am adding this for others who may find it). For the 64-bit component, I think we have come full circle and should advise you to either use the above extension function, or just try installing the file for self-registration, as described here . I hate this self-registration “solution”, but at the moment I can’t come up with any quick fixes (I do not recommend it in any case). I will check again. Be sure to check the latest version of WiX to see if the 64-bit issue has been fixed before moving on to this "fix your own registration . " This is at least better than trying to log in using custom actions and batch files (which should never be tried - there are so many potential problems with sequential MSI custom actions, impersonation / elevation, configuration, silent and installation modes interactive, and not mention potential interference from security software, and the list goes on).




Some links:

  • How to register a Win32 COM DLL file in WiX 3?
  • Unable to register DLL using WiX
  • Use wix to execute the REGSVR32 function
  • Heat.exe cannot collect TypeLib information from the 64-bit COM DLL
  • Heat.exe: 64-bit .dll cannot be converted to 64-bit .msi
+3
Dec 11 '17 at 15:07
source share

The idea is not to use the bat file to register the DLL. Let Windows Installer / WiX do it for you. In the past, this has also been answered here .

+1
Dec 11 '17 at 12:30
source share

Just add another answer with information on how to use procmon.exe effectively in an efficient way to debug missing dependencies during self-registration using regsvr32.exe .

Essentially, you have to set up an inclusion filter , which events you want to track and record, otherwise you will receive an almighty list of irrelevant events listed, and it is difficult for you to find what you need in the sea of ​​useless information:

Apply inclusion filter in procmon.exe

  • To limit the captured process information to the information you need, simply go to Filter => Filter...
  • Set the left button down to Process Name and then the second column to is and finally enter regsvr32.exe in the right field, as shown in the figure above.
  • Set the rightmost edge to Include . Then click OK.
  • All unnecessary events should now be suppressed, and only regsvr32.exe events are displayed (when you run it).
  • Run regsvr32.exe normal path and look for the entries " NAME NOT FOUND " (or similar) in the list.
  • In the image below, MMUtilities.dll could not be found. In other words, this is a missing addiction.

Could not find MMUtilities.dll file




Another way to debug missing dependencies during self-registration is to use Dependency Walker , as shown in my other answer in this “thread” or question or something else, to call it. I usually find Dependency Walker faster, but ProcMon is probably better overall - if you are not debugging an EXE file, then Dependency Walker has an excellent Profile function ( Profile => Start Profiling... ).

+1
Dec 13 '17 at 11:59 on
source share



All Articles