我有一个类在Active Directory中搜索所有OU,然后搜索其中的所有计算机对象。它工作得很好......然后我决定利用一些线程来允许OU搜索和计算机对象搜索同时运行。现在,计算机搜索者突然返回0结果......(没有错误,只是没有结果)
我还添加了一个额外的属性来加载(objectGUID),但我尝试删除它,但它没有解决问题。我看不出我做了什么来打破它。这可能是一种愚蠢的盯着我的脸,但我找不到它。我希望一副新鲜的眼睛能够发现我的错误。
在破碎的代码中,Public Sub FindComputers(...)就是我遇到问题的地方。 在工作代码中,它是Private Function FindComputers(...)。我改变它,因为它现在在一个单独的类中。
编辑: 我在FindComputers子上设置了一个断点并逐步完成它。行queryResults = searcher.FindAll()执行后,queryResults count始终为0.循环中的事件永远不会被触发。
提前致谢。
Public Class ADSearcher
'Removed properties and events etc
Public Sub StartSearch()
#If Not Debug Then
Try
#End If
Dim rootEntry As New DirectoryEntry(RootPath)
Dim rootNode As New TreeNode(rootEntry.Name)
rootNode.Name = rootEntry.Path
If Not IntegratedAuthentication Then
rootEntry.Username = UserID
rootEntry.Password = Password
End If
Dim searcher As New DirectorySearcher(rootEntry)
searcher.PropertiesToLoad.AddRange(PropertiesToLoad)
searcher.SearchScope = SearchScope
searcher.PageSize = PageSize
searcher.ServerTimeLimit = New TimeSpan(0, 10, 0)
searcher.Filter = FilterString
Dim queryResults As SearchResultCollection
queryResults = searcher.FindAll()
Dim result As SearchResult
For Each result In queryResults
FindComputers(result) 'Search the current OU for computer objects
Dim childNode As New TreeNode(CStr(result.Properties("name")(0)))
childNode.Name = result.Path
rootNode.Nodes.Add(SearchSub(result, childNode))
ouResultCount += 1
RaiseEvent ResultFound(ouResultCount, pcResultCount)
Next
RaiseEvent SearchCompleted(rootNode)
ouResultCount = 0 'Reset the result count
pcResultCount = 0 'Reset the computer result count
#If Not Debug Then
Catch Ex as Exception
MsgBox(ex.Message, MsgBoxStyle.Critical)
End Try
#End If
End Sub
Private Function SearchSub(ByVal parent As SearchResult, ByVal node As TreeNode)
#If Not Debug Then
Try
#End If
Dim subEntry As New DirectoryEntry(parent.Path)
If Not IntegratedAuthentication Then
subEntry.Username = UserID
subEntry.Password = Password
End If
Dim searcher As New DirectorySearcher(subEntry)
searcher.PropertiesToLoad.AddRange(PropertiesToLoad)
searcher.SearchScope = SearchScope
searcher.PageSize = PageSize
searcher.ServerTimeLimit = New TimeSpan(0, 10, 0)
searcher.Filter = FilterString
Dim queryResults As SearchResultCollection
queryResults = searcher.FindAll()
Dim result As SearchResult
For Each result In queryResults
FindComputers(result) 'Search for computer objects in the current OU
Dim childNode As New TreeNode(CStr(result.Properties("name")(0)))
childNode.Name = result.Path
SearchSub(result, childNode)
node.Nodes.Add(childNode)
ouResultCount += 1
RaiseEvent ResultFound(ouResultCount, pcResultCount)
Next
Return node
#If Not Debug Then
Catch Ex as Exception
MsgBox(ex.Message, MsgBoxStyle.Critical)
End Try
#End If
End Function
Private Function FindComputers(ByVal parent As SearchResult)
#If Not Debug Then
Try
#End If
Dim subEntry As New DirectoryEntry(parent.Path)
If Not IntegratedAuthentication Then
subEntry.Username = UserID
subEntry.Password = Password
End If
Dim searcher As New DirectorySearcher(subEntry)
searcher.PropertiesToLoad.AddRange(PropertiesToLoad)
searcher.SearchScope = SearchScope
searcher.PageSize = PageSize
searcher.ServerTimeLimit = New TimeSpan(0, 10, 0)
searcher.Filter = "(objectCategory=computer)"
Dim queryResults As SearchResultCollection
queryResults = searcher.FindAll()
Dim result As SearchResult
For Each result In queryResults
pcResultCount += 1
Dim dNSHostName As String
If result.Properties.Contains("dNSHostName") Then
dNSHostName = result.Properties("dNSHostName")(0)
Else
dNSHostName = result.Properties("name")(0) 'If the computer object has a value in dNSHostName (FQDN) store it else store the basic name
End If
RaiseEvent ComputerFound(result.Properties("name")(0), dNSHostName, result.Path)
RaiseEvent ResultFound(ouResultCount, pcResultCount)
Next
Return 1
#If Not Debug Then
Catch Ex as Exception
MsgBox(ex.Message, MsgBoxStyle.Critical)
End Try
#End If
End Function
End Class
Public Class ADSearcher
'Removed properties and events etc
<MTAThread()>
Public Sub StartSearch()
#If Not Debug Then
Try
#End If
Dim rootEntry As New DirectoryEntry(RootPath)
Dim rootNode As New TreeNode(rootEntry.Name)
rootNode.Name = rootEntry.Path
If Not IntegratedAuthentication Then
rootEntry.Username = UserID
rootEntry.Password = Password
End If
Dim searcher As New DirectorySearcher(rootEntry)
searcher.PropertiesToLoad.AddRange(PropertiesToLoad)
searcher.SearchScope = SearchScope
searcher.PageSize = PageSize
searcher.ServerTimeLimit = New TimeSpan(0, 10, 0)
searcher.Filter = FilterString
Dim queryResults As SearchResultCollection
queryResults = searcher.FindAll()
Dim result As SearchResult
For Each result In queryResults
Dim freeThread As Integer = WaitHandle.WaitAny(compSearchThreads)
Dim threadParams As Object
threadParams = New Object() {result, freeThread} 'Create an object to pass the parameters
compSearchInstances(freeThread) = New ComputerSearcher(compSearchThreads(freeThread))
With compSearchInstances(freeThread)
.FilterString = "(objectCategory=computer)"
If Not IntegratedAuthentication Then
.UserID = UserID
.Password = Password
End If
.PageSize = 5
.PropertiesToLoad = New String() {"cn", "name", "distinguishedName", "dNSHostName", "objectCategory", "objectGUID"}
End With
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf compSearchInstances(freeThread).FindComputers), threadParams)
'FindComputers(result) 'Search the current OU for computer objects
Dim childNode As New TreeNode(CStr(result.Properties("name")(0)))
childNode.Name = result.Path
childNode.Tag = result.Properties("objectGUID")(0)
rootNode.Nodes.Add(SearchSub(result, childNode))
ouResultCount += 1
RaiseEvent OUResultFound(ouResultCount) ', pcResultCount)
Next
WaitHandle.WaitAll(compSearchThreads)
RaiseEvent SearchCompleted(rootNode)
ouResultCount = 0 'Reset the result count
'pcResultCount = 0 'Reset the computer result count
#If Not Debug Then
Catch Ex as Exception
MsgBox(ex.Message, MsgBoxStyle.Critical)
End Try
#End If
End Sub
Private Function SearchSub(ByVal parent As SearchResult, ByVal node As TreeNode)
#If Not Debug Then
Try
#End If
Dim subEntry As New DirectoryEntry(parent.Path)
If Not IntegratedAuthentication Then
subEntry.Username = UserID
subEntry.Password = Password
End If
Dim searcher As New DirectorySearcher(subEntry)
searcher.PropertiesToLoad.AddRange(PropertiesToLoad)
searcher.SearchScope = SearchScope
searcher.PageSize = PageSize
searcher.ServerTimeLimit = New TimeSpan(0, 10, 0)
searcher.Filter = FilterString
Dim queryResults As SearchResultCollection
queryResults = searcher.FindAll()
Dim result As SearchResult
For Each result In queryResults
Dim freeThread As Integer = WaitHandle.WaitAny(compSearchThreads)
Dim threadParams As Object
threadParams = New Object() {result, freeThread} 'Create an object to pass the parameters
compSearchInstances(freeThread) = New ComputerSearcher(compSearchThreads(freeThread))
With compSearchInstances(freeThread)
.FilterString = "(objectCategory=computer)"
If Not IntegratedAuthentication Then
.UserID = UserID
.Password = Password
End If
.PageSize = 5
.PropertiesToLoad = New String() {"cn", "name", "distinguishedName", "dNSHostName", "objectCategory", "objectGUID"}
End With
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf compSearchInstances(freeThread).FindComputers), threadParams)
'FindComputers(result) 'Search for computer objects in the current OU
Dim childNode As New TreeNode(CStr(result.Properties("name")(0)))
childNode.Name = result.Path
childNode.Tag = result.Properties("objectGUID")(0) 'New Object() {}
SearchSub(result, childNode)
node.Nodes.Add(childNode)
ouResultCount += 1
RaiseEvent OUResultFound(ouResultCount) ', pcResultCount)
Next
Return node
#If Not Debug Then
Catch Ex as Exception
MsgBox(ex.Message, MsgBoxStyle.Critical)
End Try
#End If
End Function
End Class
Public Class ComputerSearcher
'Removed properties and events etc
Public Sub FindComputers(ByVal threadParams As Object)
#If Not Debug Then
Try
#End If
_doneEvent.Reset() 'Signal that the thread is working
System.Diagnostics.Debug.Print("Computer search thread " + threadParams(1).ToString + " is starting")
Dim parent As SearchResult = threadParams(0)
Dim subEntry As New DirectoryEntry(parent.Path)
If Not IntegratedAuthentication Then
subEntry.Username = UserID
subEntry.Password = Password
End If
Dim searcher As New DirectorySearcher(subEntry)
searcher.PropertiesToLoad.AddRange(PropertiesToLoad)
searcher.SearchScope = SearchScope
searcher.PageSize = PageSize
searcher.ServerTimeLimit = New TimeSpan(0, 10, 0)
searcher.Filter = FilterString
Dim queryResults As SearchResultCollection
queryResults = searcher.FindAll()
Dim result As SearchResult
For Each result In queryResults
pcResultCount += 1
Dim dNSHostName As String
If result.Properties.Contains("dNSHostName") Then 'If the computer object has a value in dNSHostName (FQDN) store it else store the basic name
dNSHostName = result.Properties("dNSHostName")(0)
Else
dNSHostName = result.Properties("name")(0)
End If
RaiseEvent ComputerFound(result.Properties("name")(0), dNSHostName, result.Path, result.Properties("objectGUID")(0).ToString)
RaiseEvent CompResultFound(pcResultCount) '### TO DO: Rename event to CompIncrementResult
Next
System.Diagnostics.Debug.Print("Computer search thread " + threadParams(1).ToString + " is ending")
_doneEvent.Set() 'Signal that the thread is finished
#If Not Debug Then
Catch Ex as Exception
MsgBox(ex.Message, MsgBoxStyle.Critical)
End Try
#End If
End Sub
End Class
答案 0 :(得分:0)
我终于发现了自己的错误,正如我以为这是傻傻的直视着我的脸。在StartSearch()和SubSearch()的以下代码部分中,我忘了设置SearchScope。
With compSearchInstances(freeThread)
.FilterString = "(objectCategory=computer)"
If Not IntegratedAuthentication Then
.UserID = UserID
.Password = Password
End If
.PageSize = 5
.PropertiesToLoad = New String() {"cn", "name", "distinguishedName", "dNSHostName", "objectCategory", "objectGUID"}
End With
我应该在那里有以下一行:
.SearchScope = SearchScope