0
votes

I am creating Wix installer for IIS website with possibility in UI choose website, app pool and choose virtual directory. Thing is: I successfully created installer, which works with UAC off, but with UAC set to max. i get error - from MSI log:

MSI (c) (A0:C8) [16:41:21:692]: Invoking remote custom action. DLL: C:\Users\kovac\AppData\Local\Temp\MSI1AEF.tmp, Entrypoint: EnumerateIISWebSitesAndAppPools MSI (c) (A0:CC) [16:41:21:692]: Cloaking enabled. MSI (c) (A0:CC) [16:41:21:692]: Attempting to enable all disabled privileges before calling Install on Server MSI (c) (A0:CC) [16:41:21:692]: Connected to service for CA interface. SFXCA: Extracting custom action to temporary directory: C:\Users\kovac\AppData\Local\Temp\MSI1AEF.tmp-\ SFXCA: Binding to CLR version v4.0.30319 Calling custom action WebAppInstallCustomActions!WebAppInstallCustomActions.CustomActions.EnumerateIISWebSitesAndAppPools EnumerateIISWebSitesAndAppPools: Begin EnumerateIISWebSitesAndAppPools: ATTEMPTING TO RUN WITHOUT ADMIN RIGHTS CustomAction EnumerateIISWebSitesAndAppPools returned actual error code 1603 (note this may not be 100% accurate if translation happened inside sandbox) Action ended 16:41:23: EnumerateIISWebSitesAndAppPools. Return value 3. MSI (c) (A0:B0) [16:41:23:878]: Doing action: FatalError Action 16:41:23: FatalError.

I tried to follow articles - all i just understood was that i should run my custom action with Impersonate="no" so i did but with no success Additional info: there is no asking from UAC if custom action can be run with right or notm it just ends installer...

<CustomAction Id="EnumerateIISWebSitesAndAppPools"
              BinaryKey="WebAppCA"
              DllEntry="EnumerateIISWebSitesAndAppPools"
              Execute="immediate"
              Return="check" Impersonate="no" /> 

Also i read somewhere that actions needs to be run as deffered - but in this case it is not possible - as i need list of websites for user before installing.

My question is how can i run custom action with full right - with UAC on, specifically how are UAC related to admin rights applied on running CA? appreciate any help or any suggestion what to... As i don't know importance and problem domain i rather attach custom action script written in C#:

/// <summary>
    /// Adds the II7 web sites and the application pool names to the 
    /// ComboBox table in the MSI file.
    /// </summary>
    /// <param name="session">
    /// The installer session.
    /// </param>
    /// <returnenter code heres>
    /// Always returns ActionResult.Success, otherwise rethrows the error
    /// encountered.
    /// </returns>
    /// <exception cref="ArgumentNullException">
    /// Thrown if the <paramref name="session"/> parameter is null.
    /// </exception>
    [CustomAction]
    public static ActionResult EnumerateIISWebSitesAndAppPools(
                                                            Session session)
    {

        Debugger.Launch();

        if (null == session)
        {
            throw new ArgumentNullException("session");
        }

        session.Log("EnumerateIISWebSitesAndAppPools: Begin");

        // Check if running with admin rights and if not, log a message to
        // let them know why it's failing.
        if (false == HasAdminRights())
        {
            session.Log("EnumerateIISWebSitesAndAppPools: " +
                        "ATTEMPTING TO RUN WITHOUT ADMIN RIGHTS");
            return ActionResult.Failure;
        }

        session.Log("EnumerateIISWebSitesAndAppPools: " +
                                "Getting the IIS 7 management object");
        ActionResult result;
        using (ServerManager iisManager = new ServerManager())
        {
            result = EnumSitesIntoComboBox(session, iisManager);
            if (ActionResult.Success == result)
            {
                result = EnumAppPoolsIntoComboBox(session, iisManager);
            }
        }

        session.Log("EnumerateIISWebSitesAndAppPools: End");
        return result;
    }

private static ActionResult EnumSitesIntoComboBox(Session session, ServerManager iisManager) { try { // Debugger.Break(); session.Log("EnumSites: Begin");

            // Grab the combo box but make sure I'm getting only the one 
            // from WebAppInstallDlg.
            View view = session.Database.OpenView(
           "SELECT * FROM ComboBox WHERE ComboBox.Property='WEBSITE_NAME'");
            view.Execute();

            Int32 index = 1;
            session.Log("EnumSites: Enumerating the sites");
            foreach (Site site in iisManager.Sites)
            {
                // Create a record for this web site. All I care about is
                // the name so use it for fields three and four.
                session.Log("EnumSites: Processing site: {0}", site.Name);
                Record record = session.Database.CreateRecord(4);
                record.SetString(1, "WEBSITE_NAME");
                record.SetInteger(2, index);
                record.SetString(3, site.Name);
                record.SetString(4, site.Name);

                session.Log("EnumSites: Adding record");
                view.Modify(ViewModifyMode.InsertTemporary, record);
                index++;
            }

            view.Close();

            session.Log("EnumSites: End");
        }
        catch (Exception ex)
        {
            session.Log("EnumSites: exception: {0}", ex.Message);
            throw;
        }

        return ActionResult.Success;
    }

    static bool HasAdminRights()
    {
        WindowsIdentity identity = WindowsIdentity.GetCurrent();
        WindowsPrincipal principal = new WindowsPrincipal(identity);
        return principal.IsInRole(WindowsBuiltInRole.Administrator);
    }
2

2 Answers

1
votes

You collect the data in the UI mode with a dialog, that will set a bunch of properties that you then use in a deferred custom action with no UI. Deferred CAs run with the privilege you need if you set package InstallPrivileges elevated. If you really want to do all this in the code you've written, run it AFTER the install with an elevation manifest to configure what the website.

Or just see if the WiX IIS extension will do what you want. Or maybe this: http://www.codeproject.com/Articles/115036/Creating-WIX-Installer-for-ASP-NET-Web-Application

This has all been done so many times before that it's not worth re-inventing it again.

0
votes

All ca's scheduled in the UI sequence have to be immediate. Impersonation doesn't apply to immediate ca's. Best practice is for the UI to not be elevated so best practice says the CA shouldn't require eleveated privs. If there is no way around this, you'll need to use a bootstrapper to invoke the MSI and elevate it before calling it.