Пользовательские действия для установки IIS - ComboxBox Пустой выпуск - PullRequest
0 голосов
/ 26 апреля 2011

Я следую нескольким различным учебным пособиям, пытаясь создать универсальный установщик IIS WIX, который затем можно соответствующим образом разделить на разные библиотеки.

Учебники

Пока чтоУ меня есть установка, которая, кажется, работает при запуске с флагом / q.Однако в интерактивном режиме пользовательское действие, которое должно заполнять поле со списком, не работает.

Я попытался отладить, но у меня возникли следующие проблемы:

  1. Команды Session.Log, похоже, нигде не выводятся
  2. Подключение к msiexec и вызов Debugger.Launch или MmsiBreak, похоже, просто завершаются сразу (даже с включенными точками останова).

Начало разочаровывать, так как не должно быть так сложно брать значения из пользовательского действия и передавать их в поле со списком.

У кого-нибудь есть идеи, что может быть основной причиной, я ожидаюМногие люди использовали этот код или что-то подобное:

using System;
using System.Diagnostics;
using System.DirectoryServices;
using System.Globalization;
using System.Linq;
using Microsoft.Deployment.WindowsInstaller;
using Microsoft.Web.Administration;
using Microsoft.Win32;

namespace MyNameSpace
{
    /// <summary>
    /// Static class for the IIS Installer Custom Action.
    /// </summary>
    public static class CustomActions
    {

        #region Private Constants

        private const string IISEntry = "IIS://localhost/W3SVC";
        private const string SessionEntry = "WEBSITE";
        private const string ServerComment = "ServerComment";
        private const string CustomActionException = "CustomActionException: ";
        private const string IISRegKey = @"Software\Microsoft\InetStp";
        private const string MajorVersion = "MajorVersion";
        private const string IISWebServer = "iiswebserver";
        private const string GetComboContent = "select * from ComboBox";
        private const string AvailableSites = "select * from AvailableWebSites";
        private const string SpecificSite = "select * from AvailableWebSites where WebSiteID=";
        #endregion

        #region Custom Action Methods

        [CustomAction]
        public static ActionResult GetWebSites(Session session)
        {
            ActionResult result = ActionResult.Failure;
            try
            {
                if (session == null) { throw new ArgumentNullException("session"); }

                View comboBoxView = session.Database.OpenView(GetComboContent);
                View availableWSView = session.Database.OpenView(AvailableSites);

                if (IsIIS7Upwards)
                {
                    GetWebSitesViaWebAdministration(comboBoxView, availableWSView);
                }
                else
                {
                    GetWebSitesViaMetabase(comboBoxView, availableWSView);
                }

                result = ActionResult.Success;
            }
            catch (Exception ex)
            {
                if (session != null)
                {
                    session.Log(CustomActionException + ex);
                }
            }

            return result;
        }

        [CustomAction]
        public static ActionResult UpdatePropsWithSelectedWebSite(Session session)
        {
            Debugger.Break();

            ActionResult result = ActionResult.Failure;

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

                string selectedWebSiteId = session[SessionEntry];
                session.Log("CA: Found web site id: " + selectedWebSiteId);

                using (View availableWebSitesView = session.Database.OpenView(
                    SpecificSite + selectedWebSiteId))
                {
                    availableWebSitesView.Execute();

                    using (Record record = availableWebSitesView.Fetch())
                    {
                        if ((record[1].ToString()) == selectedWebSiteId)
                        {
                            session["WEBSITE_ID"] = selectedWebSiteId;
                            session["WEBSITE_DESCRIPTION"] = (string)record[2];
                            session["WEBSITE_PATH"] = (string)record[3];
                        }
                    }
                }

                result = ActionResult.Success;
            }
            catch (Exception ex)
            {
                if (session != null)
                {
                    session.Log(CustomActionException + ex);
                }
            }

            return result;
        }
        #endregion

        #region Private Helper Methods
        private static void GetWebSitesViaWebAdministration(View comboView,
            View availableView)
        {
            using (ServerManager iisManager = new ServerManager())
            {
                int order = 1;

                foreach (Site webSite in iisManager.Sites)
                {
                    string id = webSite.Id.ToString(CultureInfo.InvariantCulture);
                    string name = webSite.Name;
                    string path = webSite.PhysicalPath();

                    StoreSiteDataInComboBoxTable(id, name, path, order++, comboView);
                    StoreSiteDataInAvailableSitesTable(id, name, path, availableView);
                }
            }
        }

        private static void GetWebSitesViaMetabase(View comboView, View availableView)
        {
            using (DirectoryEntry iisRoot = new DirectoryEntry(IISEntry))
            {
                int order = 1;

                foreach (DirectoryEntry webSite in iisRoot.Children)
                {
                    if (webSite.SchemaClassName.ToLower(CultureInfo.InvariantCulture)
                        == IISWebServer)
                    {
                        string id = webSite.Name;
                        string name = webSite.Properties[ServerComment].Value.ToString();
                        string path = webSite.PhysicalPath();

                        StoreSiteDataInComboBoxTable(id, name, path, order++, comboView);
                        StoreSiteDataInAvailableSitesTable(id, name, path, availableView);
                    }
                }
            }
        }

        private static void StoreSiteDataInComboBoxTable(string id, string name,
            string physicalPath, int order, View comboView)
        {
            Record newComboRecord = new Record(5);
            newComboRecord[1] = SessionEntry;
            newComboRecord[2] = order;
            newComboRecord[3] = id;
            newComboRecord[4] = name;
            newComboRecord[5] = physicalPath;
            comboView.Modify(ViewModifyMode.InsertTemporary, newComboRecord);
        }

        private static void StoreSiteDataInAvailableSitesTable(string id, string name,
            string physicalPath, View availableView)
        {
            Record newWebSiteRecord = new Record(3);
            newWebSiteRecord[1] = id;
            newWebSiteRecord[2] = name;
            newWebSiteRecord[3] = physicalPath;
            availableView.Modify(ViewModifyMode.InsertTemporary, newWebSiteRecord);
        }

        // determines if IIS7 upwards is installed so we know whether to use metabase
        private static bool IsIIS7Upwards
        {
            get
            {
                bool isV7Plus;

                using (RegistryKey iisKey = Registry.LocalMachine.OpenSubKey(IISRegKey))
                {
                    isV7Plus = (int)iisKey.GetValue(MajorVersion) >= 7;
                }

                return isV7Plus;
            }
        }

        #endregion
    }

    public static class ExtensionMethods
    {
        private const string IISEntry = "IIS://localhost/W3SVC/";
        private const string Root = "/root";
        private const string Path = "Path";

        public static string PhysicalPath(this Site site)
        {
            if (site == null) { throw new ArgumentNullException("site"); }

            var root = site.Applications.Where(a => a.Path == "/").Single();
            var vRoot = root.VirtualDirectories.Where(v => v.Path == "/")
                .Single();

            // Can get environment variables, so need to expand them
            return Environment.ExpandEnvironmentVariables(vRoot.PhysicalPath);
        }

        public static string PhysicalPath(this DirectoryEntry site)
        {
            if (site == null) { throw new ArgumentNullException("site"); }

            string path;

            using (DirectoryEntry de = new DirectoryEntry(IISEntry
                + site.Name + Root))
            {
                path = de.Properties[Path].Value.ToString();
            }

            return path;
        }
    }
}

UI

 <?xml version="1.0" encoding="UTF-8"?>
    <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
        <Fragment>
            <CustomAction Id="UpdatePropsWithSelectedWebSite" BinaryKey="IISWebSiteCA"
                  DllEntry="UpdatePropsWithSelectedWebSite" Execute="immediate"
                  Return="check" />
            <Binary Id="IISWebSiteCA" SourceFile="$(var.MyCA.TargetDir)MyCA.CA.dll" />
        </Fragment>
        <Fragment>
            <UI>
                <Dialog Id="InstallationAddress" Width="370" Height="270" Title="Experian">
                    <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17"
                             Default="yes" Text="!(loc.WixUINext)">
                        <Condition Action="disable">WEBSITE = "" OR VD = ""</Condition>
                        <Condition Action="enable"><![CDATA[WEBSITE <> "" AND VD <> ""]]></Condition>
                    </Control>
                    <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17"
                             Text="!(loc.WixUIBack)" />
                    <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17"
                             Cancel="yes" Text="!(loc.WixUICancel)">
                        <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
                    </Control>
                    <Control Id="Title" Type="Text" X="15" Y="6" Width="219" Height="15" Transparent="yes"
                             NoPrefix="yes" Text="!(loc.SelectInstallAddress)" />
                    <Control Id="Description" Type="Text" X="25" Y="23" Width="340" Height="15" Transparent="yes" NoPrefix="yes" Text="!(loc.SelectInstallationDescription)" />
                    <Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44"
                             TabSkip="no" Text="!(loc.InstallDirDlgBannerBitmap)" />
                    <Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
                    <Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
                    <Control Id="SelectWebSiteLabel" Type="Text" X="20" Y="105" Width="290" Height="10"
                             NoPrefix="yes" Text="!(loc.Site)" />
                    <Control Id="SelectWebSiteCombo" Type="ComboBox" X="20" Y="117" Width="250" Height="16"
                             Property="WEBSITE" Sorted="yes" ComboList="yes" />
                    <Control Type="Text" Id="VirtualDirectoryLabel" Width="290" Height="10" X="20" Y="140"
                             Text="!(loc.VirtualDirectory)" />
                    <Control Type="Edit" Id="VirtualDirectoryTextbox" Width="250" Height="18" X="20" Y="152"
                             Property="VD" />
                    <Control Type="Text" Id="InfoText1" Width="350" Height="17" X="10" Y="55"
                             Text="!(loc.Info1)" />
                    <Control Type="Text" Id="InfoText2" Width="350" Height="17" X="10" Y="75"
                             Text="!(loc.Info2)" />
                </Dialog>
            </UI>
        </Fragment>
    </Wix>

1 Ответ

1 голос
/ 27 апреля 2011

Две быстрые вещи:

  • Я не вижу, где вы планируете свое действие здесь (только его определение и двоичная запись), поэтому я не уверен, что оно выполняется;Записи в подробном журнале могут подтвердить или опровергнуть это.Даже если он работает ...
  • Session.Log не работает с действием, запускаемым из диалогового окна (ограничения установщика Windows), поэтому даже если он выполняется, он не скажет больше, чем действиезапущен.Один общий обходной путь - убедиться, что вы регистрируете изменения свойств и изменяете свойство: Session["LOGHACK"] = message;
...