[SQL Server] SQL Server Management Studio 啟動失敗 (無法讀到 Registered Servers) 的問題與解決

原本今天要做一些資料庫設計工作,結果因為這個錯誤整個都泡湯了,試著用修復安裝也沒用,就在困惑之際,發現它的來源是 System.Xml,再加上事件檢視器中有這樣的訊息....

今天莫名奇妙地 SQL Server Management Studio 無法啟動,一直出現這個錯誤:

image

 

原本今天要做一些資料庫設計工作,結果因為這個錯誤整個都泡湯了,試著用修復安裝也沒用,就在困惑之際,發現它的來源是 System.Xml,再加上事件檢視器中有這樣的訊息:

應用程式: Ssms.exe
Framework 版本: v4.0.30319
描述: 處理序已終止,因為有未處理的例外狀況。
例外狀況資訊: Microsoft.SqlServer.Management.RegisteredServers.RegisteredServerException
堆疊:
   於 Microsoft.SqlServer.Management.RegisteredServers.RegisteredServersStore.InitChildObjects(System.String)
   於 Microsoft.SqlServer.Management.RegisteredServers.RegisteredServersStore.InitializeLocalRegisteredServersStore()
   於 Microsoft.SqlServer.Management.RegisteredServers.RegisteredServersStore.get_LocalFileStore()
   於 Microsoft.SqlServer.Management.UI.ConnectionDlg.ConnectionDialog.OnLoad(System.EventArgs)
   於 System.Windows.Forms.Form.OnCreateControl()
   於 System.Windows.Forms.Control.CreateControl(Boolean)
   於 System.Windows.Forms.Control.CreateControl()
   於 System.Windows.Forms.Control.WmShowWindow(System.Windows.Forms.Message ByRef)
   於 System.Windows.Forms.Control.WndProc(System.Windows.Forms.Message ByRef)
   於 System.Windows.Forms.ScrollableControl.WndProc(System.Windows.Forms.Message ByRef)
   於 System.Windows.Forms.ContainerControl.WndProc(System.Windows.Forms.Message ByRef)
   於 System.Windows.Forms.Form.WmShowWindow(System.Windows.Forms.Message ByRef)
   於 System.Windows.Forms.Form.WndProc(System.Windows.Forms.Message ByRef)
   於 System.Windows.Forms.Control+ControlNativeWindow.OnMessage(System.Windows.Forms.Message ByRef)
   於 System.Windows.Forms.Control+ControlNativeWindow.WndProc(System.Windows.Forms.Message ByRef)
   於 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr, Int32, IntPtr, IntPtr)
   於 System.Windows.Forms.SafeNativeMethods.ShowWindow(System.Runtime.InteropServices.HandleRef, Int32)
   於 System.Windows.Forms.Control.SetVisibleCore(Boolean)
   於 System.Windows.Forms.Form.SetVisibleCore(Boolean)
   於 System.Windows.Forms.Control.set_Visible(Boolean)
   於 System.Windows.Forms.Application+ThreadContext.RunMessageLoopInner(Int32, System.Windows.Forms.ApplicationContext)
   於 System.Windows.Forms.Application+ThreadContext.RunMessageLoop(Int32, System.Windows.Forms.ApplicationContext)
   於 System.Windows.Forms.Application.RunDialog(System.Windows.Forms.Form)
   於 System.Windows.Forms.Form.ShowDialog(System.Windows.Forms.IWin32Window)
   於 Microsoft.SqlServer.Management.UI.ConnectionDlg.ConnectionDialog.ShowDialogValidateConnection(System.Windows.Forms.IWin32Window, Microsoft.SqlServer.Management.Smo.RegSvrEnum.UIConnectionInfo ByRef, System.Data.IDbConnection ByRef)
   於 Microsoft.SqlServer.Management.SqlStudio.Explorer.ObjectExplorerService.NewConnection(Microsoft.SqlServer.Management.UI.ConnectionDlg.IServerType)
   於 Microsoft.SqlServer.Management.SqlStudio.Explorer.ObjectExplorerService.NewConnection()
   於 Microsoft.SqlServer.Management.SqlStudio.ConnectToOe()
   於 Microsoft.SqlServer.Management.SqlStudio.ApplicationStarted()
   於 Microsoft.SqlServer.Management.SqlStudio.OnShellPropertyChange(Int32, System.Object)

看起來像是用 .NET Framework 寫的組件出問題,因此我就動手追踪了幾個組件,這些組件都是用 .NET Framework 寫的,所以可以反組譯 (無誤),例如 .NET Reflector 和 JustDecompile 都可以反組譯這些 DLL (用 native language 寫的就不用試了,不行),我用工具反組譯了 Microsoft.SqlServer.Management.RegisterServers 這個組件,找到了疑似問題的入口:RegisteredServersStore,再搭配在 AppData\Temp 內的錯誤訊息:

UNHANDLED EXCEPTIONS FROM PROCESS 9484:
=====================
2013/12/30 下午 05:32:06
Microsoft.SqlServer.Management.RegisteredServers.RegisteredServerException: 無法讀取先前在此系統上註冊的伺服器清單。請在 [已註冊的伺服器] 視窗中重新註冊您的伺服器。 ---> Microsoft.SqlServer.Management.Sdk.Sfc.SfcSerializationException: 還原序列化輸入已損毀。 ---> System.Xml.XmlException: 遺漏根元素。
   於 System.Xml.XmlTextReaderImpl.Throw(Exception e)
   於 System.Xml.XmlTextReaderImpl.ParseDocumentContent()
   於 System.Xml.XmlTextReaderImpl.Read()
   於 System.Xml.XmlTextReader.Read()
   於 System.Xml.XmlReader.ReadToFollowing(String name)
   於 Microsoft.SqlServer.Management.Sdk.Sfc.SfcSerializer.Deserialize(XmlReader xmlReader, SfcObjectState state)
   --- 內部例外狀況堆疊追蹤的結尾 ---
   於 Microsoft.SqlServer.Management.Sdk.Sfc.SfcSerializer.Deserialize(XmlReader xmlReader, SfcObjectState state)
   於 Microsoft.SqlServer.Management.RegisteredServers.RegisteredServersStore.InitChildObjects(String file)
   --- 內部例外狀況堆疊追蹤的結尾 ---
   於 Microsoft.SqlServer.Management.RegisteredServers.RegisteredServersStore.InitChildObjects(String file)
   於 Microsoft.SqlServer.Management.RegisteredServers.RegisteredServersStore.InitializeLocalRegisteredServersStore()
   於 Microsoft.SqlServer.Management.RegisteredServers.RegisteredServersStore.get_LocalFileStore()
   於 Microsoft.SqlServer.Management.UI.ConnectionDlg.ConnectionDialog.OnLoad(EventArgs e)
   於 System.Windows.Forms.Form.OnCreateControl()
   於 System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
   於 System.Windows.Forms.Control.CreateControl()
   於 System.Windows.Forms.Control.WmShowWindow(Message& m)
   於 System.Windows.Forms.Control.WndProc(Message& m)
   於 System.Windows.Forms.ScrollableControl.WndProc(Message& m)
   於 System.Windows.Forms.ContainerControl.WndProc(Message& m)
   於 System.Windows.Forms.Form.WmShowWindow(Message& m)
   於 System.Windows.Forms.Form.WndProc(Message& m)
   於 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   於 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   於 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
===================

幾乎可以斷定是遺漏了什麼檔案,再看它的反組譯碼,發現是由 Environment.SpecialFolder.ApplicationData 取得,然後再經過一番尋找,終於在 %User%\AppData\Romaning\Microsoft\Microsoft SQL Server\110\Tools\Shell 中找到了一個 Regsrvr.xml,這個檔案不知什麼原因變成了空檔案,將它刪掉後重新啟動 SQL Server Management Studio,就正常了...