65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Click Once 恢复 SQL Server Express 2008 数据库

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.95/5 (18投票s)

2010年11月15日

CPOL

12分钟阅读

viewsIcon

84505

downloadIcon

4

使用 Click Once 恢复 SQL Server Express 2008 数据库

引言

我来告诉你们一件很有趣的事情。你们知道,可以使用 Click Once 安装必需的先决条件。例如 .NET Framework、Windows Installer 或 SQL Server Express 2008。但是,Visual Studio 2010 不支持通过 SQL Server 2005 或 2008 恢复数据库。

你们在网上找不到关于此问题的完整参考指南。有很多关于 Click Once、Bootstrapper Manifest Generator 或 Setup Project 的文章。现在,我将在一个解决方案中一步一步地讲解这个项目的每个部分。

你们可以在页面顶部找到此项目的下载链接。可以使用 VS 2010 打开它来分析项目。Setup.rar 包含示例数据库、Bootstrapper Manifest Generator 设置以及该项目的源代码。

好的。这是我们的路线图

  1. 备份 SQL 数据库
  2. 创建类库连接到数据库
  3. 创建使用先前创建的类库的 MSI 包
  4. 使用 Bootstrapper 作为 VS 2010 的先决条件
  5. 并通过 Click Once 分发

备份 SQL 数据库

  1. 打开 SQL Server Management Studio。右键单击数据库,选择“任务”->“备份”

    Backup_01.jpg

  2. 在打开的窗口中,选择“添加”->“...”(三个点),然后指向备份目录。在“文件名”部分写入数据库名称。例如:HaliYikama.bak

    Backup_02.jpg

注意

我想提醒你们一下。如果你们将数据库命名为与原始数据库名称不同的名称,那么在恢复数据库时会遇到问题。请将备份文件名命名为你们的数据库名称。

通常,备份文件名可以任意命名(例如:包含日期时间)。因为你们是在同一个硬盘和位置恢复它。但是在本项目中,远程计算机的位置可能与你们的备份位置不同。

今日赠品

这些部分与本项目无关。我想给你们一个小贴士!

如果你们将数据库恢复到与备份文件原始位置不同的位置怎么办?

打开 SQL Query Analyzer 并运行此命令

restore FILELISTONLY from disk = 
'C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\
Backup\VeritabaniBackup.bak'

它会在第一列给出数据库的 LogicalName。然后在下面的语句中将你们的 LogicalName 替换为粗体部分

restore database Veritabanim
from disk = 'C:\Program Files\Microsoft SQL Server\
MSSQL10.MSSQLSERVER\MSSQL\Backup\HaliOtomasyonu.bak'
with move 'LogicalName' to 'C:\Program Files\
Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\Backup\Test\Veritabanim.mdf',
move 'LogicalName_log' to 'C:\Program Files\
Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\Backup\Test\Veritabanim_log.ldf'

创建类库以连接到数据库

本项目旨在连接数据库并恢复它。

  1. 首先,我们需要为所有项目创建一个空解决方案。打开 Visual Studio 2010,选择“新建项目”。从左侧,选择“其他项目类型”->“Visual Studio 解决方案”。在“名称”部分写入 ClickOnceSQL。

    Class_01.jpg

  2. 现在,我们来创建类库。右键单击我们刚刚创建的解决方案,选择“添加”->“新建项目”。

    Class_02.jpg

    在打开的窗口中,选择“Visual C#”->“类库”,并将其命名为 CreatingDB

    Class_03.jpg

  3. 删除项目自动创建的 Class1.cs 文件。然后添加安装程序类,如下所示:右键单击项目,选择“添加”->“新项”。然后选择“Visual C# 项”->“安装程序类”,并将其命名为 Installer1.cs。最后按“添加”按钮完成此部分。

    Class_04.jpg

  4. 单击“单击此处切换到代码视图”语句以进入代码隐藏。

好的。现在,我想谈谈 SMO 对象。Microsoft.SqlServer.Management.Smo 命名空间包含表示 SQL Server 数据库引擎核心对象的类。这些对象包括实例、数据库、表、存储过程和视图。

Microsoft.SqlServer.Management.Smo 命名空间中的大多数类都位于 Microsoft.SqlServer.Smo.dllMicrosoft.SqlServer.SmoExtended.dll 文件中。此外,一些枚举类位于 Microsoft.SqlServer.SqlEnum.dllMicrosoft.SqlServer.SmoEnum.dll 程序集文件中。你们需要导入所有四个文件才能访问 Microsoft.SqlServer.Management.Smo 命名空间中的所有类。

使用 Microsoft.SqlServer.Management.Smo 命名空间,你们可以执行以下操作

  • 连接到 SQL Server 数据库引擎的实例。
  • 查看和修改实例设置和配置选项。
  • 查看和修改数据库对象。
  • 在 SQL Server 数据库引擎实例上执行 DDL(数据定义语言)任务。
  • 脚本数据库依赖项。
  • 执行数据库维护任务,例如备份和还原操作。
  • 迁移数据库架构和数据。

将这些程序集作为引用添加到你们的项目中。你们可以在 C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies 路径下找到这些对象。

  • Microsoft.SqlServer.ConnectionInfo
  • Microsoft.SqlServer.Management.Sdk.Sfc
  • Microsoft.SqlServer.Smo
  • Microsoft.SqlServer.SmoExtended

此外,你们还应该添加 System.Windows.Forms 作为引用(在 .NET 部分)。

好了

using System.Data.SqlClient;
using System.IO;
using System.Security.AccessControl;
using System.Windows.Forms;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;

namespace CreatingDB
{
[RunInstaller(true)]
public partial class Installer1 : System.Configuration.Install.Installer
{
public Installer1()
{
InitializeComponent();
}

public void RestoreDatabase(String databaseName, String filePath, String serverName,
    String userName, String password, String dataFilePath, String logFilePath)
{
// Create Restore instance
Restore sqlRestore = new Restore();

// Point to database
BackupDeviceItem deviceItem = new BackupDeviceItem(filePath, DeviceType.File);
sqlRestore.Devices.Add(deviceItem);
sqlRestore.Database = databaseName;

// Connect to DB Server
ServerConnection connection;

if (userName == "") // for Windows Authentication
{
SqlConnection sqlCon = new SqlConnection(@"Data Source=" + serverName + @"; 
Integrated Security=True;");
connection = new ServerConnection(sqlCon);
}
else // for Server Authentication
connection = new ServerConnection(serverName, userName, password);

// Restoring
Server sqlServer = new Server(connection);
Database db = sqlServer.Databases[databaseName];
sqlRestore.Action = RestoreActionType.Database;
String dataFileLocation = dataFilePath + databaseName + ".mdf";
String logFileLocation = logFilePath + databaseName + "_Log.ldf";
db = sqlServer.Databases[databaseName];
RelocateFile rf = new RelocateFile(databaseName, dataFileLocation);
sqlRestore.RelocateFiles.Add(new RelocateFile(databaseName, dataFileLocation));
sqlRestore.RelocateFiles.Add(new RelocateFile(databaseName + "_log", logFileLocation));
sqlRestore.ReplaceDatabase = true;
sqlRestore.PercentCompleteNotification = 10;

try
{
sqlRestore.SqlRestore(sqlServer);
}
catch (Exception ex)
{
MessageBox.Show(ex.InnerException.ToString());
}

db = sqlServer.Databases[databaseName];
db.SetOnline();
sqlServer.Refresh();
}

public override void Commit(System.Collections.IDictionary savedState)
{
// Required permission
try
{
DirectorySecurity dirSec = Directory.GetAccessControl(Context.Parameters["TargetDir"]);
FileSystemAccessRule fsar = new FileSystemAccessRule
(@"NT AUTHORITY\NETWORK SERVICE"
, FileSystemRights.FullControl
, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit
, PropagationFlags.None
, AccessControlType.Allow);
dirSec.AddAccessRule(fsar);
Directory.SetAccessControl(Context.Parameters["TargetDir"], dirSec);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}

// Parameters that comes from setup project (CreatingDBSetup) 
RestoreDatabase(Context.Parameters["databaseName"].ToString(), 
    Context.Parameters["filePath"].ToString(), Context.Parameters
["serverName"].ToString(), Context.Parameters["userName"].ToString(), 
    Context.Parameters["password"].ToString(), Context.Parameters
["dataFilePath"].ToString(), Context.Parameters["logFilePath"].ToString());

base.Commit(savedState);
}
}
}

创建使用先前创建的类库的 MSI 包

我们已经完成了上面的困难部分。现在,我们将其打包为 MSI 进行分发。

右键单击解决方案(ClickOnceSQL),选择“添加”->“新建项目”。在打开的窗口中,选择“其他项目类型”->“设置和部署”->“Visual Studio Installer”->“Setup Project”。将其命名为 CreatingDBSetup ,然后单击“确定”完成。

MSI-Setup-01.jpg

当新打开的页面时,你们会看到“文件系统”(CreatingDBSetup)选项卡。如果没有,请在“解决方案资源管理器”顶部选择“文件系统编辑器”图标。

MSI-Setup-00.jpg

右键单击“应用程序文件夹”,选择“添加”->“项目输出”。

MSI-Setup-01.jpg

你们会看到 CreatingDB 和“主要输出”已选中。不要更改它。单击“确定”应用设置。

MSI-Setup-02.jpg

正如下面图片所示,必需的依赖项已自动加载。现在,我们应该添加数据库备份文件。右键单击面板中的空白区域,选择“添加”->“文件”。

MSI-Setup-03.jpg

指向数据库备份文件(HaliYikama.bak)。

MSI-Setup-04.jpg

接下来,我们为还原的数据库 .mdf.ldf 创建一个文件夹。右键单击“应用程序文件夹”,选择“添加”->“文件夹”,并将其命名为 Database。然后,单击 Database 文件夹,打开属性窗口(F4),并将 AlwaysCreate 属性设置为 True

MSI-Setup-05.jpg

接下来,是时候将参数传递给上一个名为 CreatingDB 的项目中的安装程序类(Installer1.cs)了。这些参数将进入方法名为 public override void Commit 部分,作为 Context.Parameters。这些参数包含服务器名称、数据库名称等。

好的。当你们在“解决方案资源管理器”中单击 CreatingDBSetup 时,会在“解决方案资源管理器”顶部看到“自定义操作编辑器”。单击它。你们会在页面左侧看到“自定义操作”(CreatingDBSetup)窗格。

MSI-Setup-06.jpg

正如你们所见,有四个文件夹,名为“安装”、“提交”、“回滚”、“卸载”。我们对每个文件夹重复以下操作。右键单击“安装”文件夹,选择“添加自定义操作”。单击“应用程序文件夹”以进入。选择 CreatingDB (活动)的“主要输出”,然后单击“确定”应用设置。

MSI-Setup-07.jpg

你们会在“安装”文件夹下看到 CreatingDB (活动)的“主要输出”部分。单击它一次,然后按 F4 查看其属性。在第三行有一个 CustomActionData 属性。写入以下 string

/TargetDir="[TARGETDIR]\" /databaseName="HaliYikama" 
/filePath="[TARGETDIR]HaliYikama.bak" /serverName=".\SQLEXPRESS" 
/userName="" /password="" /dataFilePath="[TARGETDIR]Database\\" 
/logFilePath="[TARGETDIR]Database\\"

MSI-Setup-08.jpg

好的。现在,第一个部分已完成。对剩余的 3 个文件夹(CommitRollbackUninstall)重复以上步骤。

注意

先决条件的安装顺序对于本项目而言是一个非常重要的问题。因为,如果你们在安装 SQL Server 2008 之前安装 Restore DB 设置,你们将会失败。因此,我将在下面第四部分“注意”标签下告诉你们一些关键配置。

使用 Bootstrapper 作为 VS 2010 的先决条件

我们使用 BMG 来扩展 Visual Studio 2010 的先决条件容量。Setup 程序是一个通用的安装程序,可以配置为检测和安装可再发行组件,例如 Windows Installer(.msi)文件和可执行程序。该安装程序也称为引导程序。它通过一组 XML 清单进行编程,这些清单指定了管理组件安装的元数据。引导程序首先检测任何先决条件是否已安装。如果未安装先决条件,则引导程序会显示许可协议。其次,在最终用户接受许可协议后,开始安装先决条件。否则,如果检测到所有先决条件,引导程序将直接启动应用程序安装程序。

你们可以从 http://code.msdn.microsoft.com/bmg/Release/ProjectReleases.aspx?ReleaseId=1567 下载 BMG。单击 BMG2008Setup.msi 开始下载。下载后安装它。你们可以在桌面上看到程序的快捷方式。打开程序。选择“文件”-“新建”-“包清单”,然后单击“确定”关闭窗口。

Package-01.jpg

在打开的窗口中,将项目名称设置为 Restore DB。产品代码也会自动填充。不要更改。

单击屏幕左上角的“添加安装文件”图标。选择“浏览”并指向你们 MSI 包的发布版本(例如:D:\My Projects\Visual Studio 2010\ClickOnceSQL\CreatingDBSetup\Release)。单击“确定”完成此部分。

Package-02.jpg

在“显示名称”部分写入 Restore DB。然后,单击屏幕顶部第二的“生成”图标。在新建的窗口中完成生成过程。

Package-03.jpg

你们可以在新建窗口的顶部看到生成的包位置。C:\Users\Ferhat\Documents\Restore DB 是我用于此示例项目的路径。打开此位置,向上移动一个级别,然后复制整个(Restore DB)文件夹。然后将其粘贴到 C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bootstrapper\Packages 文件夹中,以便 VS 2010 识别新的先决条件。好了,我们完成了 Bootstrapper 操作。重启 VS 2010 以使用新的先决条件。

注意

现在,我们正处于最关键的配置阶段。请仔细阅读并按照我的指示进行操作。

先决条件的安装顺序对于此部署项目非常重要。但是 VS 2010 也无法通过其用户界面支持安装顺序。我们通过一些 XML 更改来实现这一点。

首先,我们应该理解 product.xml 的 XML 格式。打开 C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bootstrapper\Packages\ 下的 SqlExpress2008 文件夹。你们会看到 product.xml 文件。打开它并仔细查看。

<?xml version="1.0" encoding="utf-8"?>
<!-- SQL Express 2008 VS Bootstrapper : product.xml : Language neutral information -->
<Product xmlns=http://schemas.microsoft.com/developer/2004/01/bootstrapper 
	ProductCode="Microsoft.Sql.Server.Express.10.0">
<RelatedProducts>
<EitherProducts>
<DependsOnProduct Code=".NETFramework,Version=v4.0" />
<DependsOnProduct Code="Microsoft.Net.Framework.3.5.SP1" />
</EitherProducts>
<DependsOnProduct Code="Microsoft.Windows.Installer.4.5" />
<IncludesProduct Code="Microsoft.Sql.Server.Express.1.0" />
<IncludesProduct Code="Microsoft.Sql.Server.Express.9.2" />
</RelatedProducts>
<PackageFiles>
<PackageFile Name="SqlExpressChk.exe" />
</PackageFiles>
</Product>

有一个 DependsOnProduct 节点,它定义了必需的安装。Code 属性指向 XML 文件顶部的 Product 节点中的 ProductCode。例如

<Product xmlns=http://schemas.microsoft.com/developer/2004/01/bootstrapper 
	ProductCode="Microsoft.Sql.Server.Express.10.0">

好的。打开你们的 product.xmlC:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bootstrapper\Packages\Restore DB)并添加以下节点

<RelatedProducts>
<DependsOnProduct Code="Microsoft.Sql.Server.Express.10.0" />
</RelatedProducts>
</Product>

最后,product.xml 文件应该是

<?xml version="1.0" encoding="utf-8"?>
<Product ProductCode="Restore.DB" 
xmlns="http://schemas.microsoft.com/developer/2004/01/bootstrapper">
<PackageFiles CopyAllPackageFiles="false">
<PackageFile Name="creatingdbsetup.msi" Hash="31E40D0C5D7BCA642E412EABF16E4C381EB7ADEB" />
</PackageFiles>
<Commands Reboot="Defer">
<Command PackageFile="creatingdbsetup.msi">
<ExitCodes>
<DefaultExitCode Result="Success" String="Anunexpectedexitcodewasr" 
FormatMessageFromSystem="true" />
</ExitCodes>
</Command>
</Commands>
<RelatedProducts>
<DependsOnProduct Code="Microsoft.Sql.Server.Express.10.0" />
</RelatedProducts>
</Product>

请小心!

如果你们的 product.xml 与上面的不同,则安装将失败。如果你们不将 product.xml 更改为如上所示,或者将其保留为原始状态,你们发布的“Click Once”屏幕将变成这样

Prerequisites-Order-01.jpg

如你们所见,Restore DB 放在了 SQL Server 2008 Express 安装之前。在 product.xml 配置之后,我们的 ClickOnce 发布屏幕将变成这样

Prerequisites-Order-02.jpg

是的!这就是我们期待的。:)

以及通过 Click Once 分发

在本节中,我将提到 ADO.NET Entity Data Model 和 WPF Windows 应用程序。但这些概念不属于本文。简而言之,我想创建一个连接到本地数据库的数据层。你们可以选择 Windows Forms 而不是 WPF,并选择 LINQ to SQL Classes 而不是 ADO.NET Entity Framework。

我向解决方案中添加了一个名为 CreatingDB.Data 的新项目,类型为类库。这是我的 WPF 应用程序的数据层。之后,我添加了 ADO.NET Entity Data Model 以通过 Windows 身份验证连接本地数据库。

现在,只剩下一个项目要添加了。我向解决方案中添加了另一个名为 CreatingDB.WPF 的项目,类型为 WPF 应用程序。该项目使用 CreatingDB.Data 来连接数据库。因此,我通过“添加引用”-“项目”选择来添加 CreatingDB.Data 作为引用。

另外,我还应该添加 System.Data.Entity 命名空间(通过“添加引用”-“.NET”)以使用 Entity Framework。最后,我向 WPF 项目添加了应用程序配置文件(App.config)以覆盖 CreatingDB.Data 的连接字符串。并将 CreatingDB.Data App.Config 的内容复制到 CreatingDB.WPF App.Config

好的。是时候设计用户界面了。

这是我的 WPF 表单设计部分

<DataGrid AutoGenerateColumns="False" Height="80" 
	HorizontalAlignment="Left" Margin="35,70,0,0" Name="dataGrid1" 
VerticalAlignment="Top" Width="323" ItemsSource="{Binding}" >

<DataGrid.Columns>
<DataGridTextColumn Header="Adi" Width="135" Binding="{Binding Name}" IsReadOnly="True"/>
<DataGridTextColumn Header="Adresi" Width="135" 
	Binding="{Binding Address}" IsReadOnly="True"/>
</DataGrid.Columns>
</DataGrid>

这是代码隐藏部分

private void button1_Click(object sender, RoutedEventArgs e)
{
try
{
CreatingDB.Data.HaliYikamaEntities context = new Data.HaliYikamaEntities();
dataGrid1.DataContext = context.CustomerSet;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}

右键单击 WPF 项目,选择“设为启动项目”,然后进行编译。检查是否有错误。如果没有错误,当你们单击按钮时,将会看到记录。

注意

在你们的开发机器上,SQL Server Enterprise 或 Developer 版本,你们的连接字符串应该被更改,因为在此“Click Once”项目中,客户端机器始终使用 SQL Server Express 版本。查看 WPF 项目下的 App.config 文件中的连接字符串。

将 Data Source=.\; 语句替换为 Data Source=.\SQLEXPRESS;

最后,你们的 WPF(Windows App)App.config 文件应该如下所示

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add name="HaliYikamaEntities" connectionString= 
"metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;
provider=System.Data.SqlClient;provider connection string="Data Source=.\SQLEXPRESS;
Initial Catalog=HaliYikama;Integrated Security=True;
MultipleActiveResultSets=True"" providerName="System.Data.EntityClient" />
</connectionStrings>
</configuration>

接下来,我们将发布项目。请重置你们的 Visual Studio 以识别新的先决条件(Restore DB),右键单击 WPF 项目。选择“属性”,切换到“发布”选项卡,单击“先决条件”按钮。你们会看到 Restore DB,选择它,以及 SQL Server 2008 Express。还有一个由系统选择的复选框:Microsoft .NET Framework 4 Client Profile(x86 和 x64)和 Windows Installer。不要更改。最终,有 4 个先决条件被选中。单击“确定”应用设置。

Prerequisites-01.jpg

单击“更新”按钮,并选择“应用程序应检查更新”复选框,以便在你们更新应用程序时告知用户。单击“确定”应用你们的选择。

Prerequisites-02.jpg

接下来,单击页面底部的“发布向导”以发布你们的项目。选择“浏览”并指向你们新创建的空目录(例如:publish)

Publish-01.jpg

单击“下一步”,你们的问题是“用户将如何安装应用程序?”我们倾向于选择网站(它为我们提供了易于更新的应用程序)。

Publish-02.jpg

单击“下一步”,问题是“应用程序是否可离线使用?”我们选择“是”。

Publish-03.jpg

单击“完成”以完成发布过程。通过 FTP 将你们的“publish”文件夹上传到你们的网站。现在,你们可以像这样安装你们已发布的项目:http://www.fkaratas.com/app/publish.htm

当你们打开 URL 时,会看到“安装”按钮。请单击它以开始安装。同时,在消息框出现时选择“运行”。

Prerequisites-Order-02.jpg

这是安装顺序。第一个屏幕是 Microsoft .NET Framework 4 Client Profile(x86 和 x64),单击“接受”以继续。(如果你们已经安装了 .NET Framework,将不会看到此屏幕)

Installation-01.jpg

我的测试机器是 XP Service Pack 3。因此,Windows Installer 3.1 的安装屏幕对我来说不会出现。如你们所知,这是 Click Once 部署的概念。

第二个屏幕是 SQL Server 2008 Express,请单击“接受”以继续。

Installation-02.jpg

最后一个屏幕是“Restore DB”。选择“安装”以继续。

Installation-03.jpg

现在,下载开始...

Installation-04.jpg

下载完成后,安装会自动开始。在 .NET Framework 安装完成后,机器会提示你们重启 PC。请选择“是”以继续安装。

Installation-05.jpg

重启后,SQL Server 2008 Express 和 Restore DB 安装将开始。

Installation-06.jpg

当所有先决条件都完成后,我们的 Windows 应用程序将启动。

我希望本文能对有需要的开发者有所帮助。

© . All rights reserved.