CustomCLRDialog not correctly works in bootstrapper

Feb 1, 2016 at 11:21 PM
Hello,
In my msi I created CustomCLRDialog, injected it by using code
 project.UI = WUI.WixUI_Common;
 project.InjectClrDialog("ShowRestorePathDialog", NativeDialogs.InstallDirDlg, NativeDialogs.VerifyReadyDlg);
...
var mainProj = project.BuildMsi();
and in .msi it works really fine!
Then I added this msi to bootstrapper:
var bootstrapper = new Bundle(ProjectName); 
var msi = new MsiPackage(mainProj);
msi.Id = ProjectName;
msi.Permanent = false;
msi.DisplayInternalUI = true;
msi.InstallCondition = "VersionNT64";
msi.Vital = false;
bootstrapper.Chain.Add(new PackageGroupRef("NetFx45Web"));
bootstrapper.Chain.Add(msi);
bootstrapper.Application = new SilentBootstrapperApplication(msi.Id);_
When I run burned .exe file, at step with customDialog it opens like a new msi and it fully minimized...Image
Can you suggest what I'm doing wrong?
Coordinator
Feb 2, 2016 at 5:21 AM
Edited Feb 5, 2016 at 11:55 PM
Unfortunately you are not doing anything wrong. 'Unfortunately' because otherwise you would be able to fix it... and sadly you are not.

CustomCLRDialog was always an ad hoc solution for a case of a single msi setup and it is not guaranteed to work with Burn bundle. CustomCLRDialog has been superseded with the MSI/WiX native "EmbeddedUI" model and Wix# fully supports this model. In fact it is a Wix# recommended UI customization technique.

However, unfortunately because of the implementation limitations Burn doesn't support "EnbeddedUI" at all. It seems to be temporary as WiX team acknowledged the problem and scheduled the fix for WiX v4: https://github.com/wixtoolset/issues/issues/4921/.

Saying that your report makes me think that CustomCLRDialog could be a temporary alternative for the broken Burn+EmbeddedUI combination so developers don't have to wait for the next WiX release.

I will have a look if CustomCLRDialog can be extended to work with the bootstrapper. I have created the corresponding issue on your behalf: https://wixsharp.codeplex.com/workitem/88
Feb 2, 2016 at 10:02 AM
Ohh... it is sad :(
But thank you for quick response and for help! Please let me know if will be some news about this issue, I'll be waiting for them
Coordinator
Feb 4, 2016 at 12:07 AM
Edited Feb 5, 2016 at 11:52 PM
I just published the new release v1.0.31.0. Among other improvements and fixes it contains the work around for the problem of Bundle UI not being hooked to CustomCLRDialog. Now CustomCLRDialog should work the same way when executed standalone or from bootstrapper.

This is still a work around that developers should resort to only until WiX releases a proper solution in v4.0
Feb 5, 2016 at 4:10 PM
It works, thank you!
Feb 9, 2016 at 1:45 PM
Edited Feb 9, 2016 at 1:50 PM
I suppose it's related to my issue but with this new version the 1.0.31.0! I got the same bug but with the WixCLRDialog.ShowAsMsiDialog(myform) function i use in my customActions... (i don't use the wix bundle and with the previous stable version it worked).
Coordinator
Feb 9, 2016 at 9:58 PM
I just retested the CustomCLRDialog sample and it works. Thus it must be something about your test conditions (or setup itself) that the current MsiWindowFinder doesn't handle well. It's kind of expected as GetMsiForegroundWindow algorithm can be easily broken by non-trivial runtime conditions. If you feel that the previous algorithm worked for you better you can use it instead of a new one. You just need to override your custom dialog GetMsiForegroundWindow:
public partial class YourCustomDialog : WixCLRDialog
{
    ...
    protected override IntPtr GetMsiForegroundWindow()
    {
        var window = Process.GetProcessesByName("msiexec")
                            .Where(p => p.MainWindowHandle != IntPtr.Zero)
                            .Select(p => p.MainWindowHandle)
                            .FirstOrDefault();

        if (window != default(IntPtr))
            return window; //old algorithm
        else
            return base.GetMsiForegroundWindow(); //new algorithm
    }
}
You can even implement your own algorithm. The GetMsiForegroundWindow requirement is simple - it supposed to find a window handle of the 'prev dialog', which is the dialog being displayed just before your custom one. The reliable generic algorithm is a challenge but a custom one for a specific setup is not. Thus for example if your 'prev dialog' has a title "My supper cool product setup" then the whole algorithm is Win32.FindWindow(null, "My supper cool product setup")

As I mentioned before the default algorithm itself is not reliable by nature and was only provided as an ad hoc solution prior support for EmbeddedUI. Yes if you are using bundle then it is the only available option for the moment but you are not. I really think you would dramatically benefit from moving to EmbeddedUI. You actually have no serious reason for not using the recommended technique and sticking to the old work around.

Seriously, your code will stay practically the same. Just create a test project from "WixSharp Managed Setup - Custom Dialog" and see it all for yourself.
Feb 10, 2016 at 9:14 AM
Thank you for the answer and to have take the time to answer ! I will test this ASAP ;)