Я использую WixSharp (WiX #) только по тем причинам, которые вы описываете. Я нашел установщик, управляемый XML, слишком уродливым и неинтуитивным, чтобы иметь дело с редактированием файлов XML как способом создания установщика. Я копался в CX на основе WiX # в качестве более доступной альтернативы. В моем случае мне нужно было создать MSI для установки DLL-библиотеки .NET (не в GAC) на сервер, а затем зарегистрировать ее для COM Interop.
Больше информации на домашней странице CodePlex для Wix #: http://wixsharp.codeplex.com/
Для типа установки, описанного в OP, может показаться применимой концепция MSI / WiX «Функции», например, когда пользователь может установить флажок для установки или пропустить определенные функции («функция» может быть набором файлов / программ, набор записей реестра и т. д.)
В установщике WiX # вы объявляете «Feature» с «ID», например, двоичные файлы, документы, registryEntries и т. Д. В верхней части кода установщика C #, а затем ссылаетесь на этот ID Feature при объявлении дополнительных Установщик компонентов. (см. код Wix # «AllInOne» в папке «Samples», которая поставляется вместе с установкой Wix #),
Feature binaries = new Feature("MyApp Binaries");
Feature docs = new Feature("MyApp Documentation");
...
new File(binaries, @"AppFiles\MyApp.exe",
new FileShortcut(binaries, "MyApp", @"%ProgramMenu%\My Company\My Product"),
new FileShortcut(binaries, "MyApp", @"%Desktop%")),
Обратите внимание, что идентификатор компонента «binaries» является первым параметром при объявлении компонентов File и FileShortcut, т. Е. «New File (binaries, ...)», и связывает эти компоненты для включения в идентификатор компонента «binaries».
Кроме того, установщики MSI позволяют указывать идентификаторы функций в командной строке, например,
msiexec / i install.msi ADDLOCAL = двоичные файлы
Также смотрите этот пост: WIX: Как выбрать функции из командной строки
Хотя в WiX есть способы взглянуть на целевую систему и определить, что устанавливать, я не видел примеров Wix #, которые кажутся интуитивно понятными, за исключением возможного использования пользовательских действий (которые поддерживает Wix #). Один из способов адаптации Поведение установщика для целевой системы будет использовать настраиваемые действия для установки свойства, как в примере Wix # «Условная установка» в развертывании Wix #.
//setting property to be used in install condition
new Property("INSTALLDESKTOPSHORTCUT", "no"),
new ManagedAction(@"MyAction", Return.ignore, When.Before, Step.LaunchConditions, Condition.NOT_Installed, Sequence.InstallUISequence));
Который ссылается на этот код ранее в установщике Wix #:
new Dir(@"%Desktop%",
new ExeFileShortcut("MyApp", "[INSTALLDIR]MyApp.exe", "")
{
Condition = new Condition("INSTALLDESKTOPSHORTCUT=\"yes\"") //property based condition
}),
Обратите внимание, что «Условие» в фигурных скобках установлено для проверки свойства «INSTALLDESKTOPSHORTCUT» на значение «да», которое устанавливается в результате пользовательского действия. Код C # для настраиваемого действия выглядит следующим образом.
public class CustomActions
{
[CustomAction]
public static ActionResult MyAction(Session session)
{
if (DialogResult.Yes == MessageBox.Show("Do you want to install desktop shortcut", "Installation", MessageBoxButtons.YesNo))
session["INSTALLDESKTOPSHORTCUT"] = "yes";
return ActionResult.Success;
}
}
Другим способом для набора навыков C # было бы запустить программу установки msi с программой на C #, которая делает что-то вроде этого:
- Посмотрите на настройки пользователя целевой системы, определите, какие функции подходят для установки в этой системе.
- Соберите и отформатируйте командную строку msiexec и параметры объектов для выбранных функций.
- Выполнить командную строку MSIExec.
Вероятно, есть и другие "более аккуратные" способы сделать это, например, с помощью пользовательских действий и т. Д. Однако, исходя из набора навыков C #, этот способ доступен и может помочь с кривой обучения Windows Installer / WiX. Что я нашел, так как работал над установщиками Wix #, так это то, что это помогло мне постепенно освоить некоторые программы установки WiX и Windows. Я часто ищу, как выполнить определенную задачу развертывания в WiX, а затем работаю над переводом Wix-пути в Wix #, чтобы заставить Wix # генерировать нужный XML в создаваемом им файле .wxs.
В тех случаях, когда я не могу понять, как заставить Wix # выполнить определенную задачу развертывания, я часто могу использовать опору простого включения операторов WiX XML в файл .wxs, сгенерированный Wix #, например: отредактировав файл .wxs вручную.
Например, WiX и Wix #, способ предоставления определенного диска и пути, который не является одним из «поддерживаемых» мест назначения, не интуитивен. Я обнаружил, что добавление этого фрагмента xml в сгенерированный файл .wxs из Wix #, а затем запуск вручную Candle, а затем Light, помогли мне.
Я помню, что при запуске работало несколько примеров того, как заставить код Wix # C # программно включать XML в операторы .wxs, а затем компилировать .wxs для генерации msi.Я обновлю этот ответ, если снова найду пример Wix #.
Обновление Я нашел код примера ... Есть пара примеров кода Wix # в Wix #папка примеров, включенная в Wix #.Однако ... они работали не так, как я хотел, и включали дополнительные классы Wix # и объекты, с которыми я еще не был знаком.Я хотел работать с выводом Wix # в виде XML-текста, используя «стандартные» наборы инструментов XML C #, а не классы, специфичные для Wix #.Итак, я попытался выполнить синтаксический анализ XML-документа .wxs и безуспешно использовал XPath для перехода туда, куда я хотел вставить дополнительные операторы WiX XML.(Может быть, я отправлю так вопрос для помощи с этим).Тем не менее, я выполнил то, что хотел, используя текстовую подстановку WiX XML, которая рассматривается как текстовая строка.Вот что я получил, чтобы успешно работать.
Код выполняет назначение делегата событию Compiler.WixSourceSaved, и это событие вызывается как часть того, что происходит при вызове метода "Compiler.BuildMsi"в коде Wix #.После прочтения файла .wxs, который создается (но до того, как файл MSI был создан из wxs), я обновляю текст в файле, чтобы он содержал строки XML, которые я хочу включить.
Затем продолжается последовательность событий Wix # и встраивает измененные wxs в окончательный MSI.
// ...
internal class Script
static string myWIX_SET_DIRECTORY_STATEMENT = " <SetDirectory Id=\"INSTALLDIR\" Value=\"D:\\Program Files\\DOL\\WA.DOL.HQSYS.ExecECL\" />";
static string myWIX_INSERT_AFTER_TEXT = " <InstallExecuteSequence >";
public static void Main()
{
// ... (your other Wix# code goes here...)
// Hook an event to Wix# save of .wxs file to post-process the .wxs
Compiler.WixSourceSaved += PostProcessWxsXMLOutput;
// Trigger the MSI file build
Compiler.BuildMsi(project);
}
/// <summary>
/// Post-process the Wix .wxs file before compiling it into an MSI
/// </summary>
/// <param name="wxsFileName"></param>
private static void PostProcessWxsXMLOutput(string wxsFileName)
{
StreamReader sr = new StreamReader(wxsFileName);
string myWixDocument = sr.ReadToEnd();
sr.Close();
string myProcessedWixDocument = WiXHelpers.InsertFragmentInWiXDocument(myWixDocument, myWIX_INSERT_AFTER_TEXT, myWIX_SET_DIRECTORY_STATEMENT);
StreamWriter sw = new StreamWriter(wxsFileName);
sw.Write(myProcessedWixDocument);
sw.Close();
}
Примечание. Файл .wxs удаляется после завершения BuildMsi.Чтобы принудительно сохранить полученный файл .wxs, вам необходимо добавить строку к вашему коду Wix # после строки Compiler.BuildMsi следующим образом:
Compiler.BuildWxs(Project)
Что на самом делезапустить событие WixSourceSaved, которое затем вызывает мой делегат PostProcessXMLOutput, который создает новую, идентичную содержимому копию файла .wxs.На этот раз файл wxs не удаляется автоматически.Полученный файл wxs также будет иметь более позднюю временную метку, чем соответствующий файл MSI из сборки.