Wixsharp: [Question] Register DLL with ComRegistration

Created on 2 May 2019  路  6Comments  路  Source: oleg-shilo/wixsharp

Hello,

I am trying to register several DLLs and OCX (ActiveX controls). I tried using the new ComRegistration feature added in 1.9.6.0 but to no avail.

Here's how I do it :

project.AddDir(new Dir(@"C:\destination", new Files(@"sources\*.*")));

project.ResolveWildCards();

project.AllFiles
    .Where(file => file.Name.ToLower().EndsWith(".dll") || file.Name.ToLower().EndsWith(".ocx"))
    .ForEach(file => file.Add(Tools.GetComRegistration(file.Name.PathGetFileName(), Version)));

My Tools class :

public static class Tools
    {
        public static ComRegistration GetComRegistration(string dllName, string dllVersion)
        {
            return new ComRegistration()
            {
                Id = Guid.NewGuid(),
                Description = dllName,
                ThreadingModel = ThreadingModel.apartment,
                Context = "InprocServer32",
                ProgIds = new[]
                {
                    new ProgId
                    {
                        Id = dllName + " " + dllVersion,
                        Description = dllName + " " + dllVersion
                    }
                }
            };
        }
    }

The resulting WIX component looks OK

<Component Id="Component.foo.dll_740789922" Guid="ed7d977d-1bfa-4a6f-a2bb-a2f13d407eae" Win64="yes">
    <File Id="foo.dll_740789922" Source="sources\foo.dll">
      <Class Id="a60aa624-baba-4134-8b58-618e612ec919" Context="InprocServer32" ThreadingModel="apartment" Description="foo.dll" IconIndex="0">
        <ProgId Id="foo.dll 6.8.1.0" Description="foo.dll 6.8.1.0" />
      </Class>
    </File>
</Component>

Yet the DLLs are not properly registered (the program that uses them doesn't see them).
If I use regsvr32 it works, but I would prefer not to use that in my project.

I presume I made a mistake but I cannot find much information on the subject.

Thank you to anyone that can help me !

EDIT : If I use SelfRegCost=1 it also works, but according to https://stackoverflow.com/questions/364187/how-do-you-register-a-win32-com-dll-file-in-wix-3 it is not a desirable solution.

question

Most helpful comment

You confirm there is no native way in WixSharp to register a DLL ?

You see, WIxSharp is just a trans-compiler. It produces WiX code that is then compiled into MSI. Thus if WiX/MSI offers only one native way of registering COM servers (ProgIds) then WixSharp cannot introduce anything new that is equally "native".

Though WixSharp brings rather a unique ease of defining managed CA where you can do ANYTHING you want on the target system. Thus if you decide to go with regsvr32 the you code can be as simple as this:

```C#
var project =
new Project("My Product",
new Dir(@"%ProgramFiles%\My Company\My Product",
new File(@"..\SimpleServer\MyApp.dll")),
new ElevatedManagedAction(CustomActions.InstallServer, Return.check, When.After, Step.InstallFiles, Condition.NOT_Installed),
new ElevatedManagedAction(CustomActions.UnInstallServer, Return.check, When.Before, Step.RemoveFiles, Condition.BeingUninstalled));

. . .

public class CustomActions
{
[CustomAction]
public static ActionResult InstallServer(Session session)
{
return session.HandleErrors(() =>
{
var dll = session.Property("INSTALLDIR") + "MyApp.dll";
Process.Start("regsvr32.exe", $"/s \"{dll}\"")
});
}

[CustomAction]
public static ActionResult UnInstallServer(Session session)
{
    return session.HandleErrors(() =>
    {
        var dll = session.Property("INSTALLDIR") + "MyApp.dll";
        Process.Start("regsvr32.exe", $"/s /u \"{dll}\"");
    });
}

}
```

All 6 comments

Hallo, i also tried to register dll as com , but my mainapplication dont see it as com. Dll is marked as comvisible . i found 2 ways to harvest important values in wix toolset, but dont know how to use it in wix sharp. May be Oleg can write something about it.

First: https://ecmtechnicalexpertise.wordpress.com/2014/10/07/registering-dlls-in-com-with-wix/
I get all important info for application as com, but only if you use pure wixtoolset.
Second : use batch in installfinalize to register your dll as com. soomething like %windir%\Microsoft.NET\Framework\v2.0.50727regasm.exe " -codebase path to your dll. Warning: tlb should be exists in same path.
Both approach are works. i personally use second. because i dont know how to use first approach in Wix#.
my batch/cmd file looks like
@echo off

%systemdrive%

REM regasm Pr眉fung auf .Net Framework V4
cd %WINDIR%\Microsoft.NET\Framework\v4*
if exist regasm.exe (
goto :regasm
)

REM regasm Pr眉fung auf .Net Framework V3
cd %WINDIR%\Microsoft.NET\Framework\v3*
if exist regasm.exe (
goto :regasm
)

REM regasm Pr眉fung auf .Net Framework V2
cd %WINDIR%\Microsoft.NET\Framework\v2*
if exist regasm.exe
(
goto :regasm
)

goto :eof

:regasm
wmic path win32_operatingsystem get OSArchitecture|FINDSTR "64-Bit" && goto :x64

:x32
for /f "tokens=2*" %%A in ('REG QUERY "HKLM\Software\crm" /v ModuleDir') DO set ModuleDir=%%B
goto :start

:x64
for /f "tokens=2*" %%A in ('REG QUERY "HKLM\Software\Wow6432Node\crm" /v ModuleDir') DO set ModuleDir=%%B
:start
regasm.exe "Pathtoapp\Plugin.dll"

just add it to msi iin CA and execute it in iinstallaton at end. Works for me each time i need dll as com as plung-in.

I am not sure using regasm.exe is an option since @fschlaef already indicated he does not want to rsort to the use of external executable (regsvr32.exe).

I would suggest consulting the WiX documentation but since it is already done the use if SelfRegCost=1 may be the only option.

Ok, thanks for answer Oleg. is it possible to implement first approach to wix sharp ? .wxs file looks ok and if i try it in wix toolset project it works. how do i set it in wix# ? AFAIK wxs is important to create msi and going to be overwirtten by wix# right ?

@oleg-shilo thank you for answer, I think I will use regsvr32.exe anyway, it's much better than SelfRegCost

You confirm there is no native way in WixSharp to register a DLL ?

You confirm there is no native way in WixSharp to register a DLL ?

You see, WIxSharp is just a trans-compiler. It produces WiX code that is then compiled into MSI. Thus if WiX/MSI offers only one native way of registering COM servers (ProgIds) then WixSharp cannot introduce anything new that is equally "native".

Though WixSharp brings rather a unique ease of defining managed CA where you can do ANYTHING you want on the target system. Thus if you decide to go with regsvr32 the you code can be as simple as this:

```C#
var project =
new Project("My Product",
new Dir(@"%ProgramFiles%\My Company\My Product",
new File(@"..\SimpleServer\MyApp.dll")),
new ElevatedManagedAction(CustomActions.InstallServer, Return.check, When.After, Step.InstallFiles, Condition.NOT_Installed),
new ElevatedManagedAction(CustomActions.UnInstallServer, Return.check, When.Before, Step.RemoveFiles, Condition.BeingUninstalled));

. . .

public class CustomActions
{
[CustomAction]
public static ActionResult InstallServer(Session session)
{
return session.HandleErrors(() =>
{
var dll = session.Property("INSTALLDIR") + "MyApp.dll";
Process.Start("regsvr32.exe", $"/s \"{dll}\"")
});
}

[CustomAction]
public static ActionResult UnInstallServer(Session session)
{
    return session.HandleErrors(() =>
    {
        var dll = session.Property("INSTALLDIR") + "MyApp.dll";
        Process.Start("regsvr32.exe", $"/s /u \"{dll}\"");
    });
}

}
```

Awesome ! Thank you for taking the time to put this together, and for the explanation :)

I tested your solution and it works flawlessly, thank you very much !

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ltemimi picture ltemimi  路  5Comments

marcobeninca71 picture marcobeninca71  路  4Comments

JamesWHurst picture JamesWHurst  路  5Comments

meytes picture meytes  路  5Comments

UweKeim picture UweKeim  路  5Comments