在移动设备上远程显示服务器逻辑磁盘
一个Web方法,用于在移动设备上远程显示服务器的逻辑磁盘。
引言
在 Siccolo - SQL Server 管理工具 中,其中一个功能是可以从 Windows Mobile 设备备份 SQL Server 数据库(参见我之前的文章,Web 方法远程备份数据库,在 Siccolo 文章中)。为了使备份过程体验更友好,并且更类似于 Microsoft SQL Server 企业管理器,我需要允许用户选择将实际数据库备份文件保存到哪里 - 哪个目录。但首先,用户需要选择一个磁盘。
在提供的代码中,客户端(移动设备)从 Web 服务检索磁盘列表。
1. 服务器代码 - 检索磁盘列表
首先,Web 方法允许客户端检索服务器上的逻辑磁盘列表
<WebMethod()> Public Function LocalDisksList(ByVal ServerAddress As String, _
ByRef ErrorInfo As String) As String
Try
Dim DiskList_XML As String = ""
If DirectoryTree.GetFixedLocalDisks_XML(CType(User, WindowsPrincipal), _
ServerAddress, _
ToDebug, _
DiskList_XML, _
ErrorInfo) Then
ErrorInfo = ""
Return DiskList_XML
Else
Return ""
End If
Catch ex As Exception
ErrorInfo = ex.Message
Return ""
End Try
End Function
其中 GetFixedLocalDisks_XML()
从磁盘列表中创建一个 XML 字符串
Public Shared Function GetFixedLocalDisks_XML(ByVal WebServiceUser As WindowsPrincipal, _
ByVal ServerName As String, _
ByVal ToDebug As String, _
ByRef ServerLocalDisksList_XML As String, _
ByRef ErrorInfo As String) As Boolean
Dim collection As ManagementObjectCollection
Dim impersonationContext As System.Security.Principal.WindowsImpersonationContext = _
CType(WebServiceUser.Identity, _
System.Security.Principal.WindowsIdentity).Impersonate()
If Not GetFixedLocalDisks(ServerName, _
ToDebug, _
collection, _
ErrorInfo) Then
ServerLocalDisksList_XML = ""
impersonationContext.Undo()
Return False
Else
Dim objDisks As DataSet = New DataSet("QueryResults")
objDisks.Tables.Add("LocalDisks")
objDisks.Tables(0).Columns.Add("disk_path", _
System.Type.GetType("System.String"))
Dim management_object As ManagementObject
For Each management_object In collection
Dim r As Object = New Object() {management_object("deviceID")}
objDisks.Tables(0).Rows.Add(r)
Next
Dim objStringWriter As New System.IO.StringWriter()
objDisks.WriteXml(objStringWriter, XmlWriteMode.WriteSchema)
ServerLocalDisksList_XML = "<?xml version='1.0' ?>" & objStringWriter.ToString()
impersonationContext.Undo()
Return True
End If
End Function
正如您所注意到的,我使用 impersonationContext
,因为 Web 服务需要“假定”经过身份验证的用户的身份,才能访问 Web 服务宿主之外的机器上的资源。在服务器端,为了检索经过身份验证的用户,我们需要使用 System.Web.Services.WebService.User
然后“模拟” - Impersonate()
- “模拟由 WindowsIdentity
对象表示的用户”。
在这个方法中,GetFixedLocalDisks_XML()
,我使用 DataSet
类,使用 WriteXML()
方法创建一个 XML 字符串
...
Dim objDisks As DataSet = New DataSet("QueryResults")
...
...
Dim objStringWriter As New System.IO.StringWriter()
objDisks.WriteXml(objStringWriter, XmlWriteMode.WriteSchema)
...
其中 WriteXml()
使用指定的 System.IO.Stream
和 XmlWriteMode
写入 DataSet
的当前数据和模式。 XmlWriteMode.WriteSchema
告诉应用程序将 DataSet
的当前内容作为 XML 数据写入,并将关系结构作为内联 XSD 模式。
DataSet
包含一个带有一列的表
- [disk_path] - 逻辑磁盘的实际名称(路径)
要在 DataSet
中添加/创建列
...
objDisks.Tables(0).Columns.Add("disk_path", System.Type.GetType("System.String"))
...
Columns.Add()
创建并将一个 DataColumn
对象添加到 DataColumnCollection
中。 这里,Add()
创建并将 DataColumn
对象与指定的名称和类型添加到 DataColumnCollection
中。 为了让 Add()
知道列的类型,我们需要传递一个 DataColumn.DataType
类型的参数。 为此,我们可以使用 GetType()
方法,该方法使用指定的名称获取 Type
- System.Type.GetType("System.String")
和 GetFixedLocalDisks()
Private Shared Function GetFixedLocalDisks(ByVal ServerName As String, _
ByVal ToDebug As String, _
ByRef ServerLocalDisks As ManagementObjectCollection, _
ByRef ErrorInfo As String) As Boolean
Try
Dim query As ManagementObjectSearcher
Dim queryCollection As ManagementObjectCollection
Dim msc As ManagementScope = New ManagementScope("\\" & ServerName & "\root\cimv2")
Dim query_command As String = "SELECT * FROM Win32_LogicalDisk where MediaType=12 "
Dim select_query As SelectQuery = New SelectQuery(query_command)
query = New ManagementObjectSearcher(msc, select_query)
ServerLocalDisks = query.Get()
Return True
Catch ex As Exception
ServerLocalDisks = Nothing
ErrorInfo = ex.Message
Return False
End Try
End Function
(有关 Windows WMI 的更多信息 - 请参阅 Siccolo 文章)。
2. 客户端代码 - 显示磁盘列表
Friend Function PopulateLocalDiskList(ByVal cboListControl As Windows.Forms.ComboBox, _
ByVal SelectedDatabase As String, _
ByRef ErrorInfo As String) As Boolean
Try
ErrorInfo = ""
Dim DiskList_XML As String = ""
DiskList_XML = objSQLWebServiceManager.LocalDisksList(objLoginInfo.ServerAddress, _
ErrorInfo)
If ErrorInfo <> "" Or DiskList_XML = "" Then Return False
Dim objResponse As New DataSet()
Dim Reader As New System.IO.StringReader(DiskList_XML.ToString())
Dim XMLReader As New System.Xml.XmlTextReader(Reader)
XMLReader.Read()
objResponse.ReadXml(XMLReader, XmlReadMode.Auto)
objResponse.AcceptChanges()
XMLReader.Close()
cboListControl.DataSource = objResponse.Tables(0)
cboListControl.DisplayMember = "disk_path"
Return True
Catch ex As Exception
ErrorInfo = ex.Message
Me.SoundError()
If m_LogErrorToFile Then LogError("PopulateLocalDiskList():" & ex.ToString)
Return False
End Try
End Function
并在屏幕上
关注点
如果您想阅读更多关于这个故事的内容,请查看 Siccolo - 免费的 SQL Server 移动管理工具,您可以在 Siccolo 文章 中查看更多文章。