2013-04-10 65 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); 
相關問題