背景:去年曾经开发过一款基于单机版的进销存系统,是基于sqlexpress 2005 数据库。考虑到时单机版,所以在打包的时候将sqlexpress 也直接打到压缩包中了,这样比较方便,完全自动安装,包括初始化数据库,初始化数据都是些在代码当中,客户在安装的时候只需要点下一步即可。
新需求:要求曾经的单机版程序需要在局域网内访问。
解决办法:系统分为两个版本,服务版安装数据库,客户版不安装数据库。将服务版sqlexpress数据库开启远程服务,然后客户版连接服务版上的数据库。
新问题:用户计算机水平非常低,又不能全部上门服务,要求所有操作通过代码自动实现。
1. 设置sqlexpress数据库允许通过账号混合模式验证登陆(默认是windows身份验证)
以下为实现代码:
RegistryKey hklm = Registry.LocalMachine;
RegistryKey MSSQLServer = hklm.OpenSubKey("SOFTWARE", true)
.OpenSubKey("Microsoft", true)
.OpenSubKey("Microsoft SQL Server", true)
.OpenSubKey("MSSQL.1", true)
.OpenSubKey("MSSQLServer", true);
MSSQLServer.SetValue("LoginMode", 2);
2. 设置sqlexpress数据库允许远程连接访问(开启TCP/IP访问协议)
以下为实现代码:
RegistryKey Tcp = MSSQLServer.OpenSubKey("SuperSocketNetLib", true)
.OpenSubKey("Tcp", true);
Tcp.SetValue("Enabled", 1);
3. 使系统sa账号可用,并设置sa的密码为sa2005(默认sa状态为不可用)
以下为实现代码:
string strConn = @"Data Source=(local)\SQLEXPRESS;Initial Catalog=master;";
strConn += "trusted_connection=sspi;Connect Timeout=30";
SqlConnection conn = null;
try
{
conn = new SqlConnection(strConn);
conn.Open();
SqlCommand command = new SqlCommand("Alter LOGIN sa ENABLE ; Alter LOGIN sa WITH PASSWORD = 'sa2005' ; ", conn);
command.ExecuteNonQuery();
}
catch (Exception ex)
{
}
finally
{
if (conn != null)
{
conn.Close();
}
}
4. 重新启动服务,并将服务设置为Automatic。
以下为实现代码:
ServiceControllerEx scEx = new ServiceControllerEx("SQL Server Browser");
scEx.StartupType = "Automatic";
if (scEx.Status != ServiceControllerStatus.Running)
{
scEx.Start();
}
ServiceControllerEx SQLServer = new ServiceControllerEx("SQL Server (SQLEXPRESS)");
if (SQLServer.Status == ServiceControllerStatus.Running)
{
SQLServer.Stop();
while (SQLServer.Status != ServiceControllerStatus.Stopped)
{
Thread.Sleep(200);
SQLServer.Refresh();
}
SQLServer.Start();
while (SQLServer.Status != ServiceControllerStatus.Running)
{
Thread.Sleep(200);
SQLServer.Refresh();
}
}
else
{
SQLServer.Start();
}
}
5. ServiceControllerEx 类,对系统ServiceController的扩展。
class ServiceControllerEx : ServiceController
{
public ServiceControllerEx()
: base()
{ }
public ServiceControllerEx(string name)
: base(name)
{ }
public ServiceControllerEx(string name, string machineName)
: base(name, machineName)
{ }
public string StartupType
{
get
{
if (this.ServiceName != null)
{
//construct the management path
string path = "Win32_Service.Name='" + this.ServiceName + "'";
ManagementPath p = new ManagementPath(path);
//construct the management object
ManagementObject ManagementObj = new ManagementObject(p);
return ManagementObj["StartMode"].ToString();
}
else
{
return null;
}
}
set
{
if (value != "Automatic" && value != "Manual" && value != "Disabled")
throw new Exception("The valid values are Automatic, Manual or Disabled");
if (this.ServiceName != null)
{
//construct the management path
string path = "Win32_Service.Name='" + this.ServiceName + "'";
ManagementPath p = new ManagementPath(path);
//construct the management object
ManagementObject ManagementObj = new ManagementObject(p);
//we will use the invokeMethod method of the ManagementObject class
object[] parameters = new object[1];
parameters[0] = value;
ManagementObj.InvokeMethod("ChangeStartMode", parameters);
}
}
}
}
6. 客户端方法(为了那些计算机名都不会看的客户),检测可连接的数据库。
需要引入COM组件 Microsoft SQLDMO Object Library,无需注册。
SQLDMO.ApplicationClass sqlApp = new SQLDMO.ApplicationClass();
SQLDMO.NameList nameList;
int i = 0;
nameList = sqlApp.ListAvailableSQLServers();
for (i = 1; i < nameList.Count; i++)
{
MessageBox.Show(nameList.Item(i).ToString());
}
通过这6步,达到完全代码开启sqlexpress远程服务。
如果sqlexpress数据库安装在win7 系统下,需要关闭防火墙,或者为1434端口和sqlserver.exe设置例外。
SQL Express 远程访问配置
本文介绍如何通过代码自动配置 SQL Server Express 实现局域网内的远程访问,包括设置混合验证模式、启用 TCP/IP 访问、激活 SA 账户及设置密码等步骤。

被折叠的 条评论
为什么被折叠?



