Code execution in Load is not elevated

Jan 25, 2016 at 6:51 AM
I use the Load method to set the InstallDir and TargetDir by reading registry settings.
If I run the msi from an elevated command prompt everything works fine, but once I just start the msiexec; I'd expect the msi to ask for elevated permission which it's doing.
However, it doe not happen for the code being executed in the Load method, causing the generated custom action to fail.
The failure has no effect and the installation continues, but the files are stored incorrectly (in the root of the drive)
You'll have to examine the log to see that it fails.

From the msi log:
MSI (s) (D4:B0) [08:35:23:929]: Invoking remote custom action. DLL: C:\windows\Installer\MSI8249.tmp, Entrypoint: WixSharp_Load_Action
SFXCA: Extracting custom action to temporary directory: C:\Users\ADMINI~1.VIA\AppData\Local\Temp\MSI8249.tmp-\
SFXCA: Binding to CLR version v2.0.50727
Calling custom action WixSharp!WixSharp.ManagedProjectActions.WixSharp_Load_Action
Begin WIXSharp CustomAction SetInstalldir
Exception has been thrown by the target of an invocation.
Action ended 8:35:24: WixSharp_Load_Action. Return value 1.
MSI (s) (D4:DC) [08:35:24:226]: Doing action: AppSearch
The code:
static public void Main()
{
    try
    {
        var msiProject = new ManagedProject("My App",
            new Dir(@"%ProgramFiles%\My Company\My Product", new File(@"Files\myapp.exe")),
            new Dir("SubDirRoot", new File(@"Files\myapp.exe"),
            new Dir("SubDirLevel1", new File(@"Files\myapp.exe"))),
            new Dir("SubDirRoot2", new File(@"Files\myapp.exe")));
        msiProject.Version = new Version(1, 0, DateTime.Now.Year, DateTime.Now.Month);
        msiProject.Platform = Platform.x64;
        msiProject.OutFileName = "MyApp " + msiProject.Platform.ToString();
        msiProject.GUID = new Guid("B5C99E99-39E8-4417-9391-14B3E28E1432");
        msiProject.SetNetFxPrerequisite("NETFRAMEWORK40FULL='#1'");
        msiProject.Load += (e) =>
        {
            if (e.IsInstalling)
            {
                e.Session.Log("Begin WIXSharp CustomAction SetInstalldir");
                RegistryKey consoleKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Help\\v1.0");
                if (consoleKey != null)
                {
                    string consolefolder = Convert.ToString(consoleKey.GetValue("AppRoot", string.Empty));
                    e.Session.Log("Setting INSTALLDIR to Help folder '" + consolefolder + "'");
                    e.Session["INSTALLDIR"] = consolefolder;
                    e.Session["TARGETDIR"] = consolefolder;
                }
                e.Session.Log("End WixSharp CustomAction SetInstalldir");
            }
        };
        Compiler.PreserveTempFiles = true;
        Compiler.BuildMsi(msiProject);
    }
    catch (Exception)
    {

        throw;
    }
}
Any suggestions?

Best regards
Flemming
Coordinator
Jan 26, 2016 at 3:43 AM
MSI doesn't play nice with the elevation. Its runtime architecture was designed years before the elevation-based security model was introduced. The only custom action that can be elevated is a deferred action and it can only be invoked in after the installation. Wix# maps it to the AfterInstall event. Thus OnLoad can only be unelevated.

However the operations you do in OnLoad do not require elevation anyway, so you should be OK. The problem you are experiencing is most likely caused by the fact that you are trying to open the registry key as read-write and this is forbidden. Thy to change it to read-only and most likely you will be OK.

You code would benefit if you just enclose your action in the try...catch and log the error so you know exactly what triggered the failure.