Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lab3.docx
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
3.22 Mб
Скачать

Создание инсталлятора для плагина

Добавим в решение новый проект.

Это будет приложение Windows Forms.

Далее, установим зависимости и порядок построения.

Теперь регистратор будет строится после библиотеки плагина. Назначим его запускаемым проектом.

Немного схитрим и добавим ссылку на библиотеку плагина, дабы она после построения копировалась в директорию к исполняемому файлу регистратора.

Для того, чтобы зарегистрировать нашу библиотеку в реестре, нам потребуется, чтобы регистратор после запуска требовал права администратора. Ведь на Win7 и Vista для этого обычно требуются права администратора – все подряд в реестр писать не могут. В .NET можно сделать так, чтобы запускаемое приложение перед запуском требовало повышения прав. Методику я взял отсюда.

Добавим в проект регистратора файл manifest.xml.

Вставляем туда следующий текст:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity version="1.0.0.0" name="ElevationTest" type="win32"/>

<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">

<security>

<requestedPrivileges>

<requestedExecutionLevel level="requireAdministrator"/>

</requestedPrivileges>

</security>

</trustInfo>

</assembly>

Укажем в свойствах xml-ки, что мы хотим, чтоб файл копировался при построении в выходную директорию.

Теперь откроем свойства проекта регистратора (Alt+Enter), вкладка «События построения». Добавим события после построения следующий код:

"C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\mt.exe" -manifest "$(ProjectDir)manifest.xml" –outputresource:"$(TargetDir)$(TargetFileName)";#1

del "$(TargetDir)manifest.xml"

Этим самым мы назначим манифест нашему приложению и удалим его после этого. Теперь после построения исполняемый файл будет всегда требовать повышения перед запуском.

Добавим несложную форму RegistrationForm.cs в проект регистратора:

Привожу код файла RegistrationForm.Designer.cs:

namespace Plugin3Registrator

{

partial class RegistrationForm

{

/// <summary>

/// Required designer variable.

/// </summary>

private System.ComponentModel.IContainer components = null;

/// <summary>

/// Clean up any resources being used.

/// </summary>

/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>

protected override void Dispose(bool disposing)

{

if (disposing && (components != null))

{

components.Dispose();

}

base.Dispose(disposing);

}

#region Windows Form Designer generated code

/// <summary>

/// Required method for Designer support - do not modify

/// the contents of this method with the code editor.

/// </summary>

private void InitializeComponent()

{

this.register_button = new System.Windows.Forms.Button();

this.unregister_button = new System.Windows.Forms.Button();

this.SuspendLayout();

//

// register_button

//

this.register_button.Location = new System.Drawing.Point(12, 12);

this.register_button.Name = "register_button";

this.register_button.Size = new System.Drawing.Size(336, 23);

this.register_button.TabIndex = 0;

this.register_button.Text = "Register";

this.register_button.UseVisualStyleBackColor = true;

this.register_button.Click += new System.EventHandler(this.register_button_Click);

//

// unregister_button

//

this.unregister_button.Location = new System.Drawing.Point(12, 41);

this.unregister_button.Name = "unregister_button";

this.unregister_button.Size = new System.Drawing.Size(336, 23);

this.unregister_button.TabIndex = 1;

this.unregister_button.Text = "Unregister";

this.unregister_button.UseVisualStyleBackColor = true;

this.unregister_button.Click += new System.EventHandler(this.unregister_button_Click);

//

// RegistrationForm

//

this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);

this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;

this.ClientSize = new System.Drawing.Size(360, 79);

this.Controls.Add(this.unregister_button);

this.Controls.Add(this.register_button);

this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;

this.MaximizeBox = false;

this.MinimizeBox = false;

this.Name = "RegistrationForm";

this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;

this.Text = "Plugin registrator";

this.ResumeLayout(false);

}

#endregion

private System.Windows.Forms.Button register_button;

private System.Windows.Forms.Button unregister_button;

}

}

Копипастите его себе и форма принимает идентичный моему вид. Перейдём к коду формы.

Принцип регистрации плагина будет примерно таким же, каким была регистрация сервера, только значительно проще, ибо плагин будет предоставлять InProc COM server.

Наш плагин является точно таким же сервером. Приложение-хост будет запрашивать с него объект, который реализован на нём. Ведь класс Plugin2.ZigzagPlugin – такой же COM-класс, как и ZigzagControl. Таким образом, когда мы говорим, что наш плагин использует экземпляр ZigzagControl, то сервером является приложение-хост, а клиентом – плагин. Наоборот, когда мы говорим про то, что плагин экспонирует для приложения-хоста класс Plugin2.ZigzagPlugin, то сервером является уже плагин, а клиентом – приложение-хост. Такая вот теория относительности, дамы и господа.

Подключим неймспейсов в файл.

using System.Runtime.InteropServices;

using System.Reflection;

using System.Diagnostics;

Перейдём к классу формы. Добавим туда пути к утилите RegAsm.exe.

const string v4RegAsmPath = @"C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe";

const string v2RegAsmPath = @"C:\Windows\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe";

Потом конструктор:

public RegistrationForm()

{

InitializeComponent();

}

Теперь метод, который вызывает RegAsm с параметрами, переданными в него в качестве аргумента.

/// <summary>

/// Вызывает RegAsm.exe с заданными параметрами.

/// </summary>

/// <param name="param">Параметры запуска RegAsm.exe</param>

/// <returns>Возвращает exit code программы.</returns>

static int CallRegAsm(string param)

{

int result = 0;

ProcessStartInfo info = new ProcessStartInfo();

info.FileName = v4RegAsmPath; //Для регистрации в более ранних версиях Framework используйте переменную v2RegAsmPath

info.Arguments = param;

info.RedirectStandardOutput = true; //В случае, если надо будет отлаживать, вывод regasm.exe можно будет получить в regasm.StandardOutput.ReadToEnd()

info.UseShellExecute = false;

Process regasm = new Process();

regasm.StartInfo = info;

regasm.Start();

regasm.WaitForExit();

result = regasm.ExitCode;

//MessageBox.Show(regasm.StandardOutput.ReadToEnd(), "RegAsm.exe output");

return result;

}

И наконец обработчики нажатия на кнопки.

private void register_button_Click(object sender, EventArgs e)

{

try

{

string path = Environment.CurrentDirectory + "\\Plugin3.dll";

Assembly pluginAssembly = Assembly.LoadFile(path);

//Запустим RegAsm.exe для регистрации интерфейсов сборки и создания библиотеки типов. Для этого сгенерируем параметры запуска.

string assemblyDirectoryPath = pluginAssembly.Location.Remove(pluginAssembly.Location.LastIndexOf('\\') + 1);

string assemblyName = pluginAssembly.Location.Substring(pluginAssembly.Location.LastIndexOf('\\') + 1);

assemblyName = assemblyName.Remove(assemblyName.LastIndexOf('.')); // Получим имя сборки.

// Зададим параметры RegAsm-а, чтобы тут использовал codebase и создавал .tlb-файл с именем сборки

string regasmParams = "\"" + pluginAssembly.Location + "\" /s /codebase /tlb:\"" + assemblyDirectoryPath + assemblyName + ".tlb\"";

int exitCode = CallRegAsm(regasmParams); // Вызовем RegAsm.exe.

if (exitCode != 0)

throw new Exception("RegAsm.exe вернул результат, отличный от нуля. Exit code: " + exitCode.ToString());

MessageBox.Show("Done");

}

catch (Exception exc)

{

string message = "Message: " + exc.Message + "\n\r";

string stack = "Stack trace: " + exc.StackTrace + "\n\r";

MessageBox.Show(message + stack, "На сервере произошло исключение.", MessageBoxButtons.OK, MessageBoxIcon.Error);

}

}

private void unregister_button_Click(object sender, EventArgs e)

{

string path = Environment.CurrentDirectory + "\\Plugin3.dll";

Assembly pluginAssembly = Assembly.LoadFile(path);

string regasmParams = pluginAssembly.Location + " /u";

int exitCode = CallRegAsm(regasmParams);

if (exitCode != 0)

throw new Exception("RegAsm.exe вернул результат, отличный от нуля. Exit code: " + exitCode.ToString());

MessageBox.Show("Done");

}

Каждый из таких обработчиков находит путь к сборке плагина и создаёт соответствующие строки аргументов утилиты RegAsm. Вызов этой утилиты делает за нас всю грязную работу по регистрации сборки плагина в реестре.

Поздравляю, плагин готов, можете тестировать его работоспособность. И пора уже переходить к последней, хардкорной части с Borland Builder-ом.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]