2013-04-10 99 views
3

我正在部署SQL Server Express与我的应用程序,我需要有C#代码更改TCP/IP属性而不更改它们在SQL Server配置管理器中。使用C#更改tcp/ip端口为sql server express使用C#

以下代码停止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:SetStringValue ServerIPAddress'IPAll'失败。 ---> System.NullReferenceException:未将对象引用设置为对象的实例。
在System.Management.ManagementObject.MapOutParameters(对象[]指定参数时,ManagementBaseObject> outParams,IWbemClassObjectFreeThreaded outParamsClass)
在System.Management.ManagementObject.InvokeMethod(字符串方法名,对象[]参数)
在Microsoft.SqlServer.Management .Smo.Wmi.WmiSmoObject.InvokeMgmtMethod(的ManagementObject MO,> ManagementOperationObserver观察者,字符串方法名,对象[]参数)

---内部异常堆栈跟踪的结尾---
在Microsoft.SqlServer.Management.Smo .Wmi.WmiSmoObject.InvokeMgmtMethod(ManagementObject mo,> ManagementOperationObserver observer,String methodName,Object [] parameters)
在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()
---内部异常堆栈跟踪结束---
at Microsoft.SqlServer.Management.Smo.Wmi.ProtocolBase.Alter()

+0

那么,当你调用是这样的:

您可以通过重构到ServiceController类解决这个'服务Mysvc = mc.Services [ “MSSQL $ SQL” +机器名]',你应该***总是***检查返回的值('Mysvc')是否真的是'!= null',而不是仅仅调用其他方法!最有可能的是,您的SQL Server服务在Windows 7上具有不同的名称,因此此调用不会返回任何内容,但是您正在调用其上的“Mysvc.ServiceState”... – 2013-04-10 16:02:41

+0

你是这么想的?这是UAC /高程问题吗? – 2013-05-16 12:39:06

+0

UAC是这里的问题,以Admin身份运行解决问题。 – 2014-05-06 17:40:08

回答

1

UAC是这里的问题。以管理员身份运行将解决问题。

0

Service类不容易让您等待服务启动或停止,然后再继续执行下一个操作。随着代码的发展,服务会发送一条Stop命令,但在服务停止前继续执行。

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