使用C#更改sql server express的tcp / ip端口

时间:2013-04-10 15:55:56

标签: c# sql-server-2008 tcp

我正在使用我的应用程序部署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()

2 个答案:

答案 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);