IIS安装的自定义操作 - ComboBox空问题

时间:2011-04-26 13:59:01

标签: iis combobox wix custom-action

我正在学习一些不同的教程,试图制作一个通用的IIS WIX安装程序,然后我可以将其拆分为不同的库。

教程

到目前为止,我有一个在使用/ q标志运行时似乎有效的安装。但是在交互模式下,应该填充组合框的自定义操作无效。

我试过调试但是我遇到了以下问题:

  1. Session.Log命令似乎无法随处输出
  2. 附加到msiexec并调用Debugger.Launch或MmsiBreak似乎只是立即退出(即使启用了断点)。
  3. 开始变得令人沮丧,因为从自定义操作获取值并将它们传递到组合框不应该这么困难。

    任何人都有任何想法可能是根本原因,我期待很多人使用此代码或类似的东西:

    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 个答案:

答案 0 :(得分:1)

两件快事:

  • 我没有看到你在这里安排行动的地方(只是它的定义和二进制条目),所以我不相信它正在运行;详细日志中的条目可以确认或反驳该条目。即使它正在运行......
  • Session.Log不适用于从对话框启动的操作(Windows Installer限制),因此,即使此操作正在运行,也不会超出启动操作的范围。一种常见的解决方法是确保记录属性更改并更改属性:Session["LOGHACK"] = message;