Создание инсталлятора для WPF приложения, работающего с локальной БД на SqlServer'е
Задача: Необходимо создать инсталлятор для WPF приложения, которое взаимодействует с локальной базой данных на Sql Server'e.
Дано: База данных, которая лежит на сервере, в который я вхожу следующим образом - имя_компьютера\SQLEXPRESS
и приложение, которое к ней подключается (точнее имеющее такую строку подключения):
<connectionStrings>
<add name="ConnectionString"
connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=ChessTrainerDB;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
На данный момент, чтобы установить приложение к себе на компьютер пользователю необходимо:
1.Скачать проект с гитхаба.
2.Восстановить с помощью дампа базу данных в SQL Server.
3.Запустить .exe файл и пользоваться программой.
Найти: Я же хочу сделать установщик для приложения, чтобы пользователь просто установил через exe'шник приложение и пользовался им.
После гугления и поиска по ruSO я нашел следующее - https://www.cyberforum.ru/wpf-silverlight/thread1337712.html и Как создать инсталляционный пакет (дистрибутив) для разработанного приложения WPF? . По первой ссылке точно такой же вопрос как у меня, но там нет нормального ответа на вопрос (предлагается сделать через субд access), по второй же ссылке, как я понял, способ подходит только для приложения без БД (возможно я неправильно понял?).
Решение: Итак, какие именно я вижу пути для решения? Их два:
1 - Есть способ в инсталятор запихнуть базу данных и сделать так, чтобы она разворачивалась на компьютере пользователя при установке (но я этот способ просто не нашел)
2 - Либо использовать не SqlServer, а создать базу в SqlLite и уже с SqlLite делать инсталлятор (никогда не работал с SqlLite, прошу скинуть ссылки на какие-то материалы по созданию инсталлятора с SqlLite + по переносу базы данных с SqlServer'а в SqlLite)
Конечно можно было бы сделать не локальный сервер, но этот вариант, к сожалению, мне не подходит.
UPD: Попробовал сделать установщик с помощью ClickOnce и запустил его на виртуалке, приложение открывается, но как только выполнение доходит до взаимодействия с бд (авторизация в системе) приложение вылетает.
Ответы (2 шт):
Сразу уточню. Что я только добрался до внедрения базы данных, и столкнулся с тем же вопросом. Не успел полноценно протестировать данное решение. И тем более сделать на его основе свой установщик. Есть такой инструмент как "Wix" он создает инсталятор .msi https://wixtoolset.org/documentation/. Сам по себе он сложен в освоении, использует XML синтаксис. На его основе есть WixSharp https://github.com/oleg-shilo/wixsharp. Позволяет использовать синтаксис C# напрямую.
Порядок примерно такой:
- Устанавливаешь сам Wix
- Шаблоны WixSharp для Visual Studio https://marketplace.visualstudio.com/items?itemName=OlegShilo.WixSharpProjectTemplates В них присутствует шаблон "WixSharp Managed Setup - Custom WPF UI"
Сборка проекта приводит к создаению установочного пакета .msi. (почти код из шаблона)
var project = new ManagedProject("SSHF", new Dir(@"%ProgramFiles%\My Company\My Product", Files.FromBuildDir("")));
project.GUID = new Guid("524EE9BC-83E6-4F0D-917E-6A4C69A4DDD4");
project.ManagedUI = ManagedUI.DefaultWpf; // all stock UI dialogs
//custom set of UI WPF dialogs
project.ManagedUI = new ManagedUI();
project.ManagedUI.InstallDialogs.Add<WixSharp_Setup1.WelcomeDialog>()
.Add<WixSharp_Setup1.LicenceDialog>()
.Add<WixSharp_Setup1.FeaturesDialog>()
.Add<WixSharp_Setup1.InstallDirDialog>()
.Add<WixSharp_Setup1.ProgressDialog>()
.Add<WixSharp_Setup1.ExitDialog>();
project.ManagedUI.ModifyDialogs.Add<WixSharp_Setup1.MaintenanceTypeDialog>()
.Add<WixSharp_Setup1.FeaturesDialog>()
.Add<WixSharp_Setup1.ProgressDialog>()
.Add<WixSharp_Setup1.ExitDialog>();
project.SourceBaseDir = @"C:\Work\Studio\SSHF\Base\SSHF\bin\Release\net6.0-windows10.0.19041.0\publish\win-x64";
project.OutDir = @"D:\Новая папка\";
project.BuildMsi();
Потенциально должно работать.
2.Восстановить с помощью дампа базу данных в SQL Server.
Процесс восстановления БД из резервной копии вполне можно автоматизировать. Создаем резервную копию базы (.bak), вкладываем ее в дистрибутив. Затем делаем примерно такой скрипт для восстановления:
USE [master]
RESTORE DATABASE [MyDB]
FROM DISK = N'C:\Path\MyDB.bak'
WITH FILE = 1, MOVE N'MyDB' TO N'C:\DATA\MyDB.mdf',
MOVE N'MyDB_log' TO N'C:\DATA\MyDB_Log.ldf', NOUNLOAD, STATS = 5
Скрипт можно выполнить при первом запуске из C#, с помощью обычного API SqlCommand. Либо можно запустить его через sqlcmd из инсталлятора, команда выглядит примерно так:
sqlcmd -S myServer\instanceName -i C:\Path\myScript.sql
Например, если вы делаете инсталлятор через Inno Setup, нужно добавить секцию Run такого вида:
[Run]
Filename: "sqlcmd"; Parameters: "-S myServer\instanceName -i {app}\myScript.sql"
Вообще, если в программе один пользователь и ей не нужны возможности полноценного SQL Server, действительно логичнее использовать SQLite/Access/SQL Server Compact, в которых для развертывания БД достаточно копирования файла.
