I have a setup project for a .NET Service Application which uses a .NET component wich exposes a COM interface (COM callable wrapper / CCW).
To get the component working on a target machine, it has to be registered with
regasm.exe /tlb /codebase component.dll
The /tlb switch to generate the typelib is mandatory in this case, otherwise i can't create objects from that assembly.
The question is, how can i configure my Visual Studio 2008 Setup-Project to register this assembly with a call to regasm /tlb ?
You can lose the manual call to regasm.exe by using System.Runtime.InteropServices.RegistrationServices instead:
[System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
public override void Install(IDictionary stateSaver)
{
base.Install(stateSaver);
RegistrationServices regsrv = new RegistrationServices();
if (!regsrv.RegisterAssembly(GetType().Assembly, AssemblyRegistrationFlags.SetCodeBase))
{
throw new InstallException("Failed to register for COM Interop.");
}
}
[System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
public override void Uninstall(IDictionary savedState)
{
base.Uninstall(savedState);
RegistrationServices regsrv = new RegistrationServices();
if (!regsrv.UnregisterAssembly(GetType().Assembly))
{
throw new InstallException("Failed to unregister for COM Interop.");
}
}
This also unregisters the library upon uninstall.
- In your main project (the one containing the class you want to register), right click the project file and select Add / New Item and select Installer Class. Call it something like clsRegisterDll.cs
- In the designer that appears, click 'Click here to switch to code view' or right click the clsRegisterDll.cs file in solution explorer and select View Code
Override the Install, Commit and Uninstall methods adding:
// Get the location of regasm
string regasmPath = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory() + @"regasm.exe";
// Get the location of our DLL
string componentPath = typeof(RegisterAssembly).Assembly.Location;
// Execute regasm
System.Diagnostics.Process.Start(regasmPath, "/codebase /tlb \"" + componentPath + "\"");
Swap /codebase /tlb for /u in the uninstall action.
- Compile your project
- In your installer, make sure you have added your dll to the Application Folder, and then right-click the installer project and select View / Custom Actions
- Right-click Install, and then click Add Custom Action
- Double click on Application Folder, and then on your dll
- Do the same for the Commit action
- Build and test your installer
A walkthrough with an actual class for you to try can be found at: http://leon.mvps.org/DotNet/RegasmInstaller.html
Your service should have an Installer class.
Register to the OnAfterInstall event and call RegAsm: the path should be computed from the Windows directory and tied to a specific .Net version.
I initially tried running regasm from the installer process (before I saw this posting). Trying to run regasm , and handling all the errors was problematic - even without trying to handle elevated privileges for Windows 7.
Using Runtime.InteropServices.RegistrationServices.RegisterAssembly
was much cleaner and provided a much better error trapping.