在Vista的Control Panel\Network and Sharing Center 中,Network location types被分成了3大类, 即Public,Private 和Domain。 这些类型对网络通讯会造成一定影响。可以按字面来理解,Public为公用网络,需要较高的安全,这是限制比较严重的网络类型,基本一些普通的网络应用都搞不了。 Private为私人网络,可以打开一些网络共享等,属于比较灵活的能自己管理的网络。Domain为域网络,一般电脑加入域以后,许多东西就是由上面的域策略所控制了。自己能改的地方比较少,像防火墙是大多数自己关不了的。
手动改网络类型很容易, 在Control Panel\Network and Sharing Center中选择customize,可以在Public和Private中互换,Domain一般无法在这里手动修改。
编程实现的话,在许多介绍Vista的文章中,都只提到了一个Network Awareness API这个东东,这个主要用来读取网络的信息来实时提醒应用程序,提醒是否网络变了。如 http://msdn2.microsoft.com/en-us/library/ms697388.aspx 是专门用于Vista的,与XP的不同.
虽然Network Awareness说只是用来读取,但是据我研究,里面有个接口INetwork 包含了两个方法,INetwork.SetName() 可以修改网络的名称, INetwork.SetCategory()可以修改Network location types. 由于INetwork是接口,不能直接实例化,所以要靠另外一个NetworkListManager类来实现INetwork。
具体实现:
新建一个C# Console程序,然后在他的reference里面添加新的reference,选择COM组件,里面有个"Network List Manager 1.0 Type Library", 添加这个引用,VS2005中有,VS2003没试过,可能有。 添加这个引用后,就可以使用NetworkList命名空间中的NetworkListManagerClass了。
其中NetworkListItem 只是一个存取Name和INetwork的类,可以直接用个INetwork存,Name是多余的。 这个代码中包含3个方法UpdateNetworks,是即时更新网络信息的,PrintNetworks是列出网络信息,主要功能是ChangeNetworks,里面调用了INetwork.SetCategory这个方法, 改变了网络,并且是实时生效的。
还有一个方法,是改注册表的,不过不是实时起作用,改了后,虽然Network的描述变了,但是必须要重起后各个网络类型的策略才会起作用。注册表位置在:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles\{A6716226-BE20-43C8-B8AB-B154808EF060}
后面的{A6716226-BE20-43C8-B8AB-B154808EF060}各个电脑都不相同。
改动里面的键值:Category即可。 0x0表示Public,0x1表示Private, 0x2表示Domain。
工作环境: Vs.net 2005 + Vista
手动改网络类型很容易, 在Control Panel\Network and Sharing Center中选择customize,可以在Public和Private中互换,Domain一般无法在这里手动修改。
编程实现的话,在许多介绍Vista的文章中,都只提到了一个Network Awareness API这个东东,这个主要用来读取网络的信息来实时提醒应用程序,提醒是否网络变了。如 http://msdn2.microsoft.com/en-us/library/ms697388.aspx 是专门用于Vista的,与XP的不同.
虽然Network Awareness说只是用来读取,但是据我研究,里面有个接口INetwork 包含了两个方法,INetwork.SetName() 可以修改网络的名称, INetwork.SetCategory()可以修改Network location types. 由于INetwork是接口,不能直接实例化,所以要靠另外一个NetworkListManager类来实现INetwork。
具体实现:
新建一个C# Console程序,然后在他的reference里面添加新的reference,选择COM组件,里面有个"Network List Manager 1.0 Type Library", 添加这个引用,VS2005中有,VS2003没试过,可能有。 添加这个引用后,就可以使用NetworkList命名空间中的NetworkListManagerClass了。
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using NETWORKLIST;
namespace VistaNetworkManager
{
class NetworkManager
{
private NETWORKLIST.NetworkListManagerClass _networkListManager;
private string S_Connectivity, S_Connected, S_InternetConnected;
private List<NetworkListItem> _networks = new List<NetworkListItem>();
public NetworkManager()
{
_networkListManager = new NetworkListManagerClass();
_networkListManager.ConnectivityChanged += new INetworkListManagerEvents_ConnectivityChangedEventHandler( _networkListManager_ConnectivityChanged );
}
private void _networkListManager_ConnectivityChanged( NLM_CONNECTIVITY newConnectivity )
{
bool connected = _networkListManager.IsConnected;
bool internet = _networkListManager.IsConnectedToInternet;
}
public bool UpdateNetworks()
{
StringBuilder sb = new StringBuilder();
NLM_CONNECTIVITY connectivity = _networkListManager.GetConnectivity();
foreach( NLM_CONNECTIVITY c in Enum.GetValues( typeof( NLM_CONNECTIVITY ) ) )
{
if( ( connectivity & c ) == c )
{
sb.AppendFormat( "{0}, ", c );
}
}
S_Connectivity = sb.ToString();
S_Connected = _networkListManager.IsConnected.ToString();
S_InternetConnected = _networkListManager.IsConnectedToInternet.ToString();
foreach( INetwork net in _networkListManager.GetNetworks( NLM_ENUM_NETWORK.NLM_ENUM_NETWORK_ALL ) )
{
_networks.Add( new NetworkListItem( net.GetName(), net ) );
}
if( S_Connected.ToUpper() == "FALSE" || S_Connectivity.ToUpper() == "FALSE" )
{
Console.WriteLine( "The network is not connected, please check the connection of the network.\n" );
return false;
}
return true;
}
public void PrintNetworks()
{
Console.WriteLine( "The network informations of this Vista:" );
Console.WriteLine( "{0,-20}{1}", "Connected:", S_Connected );
Console.WriteLine( "{0,-20}{1}", "InternetConnected:", S_InternetConnected );
Console.WriteLine( "{0,-20}{1}\n", "Connectivity:", S_Connectivity );
for( int i = 0; i < _networks.Count; i++ )
{
INetwork network = _networks[ i ].Network;
if( network != null )
{
Console.WriteLine( "The {0} network:", i.ToString() );
Console.WriteLine( "{0,-20}{1}", "Name:", network.GetName() );
Console.WriteLine( "{0,-20}{1}", "Description:", network.GetDescription() );
Console.WriteLine( "{0,-20}{1}", "Category:", network.GetCategory().ToString() );
Console.WriteLine( "{0,-20}{1}", "Connectivity:", network.GetConnectivity().ToString() );
Console.WriteLine( "{0,-20}{1}\n", "Domain:", network.GetDomainType().ToString() );
}
}
}
public bool ChangeNetworks( int option )
{
bool result = false;
for( int i = 0; i < _networks.Count; i++ )
{
INetwork network = _networks[ i ].Network;
if( network != null )
{
Console.WriteLine( "Start to modify the {0} network: \"{1}\"", i.ToString(), _networks[ i ].Name );
if( network.GetConnectivity() == NLM_CONNECTIVITY.NLM_CONNECTIVITY_DISCONNECTED )
{
Console.WriteLine( "{0}\"{1}\" is DISCONNECTED, no need to be changed.", "Failure: ", _networks[ i ].Name );
}
else if( network.GetCategory() == NLM_NETWORK_CATEGORY.NLM_NETWORK_CATEGORY_DOMAIN_AUTHENTICATED )
{
Console.WriteLine( "Failure: " + "DOMAIN network can not be changed!!!" );
}
else
{
try
{
if( option == 1 )
{
network.SetCategory( NLM_NETWORK_CATEGORY.NLM_NETWORK_CATEGORY_PRIVATE );
Console.WriteLine( "Success: Network have been changed to PRIVATE." );
result = true;
}
else
{
network.SetCategory( NLM_NETWORK_CATEGORY.NLM_NETWORK_CATEGORY_PUBLIC );
Console.WriteLine( "Success: Network have been changed to PUBLIC." );
result = true;
}
}
catch( Exception e )
{
Console.WriteLine( "Failure: " + e.Message );
result = false;
}
}
Console.WriteLine( "" );
}
}
return result;
}
}
}
using System.Collections.Generic;
using System.Text;
using System.Data;
using NETWORKLIST;
namespace VistaNetworkManager
{
class NetworkManager
{
private NETWORKLIST.NetworkListManagerClass _networkListManager;
private string S_Connectivity, S_Connected, S_InternetConnected;
private List<NetworkListItem> _networks = new List<NetworkListItem>();
public NetworkManager()
{
_networkListManager = new NetworkListManagerClass();
_networkListManager.ConnectivityChanged += new INetworkListManagerEvents_ConnectivityChangedEventHandler( _networkListManager_ConnectivityChanged );
}
private void _networkListManager_ConnectivityChanged( NLM_CONNECTIVITY newConnectivity )
{
bool connected = _networkListManager.IsConnected;
bool internet = _networkListManager.IsConnectedToInternet;
}
public bool UpdateNetworks()
{
StringBuilder sb = new StringBuilder();
NLM_CONNECTIVITY connectivity = _networkListManager.GetConnectivity();
foreach( NLM_CONNECTIVITY c in Enum.GetValues( typeof( NLM_CONNECTIVITY ) ) )
{
if( ( connectivity & c ) == c )
{
sb.AppendFormat( "{0}, ", c );
}
}
S_Connectivity = sb.ToString();
S_Connected = _networkListManager.IsConnected.ToString();
S_InternetConnected = _networkListManager.IsConnectedToInternet.ToString();
foreach( INetwork net in _networkListManager.GetNetworks( NLM_ENUM_NETWORK.NLM_ENUM_NETWORK_ALL ) )
{
_networks.Add( new NetworkListItem( net.GetName(), net ) );
}
if( S_Connected.ToUpper() == "FALSE" || S_Connectivity.ToUpper() == "FALSE" )
{
Console.WriteLine( "The network is not connected, please check the connection of the network.\n" );
return false;
}
return true;
}
public void PrintNetworks()
{
Console.WriteLine( "The network informations of this Vista:" );
Console.WriteLine( "{0,-20}{1}", "Connected:", S_Connected );
Console.WriteLine( "{0,-20}{1}", "InternetConnected:", S_InternetConnected );
Console.WriteLine( "{0,-20}{1}\n", "Connectivity:", S_Connectivity );
for( int i = 0; i < _networks.Count; i++ )
{
INetwork network = _networks[ i ].Network;
if( network != null )
{
Console.WriteLine( "The {0} network:", i.ToString() );
Console.WriteLine( "{0,-20}{1}", "Name:", network.GetName() );
Console.WriteLine( "{0,-20}{1}", "Description:", network.GetDescription() );
Console.WriteLine( "{0,-20}{1}", "Category:", network.GetCategory().ToString() );
Console.WriteLine( "{0,-20}{1}", "Connectivity:", network.GetConnectivity().ToString() );
Console.WriteLine( "{0,-20}{1}\n", "Domain:", network.GetDomainType().ToString() );
}
}
}
public bool ChangeNetworks( int option )
{
bool result = false;
for( int i = 0; i < _networks.Count; i++ )
{
INetwork network = _networks[ i ].Network;
if( network != null )
{
Console.WriteLine( "Start to modify the {0} network: \"{1}\"", i.ToString(), _networks[ i ].Name );
if( network.GetConnectivity() == NLM_CONNECTIVITY.NLM_CONNECTIVITY_DISCONNECTED )
{
Console.WriteLine( "{0}\"{1}\" is DISCONNECTED, no need to be changed.", "Failure: ", _networks[ i ].Name );
}
else if( network.GetCategory() == NLM_NETWORK_CATEGORY.NLM_NETWORK_CATEGORY_DOMAIN_AUTHENTICATED )
{
Console.WriteLine( "Failure: " + "DOMAIN network can not be changed!!!" );
}
else
{
try
{
if( option == 1 )
{
network.SetCategory( NLM_NETWORK_CATEGORY.NLM_NETWORK_CATEGORY_PRIVATE );
Console.WriteLine( "Success: Network have been changed to PRIVATE." );
result = true;
}
else
{
network.SetCategory( NLM_NETWORK_CATEGORY.NLM_NETWORK_CATEGORY_PUBLIC );
Console.WriteLine( "Success: Network have been changed to PUBLIC." );
result = true;
}
}
catch( Exception e )
{
Console.WriteLine( "Failure: " + e.Message );
result = false;
}
}
Console.WriteLine( "" );
}
}
return result;
}
}
}
其中NetworkListItem 只是一个存取Name和INetwork的类,可以直接用个INetwork存,Name是多余的。 这个代码中包含3个方法UpdateNetworks,是即时更新网络信息的,PrintNetworks是列出网络信息,主要功能是ChangeNetworks,里面调用了INetwork.SetCategory这个方法, 改变了网络,并且是实时生效的。
还有一个方法,是改注册表的,不过不是实时起作用,改了后,虽然Network的描述变了,但是必须要重起后各个网络类型的策略才会起作用。注册表位置在:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles\{A6716226-BE20-43C8-B8AB-B154808EF060}
后面的{A6716226-BE20-43C8-B8AB-B154808EF060}各个电脑都不相同。
改动里面的键值:Category即可。 0x0表示Public,0x1表示Private, 0x2表示Domain。
工作环境: Vs.net 2005 + Vista