oleg-shilo / wixsharp

Framework for building a complete MSI or WiX source code by using script files written with C# syntax.
MIT License
1.11k stars 176 forks source link

register Sharpshell extension from wixsharp installer #1660

Open pth65 opened 1 week ago

pth65 commented 1 week ago

Hi,

I tried a lot of different ways to register my Sharpshell (2.7.2) extension dll from my wixsharp installer (1.25.3) but it didn't work. When I manually register the dll, it works but I can't make it work from the wixsharp installer. I tried 3 different ways in a custom action, starting a process that run either:

  1. "ServerRegistrationManager.exe"
  2. a .bat file
  3. the source code from ServerRegistrationManager (InstallServer, RegisterServer, UninstallServer and UnregisterServer).

I also tried using InstalledFileAction and BinaryFileAction but it also didn't work.

I almost made it work by using PathFileAction (I mean the registration is done correctly) but for a weird reason, I can only install from a cmd prompt using msiexec ! If I double click on my installer, I got the following error: "There is a problem with this Windows Installer package. A program required for this install to complete could not be run. Contact your support personnel or package vendor." I would appreciate some help because I spent so much time trying to register this dll. Thank you.

Torchok19081986 commented 1 week ago

moring, first of all: is your to register dll a COM and marked COMVisible(true) in dll ? If not , there is problem in dll, not wixshap. Second: There is code from @oleg-shilo , for registration dll . Are you tried it ? Sample name is Comserver. Maybe this can give you some info.

Best entry point of registerstation , maybe after install event , is elevated and you can check if your software / package is installed or not.

for registration com assebly in windows, your need to call regsvr32 . if dll has also .tlb , then it has to be also part of isntaller, because this is type lib for dll.

according to ms path to regsvr32 is %windir%\SysWoW64\regsvr32.exe

code , not tested


 // Custom action to register the COM DLL
        var registerComDll = new CustomAction("RegisterComDll",
            ActionType.Execute,
            @"regsvr32.exe ""[INSTALLDIR]YourComDll.dll""",
            Return.check);

        // Custom action to unregister the COM DLL
        var unregisterComDll = new CustomAction("UnregisterComDll",
            ActionType.Execute,
            @"regsvr32.exe /u ""[INSTALLDIR]YourComDll.dll""",
            Return.check);
pth65 commented 1 week ago

Thank you for your quick answer. As I mentioned, if I run the register command manually (exactly the same I want to run from the installer), it works so it is not a problem in the dll. I forgot to mention that I also tried using RegisterAsCom as it is used in the ComServer sample but it didn't work. There is no .tlb. I forgot to mention it is for windows because it was implicit, when you develop shell extensions (FileManager extensions). I will give a try to the code using "regsvr32.exe".

Torchok19081986 commented 1 week ago

hm.., ok, then you have to launch your command as Process with Verb and ProgrammStartInfo class from CA or after install. i done in my dll that should be register as com dll

//[CustomAction]
//public static ActionResult RegPlugin(Session session)
//{
//    string pathtoregasmexe = @"C:\" + Environment.SpecialFolder.Windows + @"\Microsoft.NET\Framework\v4.0.30319";
//    return session.HandleErrors(() =>
//    {
//        var dll = session.Property("INSTALLDIR") + "<YourDll>.dll";
//        Process.Start(pathtoregasmexe + "\\RegAsm.exe", $"\"{dll}\"");
//    });
//}
/// <param name="session"></param>
/// <returns></returns>
//[CustomAction]
//public static ActionResult UnregPlugin(Session session)
//{
//    string pathtoregasmexe = @"C:\" + Environment.SpecialFolder.Windows + @"\Microsoft.NET\Framework\v4.0.30319";
//    return session.HandleErrors(() =>
//    {
//         var dll = session.Property("INSTALLDIR") + "<YourDll>.dll";
//        Process.Start(pathtoregasmexe + "\\RegAsm.exe", $"\"/u {dll}\"");
//    });
//}

Was Question : https://github.com/oleg-shilo/wixsharp/issues/637

pth65 commented 1 week ago

Though it should be possible to use RegAsm (https://github.com/dwmkerr/sharpshell/blob/main/docs/installing/installing.md), it doesn' work with my dll, I got the following error: "RegAsm : warning RA0000 : No types were registered". Using "ServerRegistrationManager.exe" it works fine (I mean manually, not in the installer). Using custom actions and Process.Start (with ElevatedManagedAction) is what I was already doing, it doesn't work for me. Any idea about what I mentioned with PathFileAction ?

pth65 commented 1 week ago

Also, due to this issue (https://github.com/actions/runner-images/issues/9667), I use Project, not ManagedProject.

Torchok19081986 commented 1 week ago

very strange issue here. what about gacutil or without it ? regasm /codebase ExampleContextMenuExtension.dll or gacutil -i ExampleContextMenuExtension.dll ? Tried or not? According to link , should work, because you install it with regasm in right way. That means for me, your ServerRegistrationManager.exe should be part of installer. Unfortunatelly, msi doesnt do any external execution of exe. BUT oleg has example in latest release folder, samples, wher you can add external assembly to installer and execute it. Path to example is \Source\src\WixSharp.Samples\Wix# Samples\DTF (ManagedCA)\Different Scenarios,. Here are all example to call external assembly dll or exe from installer. Maybe this give you some info.

Try sample in separate installer project if can call your serverregmanager.exe from installer.

if this also not work and you cant call your ServerRegistrationManager.exe from msi, then only Burn Installer remain as Option. This is not trivial task and your instaler ls not msi anymore, exe - installer, but your ServerRegistrationManager.exe is payload and can be called from any point of Installation and here you have biggest options to create installer for your needs.

pth65 commented 1 week ago

That is what I did, I distributed ServerRegistrationManager.exe with installed files. But then, my custom action for registration was using Process.Start, calling this ServerRegistrationManager executable. So, if I understand correctly, you suggest that I should try to put my CA in another dll and called it as in the samples you mentioned. I will give it a try. I am still curious about why PathFileAction almost work. Thank you.

Torchok19081986 commented 1 week ago

np. just try it self and it very hard to do blackboxing if case is special and no code provieded.

pth65 commented 1 week ago

of course, you are right, about PathFileAction, here is the code that almost work (registration is done and everything run fine when installing with msiexec but I got the error here above mentioned when double clicking on .msi installer):

var project = new Project { Actions = new Action[] { new PathFileAction( SrmPath, $@"install ""{InstalledDllPath}"" -codebase", "INSTALLDIR", Return.check, When.After, Step.InstallFinalize, Condition.NOT_BeingRemoved ), new PathFileAction( SrmPath, $@"uninstall ""{InstalledDllPath}""", "INSTALLDIR", Return.check, When.Before, Step.InstallFinalize, Condition.BeingUninstalledAndNotBeingUpgraded )} ...

with SrmPath containing the path to the installed file ServerRegistrationManager.exe

Torchok19081986 commented 1 week ago

morning, questions over questions. Why normal project and not ManagedProject? I understand correctly, with cmd and calling msiexec and give path to your msi in cmd, working fine, but by doble click on msi, results in error from before ? Do you tried chage project to managedproject and what happens after changes? is ougoing / output .wxl file looking ok ?

pth65 commented 1 week ago

morning, we changed from ManagedProject to Project because of this breaking change made in WiX 3.14.1 I mentioned before. The build machine was using a version of Wix >= 3.14.1 and the only workaround we found if we didn't want to downgrade Wix version was to change from ManagedProject to Project. I quickly created an installer with ManagedProject and PathFileAction and I still have the same issue: ok with msiexec, ko with 2x click (it is installed though there is this error message but the dll is not registered).

Torchok19081986 commented 1 week ago

now, i quess, something definitly wrong with your exe or dll, not wixsharp or wixtoolset. I didnt had anything like that. Where i still curios, why is calling from cmd msiexec process works, but with double click not. UIInitlized Event cant be used from Project, only if you use ManagedProject. I quess, your UI is still normal, welcomedialog, licensedialog and so on. Normal UI for MSI. If user doesnt has any rights to install package, UAC comes, also not install priviliges problem. double click doesnt change anything , jsut invoke your msi as process with cmd command msiexec. 😵‍💫😵‍💫😵‍💫🤔🤔🤔. BUT problem at this point. AFAIK you can set InstallerVersion for your description. i always set it to 450, also version 4.5. Is it 500 or above ? MS has changes in Win 11 for msiexec installer version and verbs / paramters.

forget to mention , window event log. click your msi file to try again to install. Now go to widows event log, category Install or System. There should be now see this error with some explanation. Maybe this can help.

pth65 commented 1 week ago

There is no specific UI, just accept the UAC and then installation starts. I activated the log from registry:

MSI (s) (8C:18) [09:53:41:122]: Doing action: ServerRegistrationManager.exe MSI (s) (8C:18) [09:53:41:122]: Note: 1: 2205 2: 3: ActionText Action start 09:53:41: ServerRegistrationManager.exe. MSI (s) (8C:90) [09:53:41:122]: System Environment : Client has accepted UAC prompt MSI (s) (8C:18) [09:53:41:252]: Note: 1: 1721 2: ServerRegistrationManager.exe 3: C:\Program Files (x86)\MyCompany\Common\ShellExtensions\ 4: "C:\Program Files (x86)\MyCompany\Common\ShellExtensions\ServerRegistrationManager.exe" install "C:\Program Files (x86)\MyCompany\Common\ShellExtensions\MyCompany.ShellExtensions.dll" -codebase MSI (s) (8C:18) [09:53:41:252]: Note: 1: 2205 2: 3: Error MSI (s) (8C:18) [09:53:41:252]: Note: 1: 2228 2: 3: Error 4: SELECT Message FROM Error WHERE Error = 1721 MSI (c) (1C:48) [09:53:41:257]: Font created. Charset: Req=0, Ret=0, Font: Req=MS Shell Dlg, Ret=MS Shell Dlg

Error 1721. There is a problem with this Windows Installer package. A program required for this install to complete could not be run. Contact your support personnel or package vendor. Action: ServerRegistrationManager.exe, location: C:\Program Files (x86)\MyCompany\Common\ShellExtensions\, command: "C:\Program Files (x86)\MyCompany\Common\ShellExtensions\ServerRegistrationManager.exe" install "C:\Program Files (x86)\MyCompany\Common\ShellExtensions\MyCompany.ShellExtensions.dll" -codebase MSI (s) (8C:18) [09:53:42:667]: Note: 1: 2205 2: 3: Error MSI (s) (8C:18) [09:53:42:667]: Note: 1: 2228 2: 3: Error 4: SELECT Message FROM Error WHERE Error = 1709 MSI (s) (8C:18) [09:53:42:667]: Product: MyCompany.ShellExtensions -- Error 1721. There is a problem with this Windows Installer package. A program required for this install to complete could not be run. Contact your support personnel or package vendor. Action: ServerRegistrationManager.exe, location: C:\Program Files (x86)\MyCompany\Common\ShellExtensions\, command: "C:\Program Files (x86)\MyCompany\Common\ShellExtensions\ServerRegistrationManager.exe" install "C:\Program Files (x86)\MyCompany\Common\ShellExtensions\MyCompany.ShellExtensions.dll" -codebase

Action ended 09:53:42: ServerRegistrationManager.exe. Return value 3. Action ended 09:53:42: INSTALL. Return value 3.

About InstallerVersion, I am not sure I got it correctly, I didn't specify anything but my Version (3.0.2) in the ManagedProject. I can see InstallerVersion in generated .wxs file, it is set to "200".

Torchok19081986 commented 1 week ago

do ServerRegistrationManager.exe has paramters "install" and accept file ? Is exe x86 or x64 ? MSI Platform has to be same architectuure like all components, else msi cant find components, afaik. If i read correctly , you have to register your ShellExtensions.dll in widows with your exe, BUT here comes error 1709. https://learn.microsoft.com/en-us/windows/win32/msi/windows-installer-error-messages, error has something wiht product self. if your ShellExtensions.dll is com, just copy it to some path on testsystem, and run regasm from cmd to register it, if successfully registerd, you got message. That means, your dll is ok, you have to add it to msi installer to do same.

https://learn.microsoft.com/de-de/dotnet/framework/tools/regasm-exe-assembly-registration-tool

pth65 commented 1 week ago

As I mentioned, using msiexec and typing manually the command both work so this is neither about ServerRegistrationManager.exe having parameters "install" or accept file, the command syntax is correct., nor about a missing file in the installer. Both ServerRegistrationManager.exe and the dll are built using "Any CPU", dumpbin display it both as x86. Do you think using msiexec or double clicking the installer would make a difference concerning the platform ?

Torchok19081986 commented 1 week ago

maybe. msiexec is always x86. if your want to do something for x64, you have to mark your components as winx64 to yes. there is property to mark files as x64 components. you cant set anycpu platform in wixshapr. x86 or x64. Also registery path is different for x86 and x64. All these "little" mistakes could caused problems.

pth65 commented 1 week ago

ok thank you very much for your support, I really appreciate it. I must switch to another project now but I will resume the work in a few days and I will let you know if I am able to make it work.

Torchok19081986 commented 1 week ago

np, i "fight" wix toolset since 3 years now. It always a fight. Thank to oleg, we dont have to. Wixsharp do amazing job and it helps really good for creating msi or exe installer. 😉😉😉. Wix# makes is lot easier to creating, change and use outgoing installer for daily needs. Biggest foe is noexisting good documentaion of wix toolset team for v3, v4, and now also v5. It longs almost enternity to wait, for documentation or exlplantion.