WIX: Где и как мое CustomAction должно создавать и читать временный файл?

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

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

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

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

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

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

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


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


person Cheeso    schedule 22.03.2011    source источник
comment
минус, да? Это плохой вопрос?   -  person Cheeso    schedule 23.03.2011
comment
Ну, вы начинаете с того, что говорите, что собираетесь использовать JScript, несмотря на советы экспертов, которые вам дали, затем начинаете упоминать проблемы хрупкости, присущие использованию пользовательских действий JScript, а также говорите, что ищете лучшие идеи. Если вам нужна идея получше, поищите в Google список веб-сайтов wix dtf. IIS 7 уже будет иметь .NET, и если класс, который он использует, требует режима совместимости, повторно используйте всю инфраструктуру и просто выберите другой класс.   -  person Christopher Painter    schedule 23.03.2011
comment
Спасибо. Не все IIS7 имеют .NET; насколько мне известно, есть вариант ядра сервера, в котором отсутствует .NET. Если на вопрос нет хорошего ответа, то я полагаю, что это и есть ответ, но я не согласен с тем, что это делает вопрос плохим. Впрочем, вы имеете право на свое мнение. Касательно того, что сценарий — плохая идея, конкретные причины, по которым он не использовал его, меня никогда не затрагивали. Он работает, он удобен и прост в разработке. Если возражения против сценария неуместны, то почему я должен его избегать?   -  person Cheeso    schedule 04.04.2011
comment
Ваш аргумент немного похож на утверждение, что ваш дом никогда не горел, когда вы воткнули пенни в блок предохранителей, и ваш свет работает, так что в этом такого? Я лично испытал болевые точки, о которых упоминает Роб, и могу поручиться, что это не лучшая практика. Я занимаюсь установкой полный рабочий день в течение 15 лет, и я говорю по этому вопросу, исходя из своего опыта.   -  person Christopher Painter    schedule 05.04.2011


Ответы (1)


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

  1. да, это сработает.

  2. Используйте элемент Scripting.FileSystemObject внутри Javascript. Существует метод GetTempName(), который создает имя файла, подходящее для временного использования, и GetSpecialFolder()< /a> метод, который получает расположение временной папки. Существует даже метод 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;
}
person Cheeso    schedule 22.03.2011
comment
о боже! Кто-то тоже проголосовал за мой ответ! Это не только плохой вопрос, но и отсутствие хорошего ответа! хорошо, тогда! - person Cheeso; 11.05.2011