Опубликован: 11.09.2006 | Доступ: свободный | Студентов: 7646 / 472 | Оценка: 4.26 / 3.45 | Длительность: 30:46:00
ISBN: 978-5-9556-0080-2
Лекция 9:

Создание пакетов установки

Изменение пользовательского интерфейса установочного пакета

При создании пакета установки для приложения NotepadC# мы изменяли пользовательский интерфейс форм, предложенных мастером. Среда Visual Studio .NET позволяет также добавлять отдельные формы в диалог установки. Добавим в этот пакет форму с лицензионным соглашением.

Открываем проект NotepadCSharp и снова переходим на вкладку User Interface Editor, щелкнув на одноименной вкладке в окне Solution Explorer. Щелкаем правой кнопкой мыши на группе Start ветви Install и выбираем пункт меню Add Dialog. В появившемся окне шаблонов выделяем форму License Agreement и нажимаем ОК (рис. 9.53).

Форма License Agreement

Рис. 9.53. Форма License Agreement

Теоретически можно добавить любое диалоговое окно в любой раздел проекта установки, но добавление диалогового окна Finish в раздел Start приведет к ошибке компиляции. Лицензионное соглашение обычно появляется сразу после окна приветствия — управлять расположением формы можно, просто перетаскивая ее или используя контекстное меню (рис. 9.54).

Расположение формы в списке

Рис. 9.54. Расположение формы в списке

В свойстве LicenseFile из выпадающего списка выбираем Browse и добавляем файл license.rtf из каталога Code\Glava9\NotepadCSharpSetup\ license.rtf. В этом файле содержится фрагмент стандартного определения прав между производителем и конечным пользователем. Добавим также баннер Bannersetup.bmp, который мы использовали также для оформления других форм. Компилируем проект. Теперь при установке программы появляется окно с лицензионным соглашением (рис. 9.55).

Диалоговое окно с лицензионным соглашением. Попробуйте добавить файл лицензионного соглашения на русском языке

Рис. 9.55. Диалоговое окно с лицензионным соглашением. Попробуйте добавить файл лицензионного соглашения на русском языке

Использование данных, получаемых при установке

При установке некоторых программ требуется определять не только каталог установки, но и другие параметры, необходимые для работы приложения. Рассмотрим использование данных пользователя для пакета, устанавливающего базу данных7Для этого примера вам потребуется установленная СУБД SQL Server . Создайте новую библиотеку (тип проекта — Visual C# Projects, шаблон — Class Library) и назовите ее InstallerClass. В окне Solution Explorer щелкаем правой кнопкой на названии проекта и выбираем пункт меню Add New Item. В появившемся окне выбираем шаблон Installer Class и называем его CustomActionDB (рис. 9.56).

Добавление шаблона Installer Class

Рис. 9.56. Добавление шаблона Installer Class

Удаляем из проекта Class1.cs. В окне Server Explorer на заголовке Data Connection щелкаем правой кнопкой мыши и выбираем пункт Add Connection. В открывшемся окне на вкладке "Подключение" выбираем или вводим название SQL-сервера (для подключения к локальному серверу вводим "(local)"), выбираем для входа в сеть учетные сведения Windows NT, а в выпадающем списке названий баз данных выбираем или вводим master. Завершив настройку соединения, проверяем подключение и нажимаем OK. В окне Solution Explorer щелкаем правой кнопкой на классе CustomActionDB и выбираем View Designer. Из окна Toolbox добавляем объект SqlConnection и в свойстве ConnectionString указываем только что созданное подключение. В окне Solution Explorer щелкаем правой кнопкой на названии проекта и добавляем к нему TextFile, который называем sqlScript.txt (рис. 9.57).

Добавленный текстовый файл sqlScript.txt

Рис. 9.57. Добавленный текстовый файл sqlScript.txt

В этом текстовом файле вводим SQL-запрос на создание таблицы:

CREATE TABLE [dbo].[Employees] (
[Name] [char] (30) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[Rsvp] [int] NULL ,
[Requests] [nvarchar] (4000) COLLATE SQL_Latin1_General_CP1_CI_AS NULL 
) ON [PRIMARY];

ALTER TABLE [dbo].[Employees] WITH NOCHECK ADD 
CONSTRAINT [PK_Employees] PRIMARY KEY CLUSTERED 
(
[Name]
) ON [PRIMARY];

В окне Properties файла sqlScript.txt устанавливаем значение свойства Build Action на Embedded Resource (рис. 9.58):

 Свойство Build Action для файла sqlScript.txt

Рис. 9.58. Свойство Build Action для файла sqlScript.txt

Добавляем в класс CustomActionDB код, считывающий текстовый файл:

/// <summary>
    /// Считывание  текста из файла.
    /// </summary>
    /// <param name="name">Название файла.</param>
    /// <returns></returns>
    private string GetSql(string name)
    {
      try
      {
        // Получаем текущий объект класса Assembly
        System.Reflection.Assembly asm = System.Reflection.Assembly.GetExecutingAssembly();
        // Получаем объект класса Stream к ресурсам текущей сборки.
        System.IO.Stream str = asm.GetManifestResourceStream(asm.GetName().Name + "." + name);
        // Считываем и возвращаем содержимое.
        System.IO.StreamReader reader = new System.IO.StreamReader(str);
        return reader.ReadToEnd();
      }
      catch(Exception ex)
      {
        // Отлавливаем возникшие исключения.
        System.Windows.Forms.MessageBox.Show("В методе GetSql возникла ошибка: "+ex.Message);
        throw ex;
      }    
    }
    /// <summary>
    /// Выполнение SQL-запроса.
    /// </summary>
    /// <param name="databaseName">Название базы данных.</param>
    /// <param name="sql">Текст команды.</param>
    private void ExecuteSql(string databaseName, string sql)
    {
      // Создаем объект класса SqlCommand.
      System.Data.SqlClient.SqlCommand comm = new System.Data.SqlClient.SqlCommand(sql, sqlConnection1);
      // Открываем соединение.
      comm.Connection.Open();
      // Изменяем используемую базу данных.
      comm.Connection.ChangeDatabase(databaseName);
      try
      {
        // Выполняем команду.
        comm.ExecuteNonQuery();
      }
      finally
      {
        // Закрываем соединение.
        comm.Connection.Close();
      }
    }
    /// <summary>
    /// Создание таблицы в базе данных.
    /// </summary>
    /// <param name="databaseName">Название базы данных.</param>
    protected void AddDBTable(string databaseName)
    {      
      try
      {
        // Создаем новую базу данных.
        this.ExecuteSql("master", "CREATE DATABASE " + databaseName);
        // Создаем таблицу в новой базе данных.
        this.ExecuteSql(databaseName, this.GetSql("sqlScript.txt"));
      }
      catch(Exception ex)
      {
        System.Windows.Forms.MessageBox.Show("В методе AddDBTable возникла ошибка: "+ex.Message);
      }
    }
    /// <summary>
    /// Перегружаем метод Install
    /// </summary>
    /// <param name="stateSaver">Параметр по умолчанию.</param>
    public override void Install(IDictionary stateSaver)
    {    
      base.Install (stateSaver);
      // В качестве названия БД передаем введенное значение пользователем.
      this.AddDBTable(this.Context.Parameters["dbname"]);
    }
Листинг 9.1.

Компилируем библиотеку. При этом возникает исключение — класс библиотеки не содержит ссылки на пространство имен Windows:

The type or namespace name 'Windows' does not exist in the class or namespace
 'System' (are you missing an assembly reference?)

Для добавления ссылки на это пространство имен щелкаем правой кнопкой мыши на папке References в окне Solution Explorer и выбираем пункт Add References…(рис.рис. 9.59).

Добавление ссылки на пространство имен

Рис. 9.59. Добавление ссылки на пространство имен

В появившемся списке выбираем пространство имен System.Windows.Forms и добавляем его. Снова компилируем приложение. В окне Solution Explorer щелкаем правой кнопкой на заголовке Solution ‘Installer Class’(1 project) и выбираем Add\New Project. В появившемся окне добавляем проект установки (тип проекта — Setup And Deployment Projects, шаблон – Setup Project) и называем его CustomActionSetup.

Елена Дьяконова
Елена Дьяконова

При нажатии на Сумма в примере ArbitraryMethod из Лекция 7, VS 2013 выдается ошибка: 

Необработанное исключение типа "System.InvalidOperationException" в System.Windows.Forms.dll

Дополнительные сведения: Недопустимая операция в нескольких потоках: попытка доступа к элементу управления "lblResult" не из того потока, в котором он был создан.

Затем:

Необработанное исключение типа "System.InvalidOperationException" в mscorlib.dll

Дополнительные сведения: Для каждой асинхронной операции метод EndInvoke может вызываться только один раз.

Александр Сороколет
Александр Сороколет

Свойство WindowState формы blank Maximized. Не открывается почемуто на всё окно, а вот если последующую форму бланк открыть уже на макс открывается :-/