Метод Execute откроет форму мастера и (если пользователь не отменил диалоговое окно) будет использовать свойства формы для вызова нескольких внутренних процедур, отвечающих за генерирование выходного класса:
public void Execute(object Application, int hwndOwner, ref object[]
ContextParams, ref object[] CustomParams, ref wizardResult retval)
{
// Экземпляр диалога для мастера WizardDialog dig = new WizardDialog();
// Показать диалог dig.Show();
i
// Обработать результаты мастера if (dig.DialogResult == DialogResult.OK)
{
// Загрузить файл шаблона, заменить маркеры,
// вернуть содержимое в виде строки
string classContent = ReplaceTokens(dig.ClassName, dig.Category, dig.SubCategory, dig.UseRegistry, dig.RegKey);
// Поместить возвращенную строку в файл и добавить файл в текущий проект // (третий элемент ContextParams — это коллекция элементов // текущего проекта)
Projectltems projltems = (Projectltems)ContextParams[2];
AddFile(classContent, projltems);
retval = wizardResult.wizardResultSuccess;
i
}
// Мастер был отменен; действий не требуется else {
retval = wizardResult.wizardResultCancel;
)
}
Для реакции на нажатие пользователем кнопки ОК вы вызываете три отдельные внутренние процедуры. Первая (ReplaceTokens) открывает файл шаблона класса и заменяет маркеры (поскольку это простой процесс замены строк, то мы не будем приводить здесь этот код).
Вторая процедура (AddFile) пишет новое содержимое класса в новый файл и добавляет его в текущий проект. Поскольку этот код может оказаться не слишком очевидным, вот один из его вариантов:
private void AddFile(string className, string classContent,
Projectltems projltems)
\
{
// Определить путь к файлам проекта string fileName =
Path.GetDirectoryName(projItems.ContainingProject.FileName);
// Использовать путь и имя класса для создания имени файла для класса fileName = fileName + className + ".cs";
// Сохранить файл класса в каталог проекта
using (TextWriter writer = new StreamWriter(fileName, false))
{
wrirer.Write(classContent); writer.Close();
}
// Добавить созданный файл в текущий проект proj Items .Add FromFile (fileName) ;
}
И наконец, вы вызываете UpdateXML. Эта процедура открывает addin-файл и добавляет соответствующий узел <ToolsOptionsPage> в XML-контент:
private void UpdateXml(Projectltems projltems, string category,
string subCategory)
{
// Создать строковый фрагмент XML string xml =
ii и
xml += xml += xml += xml += xml += xml += xml += xml += xml +=
<ToolsOptionsPage>\r\n";
<Category Name=\"" + category + "\">\r\n";
<SubCategory Name=\"" + subCategory + "\">\r\n"; <Assembly></Assembly>\r\n"; <FullClassName></FullClassName>\r\n"; </SubCategory>\r\n";
</Category>\r\n";
</ToolsOptionsPage>\r\n";
</Extensibility>";
// Перебрать элементы проекта в поиске addin-файла string projName = projItems.ContainingProject.FullName; foreach (Projectltem itm in projltems)
{
if (itm.Name == projName + ".addin")
{
// Открыть объект документа addin-файла itm.Document.Activate();
TextDocument txtDoc = (TextDocument) itm. Document. Obj ect ("") ; TextRanges nullObj = null;
// Добавить во фрагмент "категория/подкатегория XML"
txtDoc.ReplacePattern("</Extensibility>", xml,
int)vsFindOptions.vsFindOptionsFromStart, ref nullObj);
}
}
}
/
Теперь код мастера готов.
Создание vsz- и vsdir-файлов
Все, что осталось сделать, — это создать vsz-файл и добавить элемент в vsdir-файл. Файл с расширением vsz прост:
VSWizard 8.0
Wizard=ContosoWizards.ToolsOptionsPageWizard Param=
Запись, которую вы добавляете в vsdir-файл, выглядит следующим образом:
ToolsOptionsPageWizard.vsz | | |1|Create a new Tools Options Page
class|c:\ContosoFramework\Wizards\ToolsOptionsPageWizard.dll| | |Contoso
Options Page Class
Теперь мастер полностью работоспособен, и его можно выбрать в диалоговом окне Add Item.