Installation WIX,Dot-Net管理的自定义操作,用SQL Server实例动态填充组合框,MSI

Installation WIX,Dot-Net管理的自定义操作,用SQL Server实例动态填充组合框,MSI,installation,wix,windows-installer,wix3,Installation,Wix,Windows Installer,Wix3,在WIX am中,需要一个由点网管理的自定义代码,以便用该网络中sql server实例的值动态填充组合框 我试着用谷歌搜索,但什么也没用 非常感谢您的帮助。OP没有要求,但如果有人想知道,是的,您也可以用脚本来完成。本例填充的是一个列表框,而不是一个组合框,但其思想是相同的 [CustomAction] public static ActionResult FillServerInstances(Session xiSession) {

在WIX am中,需要一个由点网管理的自定义代码,以便用该网络中sql server实例的值动态填充组合框

我试着用谷歌搜索,但什么也没用


非常感谢您的帮助。

OP没有要求,但如果有人想知道,是的,您也可以用脚本来完成。本例填充的是一个列表框,而不是一个组合框,但其思想是相同的

    [CustomAction]   
    public static ActionResult FillServerInstances(Session xiSession)
    {         
        xiSession.Log("Begin CustomAction");

        xiSession.Log("Opening view");
        View lView = xiSession.Database.OpenView("DELETE FROM ComboBox WHERE ComboBox.Property='DBSRVR'");
        lView.Execute();

        lView = xiSession.Database.OpenView("SELECT * FROM ComboBox");
        lView.Execute();

        int Index = 1;
        bool flag = false;
        try
        {
            foreach (DataRow dr in Microsoft.SqlServer.Management.Smo.SmoApplication.EnumAvailableSqlServers(false).Rows)
            {
                String InstanceName = dr["Name"].ToString();

                if (InstanceName.Equals(xiSession["ComputerName"] + @"\" + xiSession["SQLINSTANCENAME"], StringComparison.InvariantCultureIgnoreCase))
                { flag = true; }

                Record lRecord = xiSession.Database.CreateRecord(4);
                xiSession.Log("Setting record details");
                lRecord.SetString(1, "DBSRVR");
                lRecord.SetInteger(2, Index);
                lRecord.SetString(3, InstanceName);
                lRecord.SetString(4, InstanceName);

                xiSession.Log("Adding record");
                lView.Modify(ViewModifyMode.InsertTemporary, lRecord);

                ++Index;
            }
        }
        catch (Exception ex)
        {
            logException(xiSession, ex);              
        }
        if (flag)
        {
            xiSession["DBSRVR"] = xiSession["ComputerName"].ToString() + @"\" + xiSession["SQLINSTANCENAME"].ToString();
        }

        lView.Close();

        xiSession.Log("Closing view");
        lView.Close();
        return ActionResult.Success;       
    }
function EnumerateWebSites_CA()
{
    try 
    {
        LogMessage("function EnumerateWebSites_CA() ENTER");

        var c = 1;
        var serverBindings, aBindings;

        var listboxesView = Session.Database.OpenView("SELECT * FROM ListBox");
        listboxesView.Execute();

        var record = Session.Installer.CreateRecord(4);
        record.StringData(1) = "WEBSITE";     // Property
        record.IntegerData(2) = c++;          // display order
        record.StringData(3) = "Server";      // returned by the selection
        record.StringData(4) = "Server-wide"; // displayed in the UI
        listboxesView.Modify(MsiViewModify.InsertTemporary, record);

        // Create this table dynamically.  We could also create this
        // custom table in the WiX .wxs file , but that's not necessary.
        var query = "CREATE TABLE AvailableWebSites " + 
            "(Num INT NOT NULL, Name CHAR(64), Desc CHAR(64), Port CHAR(16) NOT NULL, IP CHAR(32), Hostname CHAR(80) PRIMARY KEY Num)";
        var createCmd = Session.Database.OpenView(query);
        createCmd.Execute();
        createCmd.Close();

        LogMessage("Table 'AvailableWebSites' has been created");

        var websitesView = Session.Database.OpenView("SELECT * FROM AvailableWebSites");
        websitesView.Execute();

        LogMessage("Query from Table 'AvailableWebSites' has returned");

        // do a WMI query to get the list of Websites on the server
        var iis = GetObject("winmgmts://localhost/root/MicrosoftIISv2"); 

        // See the metabase hierarchy diagram here:
        //   http://msdn.microsoft.com/en-us/library/ms524661.aspx

        // http://msdn.microsoft.com/en-us/library/ms525545.aspx
        // list "virtual servers", which is the same as websites. 
        query  = "SELECT * FROM IIsWebServerSetting" 

        // get the list of virtual servers
        var results = iis.ExecQuery(query);

        LogMessage("WMI Query completed.");

        LogMessage("WMI Query results : " + typeof results);

        for(var e = new Enumerator(results); !e.atEnd(); e.moveNext()) 
        { 
            var site = e.item();
            // site.Name                   // W3SVC/1, W3SVC/12378398, etc
            // site.Name.substr(6)         // 1, 12378398, etc
            // site.ServerComment)         // "Default Web Site", "Site2", etc
            // site.ServerBindings(0).Port // 80, 8080, etc

            LogMessage("Web site " + site.Name);

            LogMessage("listbox record");
            record = Session.Installer.CreateRecord(4);
            record.StringData(1) = "WEBSITE";
            record.IntegerData(2) = c++;
            record.StringData(3) = site.Name.substr(6); // site.Name;
            record.StringData(4) = site.ServerComment + " (" + site.Name + ")";
            listboxesView.Modify(MsiViewModify.InsertTemporary, record);

            LogMessage("websites record");
            LogMessage("website(" + site.Name + ") name(" + site.ServerComment + ") port(" + site.ServerBindings(0).Port + ")"); 
            record = Session.Installer.CreateRecord(6);
            record.IntegerData(1) = parseInt(site.Name.substr(6));  // WebSiteNo
            record.StringData(2) = site.Name;                       // name, like W3SVC/1
            record.StringData(3) = site.ServerComment;              // WebSiteDescription
            record.StringData(4) = site.ServerBindings(0).Port;     // WebSitePort
            record.StringData(5) = site.ServerBindings(0).Ip;       // WebSiteIP; maybe empty
            record.StringData(6) = site.ServerBindings(0).Hostname; // WebSiteHeader; maybe empty
            websitesView.Modify(MsiViewModify.InsertTemporary, record);
        }
        listboxesView.Close();
        websitesView.Close();

        LogMessage("function EnumerateWebSites_CA() EXIT");
    }

    catch (exc1)
    {
        Session.Property("CA_EXCEPTION") = exc1.message ;
        LogException(exc1);
        return MsiActionStatus.Abort;
    }
    return MsiActionStatus.Ok;
}
有几种支持方法:

var MsiViewModify = 
{
    Refresh          : 0,
    Insert           : 1,
    Update           : 2,
    Assign           : 3,
    Replace          : 4,
    Merge            : 5,
    Delete           : 6,
    InsertTemporary  : 7,   // cannot permanently modify the MSI during install
    Validate         : 8,
    ValidateNew      : 9,
    ValidateField    : 10,
    ValidateDelete   : 11
};


// http://msdn.microsoft.com/en-us/library/sfw6660x(VS.85).aspx
var Buttons = 
{
    OkOnly           : 0,
    OkCancel         : 1,
    AbortRetryIgnore : 2,
    YesNoCancel      : 3
};

var Icons= 
{
    Critical         : 16,
    Question         : 32,
    Exclamation      : 48,
    Information      : 64
}

var MsgKind =
{
    Error            : 0x01000000,
    Warning          : 0x02000000,
    User             : 0x03000000,
    Log              : 0x04000000
};

// http://msdn.microsoft.com/en-us/library/aa371254(VS.85).aspx
var MsiActionStatus = 
{
    None             : 0,
    Ok               : 1, // success
    Cancel           : 2,
    Abort            : 3,
    Retry            : 4, // aka suspend?
    Ignore           : 5  // skip remaining actions; this is not an error.
};

// spool an informational message into the MSI log, if it is enabled. 
function LogMessage(msg)
{
    var record = Session.Installer.CreateRecord(0);
    record.StringData(0) = "CustomActions: " + msg;
    Session.Message(MsgKind.Log, record);
}

// Pop a message box.  also spool a message into the MSI log, if it is enabled. 
function LogException(exc)
{
    var record = Session.Installer.CreateRecord(0);
    record.StringData(0) = "CustomActions: Exception: 0x" + decimalToHexString(exc.number) + " : " + exc.message;
    Session.Message(MsgKind.Error + Icons.Critical + Buttons.btnOkOnly, record);
}

function decimalToHexString(number)
{
    if (number < 0)
        number = 0xFFFFFFFF + number + 1;
    return number.toString(16).toUpperCase();
}
var MsiViewModify=
{
刷新:0,
插入:1,
更新:2,
分配:3,,
替换:4,
合并:5,
删除:6,
InsertTemporary:7,//安装期间无法永久修改MSI
验证:8,
新版本:9,
验证字段:10,
验证删除:11
};
// http://msdn.microsoft.com/en-us/library/sfw6660x(第85节)
变量按钮=
{
仅限:0,
好:1,,
AbortRetryIgnore:2,
是的取消:3
};
变量图标=
{
关键:16,
问题:32,
感叹号:48,
资料:64
}
var MsgKind=
{
错误:0x01000000,
警告:0x02000000,
用户:0x03000000,
日志:0x04000000
};
// http://msdn.microsoft.com/en-us/library/aa371254(第85节)
变量MsiActionStatus=
{
无:0,,
好的:1,//成功
取消:2,,
中止:3,
重试:4,//是否挂起?
忽略:5//跳过其余操作;这不是错误。
};
//如果已启用,则将信息性消息假脱机到MSI日志中。
功能日志消息(msg)
{
var record=Session.Installer.CreateRecord(0);
record.StringData(0)=“CustomActions:”+msg;
消息(MsgKind.Log,记录);
}
//弹出一个消息框。如果已启用,还将消息假脱机到MSI日志中。
功能日志异常(exc)
{
var record=Session.Installer.CreateRecord(0);
record.StringData(0)=“CustomActions:异常:0x”+decimalToHexString(exc.number)+“:”+exc.message;
Session.Message(MsgKind.Error+Icons.Critical+Buttons.btnOkOnly,记录);
}
函数decimalToHexString(数字)
{
如果(数字<0)
数字=0xFFFFFF+数字+1;
返回编号.toString(16).toUpperCase();
}

是的,我在哲学上和脚本的行为不一致,吸吮< /p> < p>有一个C++ CA来完成这个。