(#----------------程式頭-----------------------------------------=) Imports System.Diagnostics Imports System.IO Imports System.Text Module Module1 Sub Main() Console.WriteLine(Shell("ping.exe", "-n 1 192.168.1.23")) Console.ReadLine() End Sub Function Shell(ByVal sExeFile As String, ByVal sArgument As String) As String Dim pShell As Process pShell = New Process() '設定執行檔及參數 pShell.StartInfo.FileName = sExeFile pShell.StartInfo.Arguments = sArgument '必須要設定以下兩個屬性才可將輸出結果導向 pShell.StartInfo.UseShellExecute = False pShell.StartInfo.RedirectStandardOutput = True '不顯示任何視窗 pShell.StartInfo.CreateNoWindow = True '開始執行 pShell.Start() '將StdOUT的結果轉為字串, 其中StandardOutput屬性類別為StreamReader Shell = pShell.StandardOutput.ReadToEnd() pShell.WaitForExit() End Function End Module (#----------------程式尾-----------------------------------------=) (#----------------程式頭-----------------------------------------=) Function NetBIOSDetect(ByVal IP As String) As String '檢查使用者傳入的是否為合法IPAddress, 藉用System.Net.IPAddress Try Dim ipValid As System.Net.IPAddress ipValid = System.Net.IPAddress.Parse(IP) Catch '使用者傳入的非合法的IP位址格式 NetBIOSDetect = "ERROR: Invalid IP Address" Exit Function End Try 'Ping測試, 當IP不存在時, ping的傳回結果會出現timed out字眼, 以此判別IP存在與否 If InStr(Shell("ping.exe", "-n 1 " & IP), "timed out") > 0 Then NetBIOSDetect = "ERROR: IP doesn't exists!" Exit Function Else 'IP存在, 進行nbtstat -A解析 Dim sTemp As String sTemp = Shell("nbtstat.exe", "-A " & IP) '傳回結果若不包含任何UNIQUE字樣表示未查到相關的NetBIOS名稱資料 If InStr(sTemp, "UNIQUE") = 0 Then NetBIOSDetect = "ERROR: Host not found." Exit Function Else '將傳回結果解析成為多行 Dim sLines() As String sLines = Split(sTemp, vbCrLf) Dim sUsername As String = "", sMachineName As String = "" Dim I As Integer, sNetBIOSName As String For I = 0 To UBound(sLines) '以<00> UNIQUE識別機器名稱, 排除IS~開頭者 If InStr(sLines(I), "<00> UNIQUE") > 0 Then sNetBIOSName = Trim(Left(sLines(I), InStr(sLines(I), "<00>") - 1)) If Left(sNetBIOSName, 3) <> "IS~" Then sMachineName = sNetBIOSName End If ElseIf InStr(sLines(I), "<03> UNIQUE") > 0 Then '由<03> UNIQUE識別使用者名稱 sUsername = Trim(Left(sLines(I), InStr(sLines(I), "<03>") - 1)) End If Next NetBIOSDetect = IP & "," & sMachineName & "," & sUsername Exit Function End If End If End Function (#----------------程式尾-----------------------------------------=) (#----------------程式頭-----------------------------------------=) Sub Main() Dim I As Integer Dim lStart As Long, lEnd As Long Dim iCount As Integer = 0 Dim sResult As String lStart = Environment.TickCount For I = 1 To 254 sResult = NetBIOSDetect("192.168.1." & I) Console.WriteLine(sResult) If InStr(sResult, "ERROR") = 0 Then iCount = iCount + 1 Next I lEnd = Environment.TickCount Console.WriteLine("共計花費" & (lEnd - lStart) & "ms...") Console.WriteLine("找到" & iCount & "台Windows主機") Console.ReadLine() End Sub (#----------------程式尾-----------------------------------------=) (#----------------程式頭-----------------------------------------=) Imports System.Threading Module Module1 Sub Main() Dim threadA, threadB As Thread Dim Snoopy As CDog Dim Garfield As CCat Snoopy = New CDog() Garfield = New CCat() '建立一條新的Thread threadA = New Thread(AddressOf Snoopy.Bark) Console.WriteLine("Starting Thead A...") '開始執行Thread threadA.Start() threadB = New Thread(AddressOf Garfield.Meow) Console.WriteLine("Starting Thead B...") threadB.Start() '暫停Main Thread, 等待Thread A結束 threadA.Join() Console.WriteLine("Thread A is finished!") threadB.Join() Console.WriteLine("Thread B is finished!") Console.WriteLine("Job Done!!") Console.ReadLine() End Sub Class CDog Public Sub Bark() Dim I As Integer For I = 1 To 6 'Thread.CurrentThread.GetHashCode()可以取得目前執行中Thread的代碼 Console.WriteLine("Thread " & Thread.CurrentThread.GetHashCode() & " - 汪 - " & I) Thread.Sleep(500) '命令目前所在的Thread放棄所分配到的CPU控制權500ms Next End Sub End Class Class CCat Public Sub Meow() Dim I As Integer For I = 1 To 6 Console.WriteLine("Thread " & Thread.CurrentThread.GetHashCode() & " - 喵 - " & I) Thread.Sleep(1000) Next End Sub End Class End Module (#----------------程式尾-----------------------------------------=) (#----------------程式頭-----------------------------------------=) Starting Thead A... Starting Thead B... Thread 17 - 汪 - 1 Thread 18 - 喵 - 1 Thread 17 - 汪 - 2 Thread 18 - 喵 - 2 Thread 17 - 汪 - 3 Thread 17 - 汪 - 4 Thread 18 - 喵 - 3 Thread 17 - 汪 - 5 Thread 17 - 汪 - 6 Thread 18 - 喵 - 4 Thread A is finished! Thread 18 - 喵 - 5 Thread 18 - 喵 - 6 Thread B is finished! Job Done!! (#----------------程式尾-----------------------------------------=) (#----------------程式-----------------------------------------=) Imports System.Threading Module Module1 Sub Main() 'QueueUserWorkItem只接受WaitCallback類別 Dim callBack As WaitCallback Dim I As Integer '宣告101忠狗陣列 Dim Dog(101) As CDog For I = 1 To 101 Dog(I) = New CDog() '以要執行函數的位址為參數建立WaitCallback物件 callBack = New WaitCallback(AddressOf Dog(I).Bark) '在QueueUserWorkItem時, 還可傳入一個Object作為呼叫該函數的參數 '當然, 透過類別的Property也是另一種指定參數的作法, 而且更有彈性 ThreadPool.QueueUserWorkItem(callBack, I) Next Console.ReadLine() End Sub Class CDog Public Sub Bark(ByVal state As Object) 'GetHashCode可以識別程式碼是被那一條Thread所執行 Console.WriteLine("Dog No." & CType(state, String) & " is barking in Thread[" & Thread.CurrentThread.GetHashCode() & "]") '等待500ms, 讓Thread的手腳慢一點, 否則一條Thread就可以打通關 '等待時間愈長, 會用到的Thread數就愈多 Thread.Sleep(500) End Sub End Class End Module (#----------------程式尾-----------------------------------------=) 執行結果如下: (#----------------程式頭-----------------------------------------=) Dog No.1 is barking in Thread[118] Dog No.2 is barking in Thread[120] Dog No.3 is barking in Thread[118] Dog No.4 is barking in Thread[120] Dog No.5 is barking in Thread[121] Dog No.6 is barking in Thread[118] Dog No.7 is barking in Thread[121] Dog No.8 is barking in Thread[120] Dog No.9 is barking in Thread[122] Dog No.10 is barking in Thread[118] … 省略 … Dog No.95 is barking in Thread[120] Dog No.96 is barking in Thread[121] Dog No.97 is barking in Thread[122] Dog No.98 is barking in Thread[123] Dog No.99 is barking in Thread[124] Dog No.100 is barking in Thread[125] Dog No.101 is barking in Thread[126] (#----------------程式尾-----------------------------------------=) Try Monitor.Enter(m_Counter) m_Counter = m_Counter + 1 Finally Monitor.Exit(m_Counter) End Try SyncLock m_Counter m_Counter = m_Counter + 1 End SyncLock (#----------------程式-----------------------------------------=) Imports System.Diagnostics Imports System.IO Imports System.Text Imports System.Threading Module Module1 Sub Main() Dim I As Integer Dim lStart As Long, lEnd As Long Dim iCount As Integer = 0 Dim sResult As String Dim NBS(254) As CNetBIOSScanner Dim callBack As WaitCallback lStart = Environment.TickCount '將計數值設為0 CNetBIOSScanner.iJobTotal = 0 CNetBIOSScanner.iJobDone = 0 For I = 1 To 254 '建立新物件 NBS(I) = New CNetBIOSScanner() callBack = New WaitCallback(AddressOf NBS(I).Detect) '指向事件函數 AddHandler NBS(I).Done, AddressOf NBS_onDone '以IP位址作為參數 ThreadPool.QueueUserWorkItem(callBack, "211.74.96." & I) Next I '每隔0.5秒檢查一次是否所有的物件均已完成? While (CNetBIOSScanner.iJobDone < CNetBIOSScanner.iJobTotal) Thread.Sleep(500) End While '統計結果 For I = 1 To 254 sResult = NBS(I).Result If InStr(sResult, "ERROR") = 0 Then iCount = iCount + 1 Next lEnd = Environment.TickCount Console.WriteLine("共計花費" & (lEnd - lStart) & "ms...") Console.WriteLine("找到" & iCount & "台Windows主機") Console.ReadLine() End Sub Sub NBS_onDone(ByVal Result As String) Console.WriteLine(Result) End Sub Class CNetBIOSScanner '宣告為Shared後, 即使有再多個CNetBIOSScanner物件, 都共用一份變數 Public Shared iJobTotal As Integer Public Shared iJobDone As Integer Public Result As String '使用Event完成非同步呼叫 Public Event Done(ByVal Result As String) Public Sub New() Interlocked.Increment(iJobTotal) End Sub Private Sub SetJobDone(ByVal sResult As String) Result = sResult '為了即時反應, 呼叫Done Event將結果立刻顯示出來 '涉及多Thread共用資料, 加上SyncLock保護 SyncLock GetType(CNetBIOSScanner) RaiseEvent Done(sResult) '工作結束, iJobDone計數加一, 但此時多Thread並行, 需使用保護機制 iJobDone = iJobDone + 1 End SyncLock End Sub Public Sub Detect(ByVal state As Object) '檢查使用者傳入的是否為合法IPAddress, 藉用System.Net.IPAddress Dim IP As String = CType(state, String) Try Dim ipValid As System.Net.IPAddress ipValid = System.Net.IPAddress.Parse(IP) Catch '使用者傳入的非合法的IP位址格式 SetJobDone("ERROR: Invalid IP Address") Exit Sub End Try 'Ping測試, 當IP不存在時, ping的傳回結果會出現timed out字眼, 以此判別IP存在與否 If InStr(Shell("ping.exe", "-n 1 " & IP), "timed out") > 0 Then SetJobDone("ERROR: IP doesn't exists!") Exit Sub Else 'IP存在, 進行nbtstat -A解析 Dim sTemp As String sTemp = Shell("nbtstat.exe", "-A " & IP) '傳回結果若不包含任何UNIQUE字樣表示未查到相關的NetBIOS名稱資料 If InStr(sTemp, "UNIQUE") = 0 Then SetJobDone("ERROR: Host not found.") Exit Sub Else '將傳回結果解析成為多行 Dim sLines() As String sLines = Split(sTemp, vbCrLf) Dim sUsername As String = "", sMachineName As String = "" Dim I As Integer, sNetBIOSName As String For I = 0 To UBound(sLines) '以<00> UNIQUE識別機器名稱, 排除IS~開頭者 If InStr(sLines(I), "<00> UNIQUE") > 0 Then sNetBIOSName = Trim(Left(sLines(I), InStr(sLines(I), "<00>") - 1)) If Left(sNetBIOSName, 3) <> "IS~" Then sMachineName = sNetBIOSName End If ElseIf InStr(sLines(I), "<03> UNIQUE") > 0 Then '由<03> UNIQUE識別使用者名稱 sUsername = Trim(Left(sLines(I), InStr(sLines(I), "<03>") - 1)) End If Next SetJobDone(IP & "," & sMachineName & "," & sUsername) Exit Sub End If End If End Sub Private Function Shell(ByVal sExeFile As String, ByVal sArgument As String) As String Dim pShell As Process pShell = New Process() '設定執行檔及參數 pShell.StartInfo.FileName = sExeFile pShell.StartInfo.Arguments = sArgument '必須要設定以下兩個屬性才可將輸出結果導向 pShell.StartInfo.UseShellExecute = False pShell.StartInfo.RedirectStandardOutput = True '不顯示任何視窗 pShell.StartInfo.CreateNoWindow = True '開始執行 pShell.Start() '將StdOUT的結果轉為字串, 其中StandardOutput屬性類別為StreamReader Shell = pShell.StandardOutput.ReadToEnd() pShell.WaitForExit() End Function End Class End Module (#----------------程式尾-----------------------------------------=)