Video Screencast Help
Endpoint Management Community Blog

How to Manually Register a DLL in an MSI

Created: 10 Dec 2007 • Updated: 10 Dec 2007 • 11 comments
R-Vijay's picture
+1 1 Vote
Login to vote

Using Wisecomcapture is always the best option to use when registering a DLL. See this article for some background.

But, if there is a case when the DLL doesn't exist in the package and there is a necessity to register a file manually, this tip should prove handy.

To manually register a .DLL using regsvr32.exe in a .MSI package:

Step 1: Go to MSI Script in the WSI project.
Add an Execute Program from Destination custom action after InstallFinalize in the Execute Immediate tab.
The Execute Program From Destination dialog appears.

Step 2: Fill in the following information:
Custom Action Name: <registerdll>
Working Directory: Enter SystemFolder
EXE and Command Line: Enter the full path to regsvr32.exe and the full path to .DLL.
Example: [SystemFolder]regsvr32.exe [WindowsFolder]123.DLL

Step 3: Accept all other defaults and click OK.

Ensure that the custom action has a condition around it so that it only executes when the installation is getting placed on the computer:

If Not Installed  
     Execute Program from Destination
End Statement

Comments 11 CommentsJump to latest comment

AngelD's picture

You should of course want to add the silent switch to the command line otherwise the command will not end until the OK button has been pushed.
Example: [SystemFolder]regsvr32.exe /s [WindowsFolder]123.DLL

+1
Login to vote
Harsh Mokal's picture

Just for info

To call the system API DllRegisterServer to self-register modules passed on the command line
one can use

msiexec /y

Parameters
/y : Calls the system API DllRegisterServer to self-register File passed on the command line.

->This option is used only for registry information that cannot be added using the registry tables of the .msi file.
Examples
The following example shows how you can use the msiexec /y command:
msiexec /y file_name.dll

To call the system API DllUnRegisterServer to unregister modules passed on the command line
One can use

Syntax
msiexec /z
Parameters
/z : Calls the system API DllUnRegisterServer to unregister file passed on the command line.

-> This option is used only for registry information that cannot be added using the registry tables of the .msi file.

Examples
The following example shows how you can use the msiexec /z command:
msiexec /z file_name.dll

Regards
Harsh

+1
Login to vote
R-Vijay's picture

Thats a nice addin Angel. I just understand the consequences now.. :D

Microsoft MVP [Setup-Deploy]
Weblog: www.msigeek.com

-5
Login to vote
ggjone's picture

Can anyone let me know the difference between using regsvr.exe or msiexec.exe to do this?

Is there are reason to use one method over another?

thanks

+3
Login to vote
Harsh Mokal's picture

MSIEXEC /Y and /Z is one method of self registartion. This is one option provided by Windows Installer technology and entries get populated in selfreg table.

If you are using wise package studio, right click on file can see self register option. If you check this option, custom actions for MSIEXEC automatically get added in to your package, and selfReg table updated with the associated entries.
else you can enter file and cost value for required table entry record using tables.

I personally never recommend self-registration of DLLs or OCXs. I always recommend extracting COM information and populating the appropriate MSI tables. This entries can be seen in advertise tables viz ProgID, MIME , ClassID etc.

As per my experience, It is really difficult for me to find out the source of the registration issue. If running manually works then you can try creating a custom action to call regsvr32.exe with /s and pass your full path to the self registrable file command-line.

So Register using Regsvr32 is one of the trouble shooting methodology.

Hope this will helpful, let me know if require more input.

Cheers Festive season
Harsh

+3
Login to vote
williamd's picture

Hi I have a question along these lines and I am not sure where to ask and this seemed the most appropriate place, if it is not I apologize.

So I have been using Wise Windows Installer Editor for a while now.  For my installation I have 1 .dll that MUST have DllRegisterServer called for it.  This is because this dll processes an .ini file and does some additional setup for our program.  For a while I have been using a "Call Dll from installed file" and explicitly calling DllRegisterServer on it.  This was/is a 3601 CustomAction ( I believe this is a Commit action I forget exactly what the numbers mean at this point in time. ) I had MS tech support help me figure out that I needed this type of CustomAction a while ago due to the fact that our .msi uses MS and VC runtime files as merge modules and the only way to make sure that all of the required VC Runtime files were on the system prior to trying to call DllRegisterServer was to have it as this type of CustomAction.  In the MSI script it is in the execute deferred tab appearing after RegisterProduct.

So recently there has been a change in this DLL file.  We have a new .dll that is also installed in our installation that USED to be set as a delay load dll, but due to some errors some clients were receivng this option has been removed.  Ever since this new .dll needs to be loaded at the same time as our main .dll that we call DllRegisterServer on the installation has stopped working.  Using ProcessMonitor on a test machine it looks like for some reason when attempting to load our main dll via the custom action it never seems to check for the dependent .dll in the installed directory.  It only seems to be checking locations that are in the PATH environment variable.

I then attempted to use a different custom action to call regsvr32.exe and pass our main .dll as part of the command line as suggested above.  The problem is that this still fails.  It seems that regsvr32.exe is returning 3 for the registration call.  My test machine is currently 32 bit Windows 7 machine.  I personally think that the reason it is returning 3 is because of permissions of some sort.  I know that on my machine ( also windows 7 ) when manually registering our .dlls from the command line I get return codes of 3 UNLESS I am using an "administrator" cmd console. 

So I have a couple of questions I guess.
1.) Is there a way to have the 3601 customaction to work as it used to even though it requires a .dll that is also installed by the same installation.
2.) If I can't get that to work how can I go about making sure that I have the appropriate permissions to have regsvr32 run sucessfully?  
     a.)  what flags are needed for this customaction
     b.) where should this custom action be placed ( should I keep it in the same place as a "commit" action so that the files from the merge modules will be accessible? )

Thank you for your time and sorry for the lengthy post
-Mac

+2
Login to vote
EdT's picture

There are two wise support forums where you can post this type of question, although you may get a response here if someone spots your posting in the community feed column before it is overwritten.
I wonder if your situation here is being exacerbated by testing on Windows 7. Does your previous install and registration work OK on Windows 7?
Are you using a manifest with your install?  If so, is it set to run the install as Administrator, rather than as Invoker?
Finally, is there an option to extract or capture the registration information for your DLL files, and write that directly to the registry as part of the install?

If your issue has been solved, please use the "Mark as Solution" link on the most relevant thread.

+3
Login to vote
williamd's picture

Hi EdT,
Thanks for the suggestion.  I will repost this on the forums.  This site keeps changing around every time I need to post questions it seems so I get a bit lost.

Yes prior to the change where the .dll was allowed to be delay loaded everything seemed fine for window 7.  As soon as this .dll was basically statically linked the installation fails everywhere I have tested: XP, Vista (32 or 64) and Windows7(32/64).  I don't think I am using a manifest ( as I have not written 1 ).  All of our other .dlls I have extracted this information for, but the contents of the .ini differ from installation to installation and the .dll writes values into the registry based on what is in the .ini file.  I know that functionality won't be changing anytime soon.

-1
Login to vote
williamd's picture

Ok so I found a solution to this.  The problem actually was that windows had no clue where to look to load this particular dll.  The fix is to add our directory to the PATH environment variable and everything works fine now.

+3
Login to vote
packmyapp's picture

Thanks a ton for this post. I tried several methods (by using batch files and deferred exection script) but ultimately your solution worked flawlessly.

I would like to add one thing though, the path to the dll must be enclosed in double quotes:

Suppose that after installation, the path to dll to be registered is C:\Program Files (x86)\myApp\bin\xyz.dll then the command line entry should be:

[SystemFolder]regsvr32.exe /s "[ProgramFilesFolder]\myApp\bin\xyz.dll"

+2
Login to vote
NovYus's picture

Thanks to all of the above, has helped me solve my problem with registering dlls.

My next question around this same topic is how do you replace an existing dll with a newer version in e.g. C:\Windows\System32\test.dll.

When installing my new package it still showing the old dll and not the new one.

Any help would be appreciated.

Y

-1
Login to vote