WIX: Где и как мой CustomAction должен создать и прочитать временный файл? - PullRequest
7 голосов
/ 22 марта 2011

У меня есть скрипт CustomAction (Да, я знаю все о мнениях, которые говорят , не используйте скрипт CustomActions . У меня другое мнение.)

Я хотел бы запустить команду и записать вывод. Я могу сделать это с помощью COM-объекта WScript.Shell, затем вызвать shell.Exec(). Но это отображает видимое окно консоли для выполненной команды.

Чтобы избежать этого, я понимаю, что могу использовать вызов shell.Run() и указать «скрытый» для появления окна. Но .Run() не дает мне доступа к StdOut выполняемого процесса, так что это означает, что мне нужно создать временный файл и перенаправить вывод exe во временный файл, а затем прочитать этот временный файл в сценарии.

Некоторые вопросы:

  • это сработает?

  • Как мне создать имя для временного файла? В .NET я мог бы использовать статический метод в пространстве имен System.IO, но здесь я использую скрипт. Мне нужно убедиться, что у пользователя есть доступ к RW, а также, что ни одна антивирусная программа не будет этим заниматься.

  • Лучшие идеи? Я очень стараюсь избегать C / C ++.


Я мог бы избежать всего этого, если бы существовал способ запрашивать сайты в IIS7 из сценария, не прибегая к пакету IIS6 Compatibility, без использования .NET ( Microsoft.Web.Administration.ServerManager ) и без исключения процесса ( список сайтов appcmd ). Я уже задавал отдельный вопрос на эту тему ; Любые предложения по этому вопросу также будут оценены.

1 Ответ

8 голосов
/ 22 марта 2011

Отвечая на мой собственный вопрос ...

  1. да, это будет работать.

  2. Используйте Scripting.FileSystemObject вещь в Javascript.Есть метод GetTempName(), который создает имя файла, пригодное для временного использования, и метод GetSpecialFolder(), который определяет местоположение временной папки.Есть даже BuildPath() метод для их объединения.

  3. пока у меня нет идей получше.

Вот код, который я использовал:

function GetWebSites_IIS7_B()
{
    var ParseOneLine = function(oneLine) {
        ...regex parsing of output...
    };

    LogMessage("GetWebSites_IIS7_B() ENTER");

    var shell = new ActiveXObject("WScript.Shell");
    var fso = new ActiveXObject("Scripting.FileSystemObject");
    var tmpdir = fso.GetSpecialFolder(SpecialFolders.TemporaryFolder);
    var tmpFileName = fso.BuildPath(tmpdir, fso.GetTempName());
    var windir = fso.GetSpecialFolder(SpecialFolders.WindowsFolder);
    var appcmd = fso.BuildPath(windir,"system32\\inetsrv\\appcmd.exe") + " list sites";

    // use cmd.exe to redirect the output
    var rc = shell.Run("%comspec% /c " + appcmd + "> " + tmpFileName, WindowStyle.Hidden, true);
    // WindowStyle.Hidden == 0
    var ts = fso.OpenTextFile(tmpFileName, OpenMode.ForReading);
    var sites = [];

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

    return sites;
}
...