Как проверить наличие веб-сайта IIS 7 через WiX 3.5? - PullRequest
1 голос
/ 16 ноября 2010

Примечание. Этот вопрос также можно найти в списке рассылки WiX .

Мне нужно иметь возможность проверить наличие веб-сайта IIS7 на основе описания веб-сайта. Если веб-сайт не существует, мне нужно отменить установку. Если сайт существует, я хочу продолжить установку. Мне также нужно иметь возможность сохранить идентификатор сайта, чтобы я мог использовать его во время удаления.

В целях отладки я жестко запрограммировал описание сайта. Я не вижу никаких признаков того, что проверка файла выполняется в лог-файле MSI. Это код, который я использую:

 <iis:WebSite Id="IISWEBSITE" Description="Default Web Site" SiteId="*">
      <iis:WebAddress Id="IisWebAddress" Port="1"/>
 </iis:WebSite>

 <Condition Message="Website [IISWEBSITE] not found.">
      <![CDATA[IISWEBSITE]]>
 </Condition>

Используя ORCA, я вижу, что таблицы MSsWebAddress и IIsWebSite добавлены в MSI. Значения:

IIsWebsite

WEB:         IISWEBSITE
Description: Default Web Site
KeyAddress:  IisWebAddress
Id:          -1

IIsWebAddress

Address: IisWebAddress
Web_:    IISWEBSITE
Port:    1
Secure:  0

При использовании вышеуказанного кода установка останавливается с сообщением об ошибке «Веб-сайт не найден». Похоже, что IISWEBSITE никогда не устанавливается. Хотя я знаю, что «Веб-сайт по умолчанию» существует. Я знаю, что я что-то упускаю, но что?

Как выполнить простую проверку существования веб-сайта в IIS 7?

Ответы [ 2 ]

0 голосов
/ 24 марта 2012

Я написал специальное действие в Javascript, чтобы сделать это.Если вы используете IIS7, вы можете использовать инструмент appcmd.exe и просто вызвать его из Javascript, чтобы получить список сайтов.В теории это довольно просто сделать.Но на практике есть множество обручей, через которые нужно прыгать.

Вот что я придумал:

function RunAppCmd(command, deleteOutput) {
    var shell = new ActiveXObject("WScript.Shell"), 
        fso = new ActiveXObject("Scripting.FileSystemObject"), 
        tmpdir = fso.GetSpecialFolder(SpecialFolders.TemporaryFolder), 
        tmpFileName = fso.BuildPath(tmpdir, fso.GetTempName()), 
        windir = fso.GetSpecialFolder(SpecialFolders.WindowsFolder), 
        appcmd = fso.BuildPath(windir,"system32\\inetsrv\\appcmd.exe") + " " + command, 
        rc;

    deleteOutput = deleteOutput || false;

    LogMessage("shell.Run("+appcmd+")");

    // use cmd.exe to redirect the output
    rc = shell.Run("%comspec% /c " + appcmd + "> " + tmpFileName, WindowStyle.Hidden, true);
    LogMessage("shell.Run rc = "  + rc);

    if (deleteOutput) {
        fso.DeleteFile(tmpFileName);
    }
    return {
        rc : rc,
        outputfile : (deleteOutput) ? null : tmpFileName
    };
}



// GetWebSites_Appcmd()
//
// Gets website info using Appcmd.exe, only on IIS7+ .
//
// The return value is an array of JS objects, one per site.
//
function GetWebSites_Appcmd() {
    var r, fso, textStream, sites, oneLine, record,
        ParseOneLine = function(oneLine) {
            // split the string: capture quoted strings, or a string surrounded
            // by parens, or lastly, tokens separated by spaces,
            var tokens = oneLine.match(/"[^"]+"|\(.+\)|[^ ]+/g),
                // split the 3rd string: it is a set of properties separated by colons
                props = tokens[2].slice(1,-1),
                t2 = props.match(/\w+:.+?(?=,\w+:|$)/g),
                bindingsString = t2[1],

                ix1 = bindingsString.indexOf(':'),
                t3 = bindingsString.substring(ix1+1).split(','),
                L1 = t3.length,
                bindings = {}, i, split, obj, p2;

            for (i=0; i<L1; i++) {
                split = t3[i].split('/');
                obj = {};
                if (split[0] == "net.tcp") {
                    p2 = split[1].split(':');
                    obj.port = p2[0];
                }
                else if (split[0] == "net.pipe") {
                    p2 = split[1].split(':');
                    obj.other = p2[0];
                }
                else if (split[0] == "http") {
                    p2 = split[1].split(':');
                    obj.ip = p2[0];
                    if (p2[1]) {
                        obj.port = p2[1];
                    }
                    obj.hostname = "";
                }
                else {
                    p2 = split[1].split(':');
                    obj.hostname = p2[0];
                    if (p2[1]) {
                        obj.port = p2[1];
                    }
                }
                bindings[split[0]] = obj;
            }

            // return the object describing the website
            return {
                id          : t2[0].split(':')[1],
                name        : "W3SVC/" + t2[0].split(':')[1],
                description : tokens[1].slice(1,-1),
                bindings    : bindings,
                state       : t2[2].split(':')[1] // started or not
            };
        };

    LogMessage("GetWebSites_Appcmd() ENTER");

    r = RunAppCmd("list sites");
    if (r.rc !== 0) {
        // 0x80004005 == E_FAIL
        throw new Exception("ApplicationException", "exec appcmd.exe returned nonzero rc ("+r.rc+")", 0x80004005);
    }

    fso = new ActiveXObject("Scripting.FileSystemObject");
    textStream = fso.OpenTextFile(r.outputfile, OpenMode.ForReading);
    sites = [];

    // Read from the file and parse the results.
    while (!textStream.AtEndOfStream) {
        oneLine = textStream.ReadLine();
        record = ParseOneLine(oneLine);
        LogMessage("  site: " + record.name);
        sites.push(record);
    }
    textStream.Close();
    fso.DeleteFile(r.outputfile);

    LogMessage("GetWebSites_Appcmd() EXIT");

    return sites;
}
0 голосов
/ 29 января 2011

У меня тоже была такая же проблема.

Я написал специальное действие для проверки версии IIS из реестра.

На основе значения реестра создайте виртуальный каталог

...