C# 如何确定我的Windows域中的计算机是否为;主动的;
我正在尝试编写一种方法来确定我域中的哪些计算机处于“非活动”状态。我能够使其正常工作的唯一方法是尝试通过以下方式获取计算机的IP地址:C# 如何确定我的Windows域中的计算机是否为;主动的;,c#,exception,networking,dns,ping,C#,Exception,Networking,Dns,Ping,我正在尝试编写一种方法来确定我域中的哪些计算机处于“非活动”状态。我能够使其正常工作的唯一方法是尝试通过以下方式获取计算机的IP地址: Dns.GetHostAddresses(computerName) 如果计算机处于“非活动”状态,它会抛出一个System.Net.Sockets.SocketException,然后我可以捕获该计算机并将其添加到我的非活动计算机数据表中。这种方法的问题是速度慢得令人痛苦。在我的Windows域中,有500台计算机,大约300台处于“非活动”状态,用这种方法对
Dns.GetHostAddresses(computerName)
如果计算机处于“非活动”状态,它会抛出一个System.Net.Sockets.SocketException
,然后我可以捕获该计算机并将其添加到我的非活动计算机数据表中。这种方法的问题是速度慢得令人痛苦。在我的Windows域中,有500台计算机,大约300台处于“非活动”状态,用这种方法对它们进行排序几乎需要30分钟。有人对如何判断在我的Windows域中注册的计算机是否处于活动状态有什么建议吗
我还尝试通过ping列表中的所有计算机来实现这一点,但在尝试ping“非活动”计算机时,会抛出一个System.Net.NetworkInformation.PingException
,我必须以相同的方式捕获和处理它。这也给了我这个过程将近30分钟的运行时间
这是我的密码
public void findInactiveComputers( string customerName, string domain )
{
DirectoryEntry entry = new DirectoryEntry( domain );
DirectorySearcher searcher = new DirectorySearcher( entry );
searcher.Filter = ("(objectClass=computer)");
searcher.SizeLimit = int.MaxValue;
searcher.PageSize = int.MaxValue;
// Removes the inactive computers from the DataTable that associated with the customer.
if( _InactiveComputers.Rows.Count != 0 )
{
_InactiveComputers.AsEnumerable().Where( cust => cust["CustomerName"].ToString()
.Equals( customerName, StringComparison.InvariantCultureIgnoreCase ) )
.ToList().ForEach( comp => comp.Delete() );
}
foreach( SearchResult result in searcher.FindAll() )
{
if( result.GetDirectoryEntry().Name.StartsWith( "CN=" ) )
{
string computerName = result.GetDirectoryEntry().Name.Remove( 0, "CN=".Length );
try
{
Dns.GetHostAddresses( computerName );
}
catch( SocketException )
{
DataRow newRow = _InactiveComputers.NewRow();
newRow["ComputerName"] = computerName;
newRow["CustomerName"] = customerName;
_InactiveComputers.Rows.Add( newRow );
}
}
}
Properties.Settings.Default.InvalidComputers = _InactiveComputers;
Properties.Settings.Default.Save();
}
编辑:
我尝试使用多个线程来完成任务,但等待时间仍然很长(我现在正在运行它,但它仍然没有完成)
下面是我如何实现它的,改进性能的建议
List<string> inactiveComputerNames = new List<string>();
foreach( SearchResult result in searcher.FindAll() )
{
new Thread( delegate()
{
if( result.GetDirectoryEntry().Name.StartsWith( "CN=" ) )
{
string computerName = result.GetDirectoryEntry().Name.Remove( 0, "CN=".Length );
try
{
Dns.GetHostAddresses( computerName );
}
catch( SocketException )
{
inactiveComputerNames.Add( computerName );
}
}
} ).Start();
}
foreach( string computerName in inactiveComputerNames )
{
DataRow newRow = _InactiveComputers.NewRow();
newRow["ComputerName"] = computerName;
newRow["CustomerName"] = customerName;
_InactiveComputers.Rows.Add( newRow );
}
List inactiveComputerNames=new List();
foreach(searcher.FindAll()中的SearchResult)
{
新线程(委托()
{
if(result.GetDirectoryEntry().Name.StartsWith(“CN=))
{
字符串computerName=result.GetDirectoryEntry().Name.Remove(0,“CN=.Length”);
尝试
{
Dns.GetHostAddresses(计算机名);
}
捕获(SocketException)
{
不活动的computerName.Add(computerName);
}
}
}).Start();
}
foreach(InactiveComputerName中的字符串computerName)
{
DataRow newRow=\u InactiveComputers.newRow();
newRow[“ComputerName”]=计算机名称;
newRow[“CustomerName”]=CustomerName;
_不活动的computers.Rows.Add(newRow);
}
我有一个类似的要求,我想扫描网络中的IP地址,以确定正在使用的地址
我做了几个假设,首先,Ping不会在大多数设备上被阻止,其次,我们只处理特定范围的地址,例如192.168.x.x
这不是最干净的代码,只是一个快速而肮脏的示例,但下面将作为控制台应用程序运行,并演示如何将线程与Ping结合使用的基本原则
希望有帮助
你好,韦恩
using System;
using System.Net;
using System.Net.NetworkInformation;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Threading.Tasks;
namespace NetworkPing
{
class Program
{
private static int _Timeout = 120;
private static int nextLine = 0;
public static void Main(string[] args)
{
Console.WriteLine("NetworkPing!");
//check if any command line arguments have been supplied
if (args.Length > 0)
{
//parse the the arguments
foreach ( string arg in args)
{
switch( arg[1].ToString() )
{
case "?":
{
//display help topic
DisplayHelp();
}
break;
case "t":
{
//change the timout
_Timeout = Int32.Parse( GetParameter(arg) );
Console.WriteLine("Ping timeout set to {0}ms", _Timeout);
}
break;
}
}
}
DateTime startTime = DateTime.Now;
IPAddress[] Adresses2 = GetAllUnicastAddresses();
foreach (IPAddress Adres in Adresses2)
{
Console.WriteLine("");
Console.WriteLine("Local IP Address: {0}", Adres);
Console.WriteLine("Scanning IP from {0}.1 to {0}.254, awaiting results...", NetworkAddress(Adres) );
nextLine = Console.CursorTop;
Task[] tasks = new Task[254];
for (int i = 0; i != 254; i++)
{
//calculate the IP address for the ping
string ipAddressToPing = NetworkAddress( Adres ) + "." + (i+1);
//ping the address and check the response
tasks[ i ] = Task.Factory.StartNew( () => PingAddress(ipAddressToPing) );
}
//Block until all tasks complete.
Task.WaitAll(tasks);
}
TimeSpan ts = DateTime.Now - startTime;
Console.WriteLine("");
Console.WriteLine("Scan complete in {0} seconds, Press any key to continue...", ts.Seconds);
Console.ReadKey();
}
private static string GetParameter( string Argument )
{
return Argument.Substring( Argument.LastIndexOf(":") +1);
}
public static void DisplayHelp()
{
Console.WriteLine("Usage: PingNetwork [/?] or [-?] [-t:Timeout]");
Console.WriteLine("");
Console.WriteLine(" {0,-12} {1}","/?","Display these usage instructions");
Console.WriteLine(" {0,-12} {1}","-?","Display these usage instructions");
Console.WriteLine(" {0,-12} {1}","-t:timeout","Changes the default timout from 120ms");
Console.WriteLine("");
}
public static IPAddress[] GetAllUnicastAddresses()
{
// This works on both Mono and .NET , but there is a difference: it also
// includes the LocalLoopBack so we need to filter that one out
List<IPAddress> Addresses = new List<IPAddress>();
// Obtain a reference to all network interfaces in the machine
NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface adapter in adapters)
{
IPInterfaceProperties properties = adapter.GetIPProperties();
foreach (IPAddressInformation uniCast in properties.UnicastAddresses)
{
// Ignore loop-back, IPv6 and link-local
if (!IPAddress.IsLoopback(uniCast.Address) && uniCast.Address.AddressFamily!= AddressFamily.InterNetworkV6 && !uniCast.Address.ToString().StartsWith("169.254.") )
Addresses.Add(uniCast.Address);
}
}
return Addresses.ToArray();
}
private static void PingAddress( string IPAddress )
{
Ping pingSender = new Ping ();
PingOptions options = new PingOptions ();
// Use the default Ttl value which is 128,
// but change the fragmentation behavior.
options.DontFragment = true;
// Create a buffer of 32 bytes of data to be transmitted.
string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
byte[] buffer = System.Text.Encoding.ASCII.GetBytes (data);
PingReply reply = pingSender.Send(IPAddress, _Timeout, buffer, options);
if (reply.Status == IPStatus.Success)
{
//set the cursor to the next line
Console.CursorTop = nextLine;
//
Console.WriteLine( IPAddress + " :OK");
//
nextLine++;
}
}
private static string NetworkAddress( IPAddress Address )
{
string ipAddress = Address.ToString();
return ipAddress.Substring( 0, ipAddress.LastIndexOf(".") );
}
private static string LastOctet( IPAddress Address )
{
string ipAddress = Address.ToString();
return ipAddress.Substring( ipAddress.LastIndexOf(".") );
}
private static int _cursorX;
private static int _cursorY;
private static void GetCursor()
{
_cursorX = Console.CursorLeft;
_cursorY = Console.CursorTop;
}
private static void SetCursor()
{
Console.CursorLeft = _cursorX;
Console.CursorTop = _cursorY;
}
}
}
使用系统;
Net系统;
使用System.Net.NetworkInformation;
使用System.Collections.Generic;
使用System.Net.Sockets;
使用System.Threading.Tasks;
名称空间网络
{
班级计划
{
私有静态int_超时=120;
私有静态int nextLine=0;
公共静态void Main(字符串[]args)
{
Console.WriteLine(“NetworkPing!”);
//检查是否提供了任何命令行参数
如果(args.Length>0)
{
//解析参数
foreach(args中的字符串arg)
{
开关(arg[1].ToString())
{
案例“?”:
{
//显示帮助主题
显示帮助();
}
打破
案例“t”:
{
//改变时间表
_Timeout=Int32.Parse(GetParameter(arg));
WriteLine(“Ping超时设置为{0}ms”,_超时);
}
打破
}
}
}
DateTime startTime=DateTime.Now;
IPAddress[]地址S2=GetAllunicastAddresss();
foreach(地址中的IP地址2)
{
控制台。写线(“”);
WriteLine(“本地IP地址:{0}”,Adres);
WriteLine(“扫描从{0}.1到{0}.254的IP,等待结果…”,网络地址(Adres));
nextLine=Console.CursorTop;
Task[]tasks=新任务[254];
for(int i=0;i!=254;i++)
{
//计算ping的IP地址
字符串ipAddressToPing=网络地址(Adres)+“+(i+1);
//ping地址并检查响应
tasks[i]=Task.Factory.StartNew(()=>PingAddress(ipAddressToPing));
}
//阻止,直到所有任务完成。
Task.WaitAll(任务);
}
TimeSpan ts=日期时间.Now-startTime;
控制台。写线(“”);
WriteLine(“扫描在{0}秒内完成,按任意键继续…”,ts.seconds);
Console.ReadKey();
}
私有静态字符串GetParameter(字符串参数)
{
返回参数.Substring(参数.LastIndexOf(“:”)+1);
}
publicstaticvoiddisplayhelp()
{
Console.WriteLine(“用法:PingNetwork[/?]或[-?][-t:Timeout]”);
控制台。写线(“”);
安慰
SearchResultCollection results = searcher.FindAll();
List<string> inactiveComputerNames = new List<string>();
object threadLock = new object();
Parallel.ForEach( results.OfType<SearchResult>(), result =>
{
if( result.GetDirectoryEntry().Name.StartsWith( "CN=" ) )
{
string computerName = result.GetDirectoryEntry().Name.Remove( 0, "CN=".Length );
try
{
Dns.GetHostAddresses( computerName );
}
catch( SocketException )
{
lock( threadLock )
{
inactiveComputerNames.Add( computerName );
}
}
}
}
);