在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了。

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 );
            
forint 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;
            
forint 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
posted on 2007-06-22 12:59  phytan  阅读(2682)  评论(1编辑  收藏  举报