我正在使用我的应用程序部署SQL Server Express,我需要使用C#代码来更改TCP / IP属性,而无需在SQL Server配置管理器中更改它们。
以下代码停止SQL Server,然后将tcp端口更改为1433,然后再次启动SQL Server。该代码在Windows XP机器上运行良好;但是,它在Windows 7机器上出错。错误发生在prot.Alter();
行。
try
{
Service Mysvc = mc.Services["MSSQL$SQL" + machineName];
if (Mysvc.ServiceState == ServiceState.Running)
{
MessageBox.Show("Stopping Service","PMP");
Mysvc.Stop();
}
ServerInstance s = mc.ServerInstances["SQL" + machineName];
ServerProtocol prot = s.ServerProtocols["Tcp"];
prot.IPAddresses[0].IPAddressProperties["TcpPort"].Value = "1433";
prot.Alter();
MessageBox.Show("Starting Service","PMP");
Mysvc.Start();
}
catch (Exception e)
{
MessageBox.Show("Error in setting TCP Port " + e.ToString(),"PMP");
}
以下错误消息是我在Windows 7计算机上运行时收到的消息:
SqlServer.Management.Smo.FailedOperationException:更改失败。 ---> Microsoft.SqlServer.Management.Smo.FailedOperationException:ServerSAddress' IPAll'的SetStringValue失败。 ---> System.NullReferenceException:未将对象引用设置为对象的实例 在System.Management.ManagementObject.MapOutParameters(Object [] args,ManagementBaseObject> outParams,IWbemClassObjectFreeThreaded outParamsClass)
在System.Management.ManagementObject.InvokeMethod(String methodName,Object [] args)
在Microsoft.SqlServer.Management.Smo.Wmi.WmiSmoObject.InvokeMgmtMethod(ManagementObject mo,> ManagementOperationObserver observer,String methodName,Object []参数)---内部异常堆栈跟踪结束---
在Microsoft.SqlServer.Management.Smo.Wmi.WmiSmoObject.InvokeMgmtMethod(ManagementObject mo,> ManagementOperationObserver observer,String methodName,Object []参数)
在Microsoft.SqlServer.Management.Smo.Wmi.WmiSmoObject.AlterProtocolProperties (ProtocolPropertyCollection protocolProperties)
在Microsoft.SqlServer.Management.Smo.Wmi.ServerIPAddress.AlterImplWorker()
---内部异常堆栈跟踪结束---
在Microsoft.SqlServer.Management.Smo.Wmi.ServerIPAddress.AlterImplWorker()
在Microsoft.SqlServer.Management.Smo.Wmi.ServerProtocol.AlterImplWorker()
在Microsoft.SqlServer.Management.Smo.Wmi.ProtocolBase.Alter()
---内部异常堆栈跟踪结束---
在Microsoft.SqlServer.Management.Smo.Wmi.ProtocolBase.Alter()
答案 0 :(得分:1)
UAC是这里的问题。以管理员身份运行将解决问题。
答案 1 :(得分:0)
Service
类不允许您在继续执行下一个操作之前等待服务启动或停止。正如您的代码所代表的那样,服务将发送一个Stop命令,但在服务停止之前继续执行。
您可以通过重构ServiceController
类来解决此问题:
using Microsoft.SqlServer.Management.Smo.Wmi;
const string instanceName = "SQLEXPRESS";
var managedComputer = new ManagedComputer();
var serviceController = new ServiceController(string.Concat("MSSQL$", instanceName));
var serverInstance = managedComputer.ServerInstances[instanceName];
var serverProtocol = serverInstance?.ServerProtocols["Tcp"];
var ipAddresses = serverProtocol?.IPAddresses;
if (ipAddresses != null)
{
for (var i = 0; i < ipAddresses?.Count; i++)
{
var ipAddress = ipAddresses[i];
if (!string.Equals(ipAddress.Name, "IPAll"))
{
continue;
}
if (serviceController.Status == ServiceControllerStatus.Running)
{
serviceController.Stop();
serviceController.WaitForStatus(ServiceControllerStatus.Stopped);
}
ipAddress.IPAddressProperties["TcpDynamicPorts"].Value = "0";
ipAddress.IPAddressProperties["TcpPort"].Value = "1433";
serverProtocol.Alter();
break;
}
}
if (serviceController.Status == ServiceControllerStatus.Running)
{
return;
}
serviceController.Start();
serviceController.WaitForStatus(ServiceControllerStatus.Running);