用代碼實現”停用/啟用”網路連接

來源:互聯網
上載者:User

代碼如下:

BOOL NetConnect(BOOL bConnect)
{
CoInitialize(NULL) ;

BOOL bReturn = FALSE ;
HRESULT hr ;
CComPtr<IShellDispatch> spShell ;

// search "Shell Object" in MSDN
hr = spShell.CoCreateInstance(CLSID_Shell, NULL, CLSCTX_INPROC_SERVER) ;

if (hr==S_OK)
{
   CComPtr<Folder> spFolder ;
   CComVariant varDir(49) ;
  
   spShell->NameSpace( varDir , &spFolder ) ;
  
   if (spFolder)
   {
    CComPtr<FolderItems> spFolderItems ;
   
    spFolder->Items(&spFolderItems) ;
   
    if (spFolderItems)
    {
     long length = 0;
    
     hr = spFolderItems->get_Count(&length) ;
    
     for (int i=0; i<length; i++)
     {
      CComVariant var (i);
      CComPtr<FolderItem> spFolderItem ;
     
      spFolderItems->Item(var, &spFolderItem ) ;
     
      if (spFolderItem)
      {
       CComBSTR bstr ;
      
       spFolderItem->get_Name(&bstr) ;
      
       // 遍曆網路連接
       // 要考慮系統版本的問題      
       if (wcsncmp( bstr, L"本地串連", 4)==0)
       {
        CComPtr<FolderItemVerbs> spFolderItemVerbs ;
       
        spFolderItem->Verbs(&spFolderItemVerbs) ;
       
        if (spFolderItemVerbs)
        {
         // 遍曆功能表項目
         long iMenu = 0 ;        
         hr = spFolderItemVerbs->get_Count(&iMenu) ;
        
         for (int m=0; m<iMenu; m++)
         {
          CComVariant var (m) ;
          CComPtr<FolderItemVerb> spFolderItemVerb;
         
          spFolderItemVerbs->Item(var, &spFolderItemVerb ) ;
         
          if (spFolderItemVerb)
          {
           CComBSTR bstrMenuName ;
           LPWSTR pwzMenuName = bConnect ? L"啟用":L"停用" ;
           spFolderItemVerb->get_Name(&bstrMenuName) ;

          
           if (wcsncmp(bstrMenuName, pwzMenuName , 2)==0)
           {
            // 執行功能表命令
            bReturn = spFolderItemVerb->DoIt()==S_OK ;
           }
          }
         }
        }
       
       }
      }
     }
    
    }
   }
}

CoUninitialize();

return bReturn ;
}

以上代碼在 xp sp2+vc6+200408-psdk 測試通過 。

   此方法並不是我想出來的,而是在CSDN論壇上的VB版塊找到的一段VB代碼翻譯過來的。由這個舉一反三,可以實現更多的功能。代碼還是有缺陷的, 程式通過名稱來尋找要執行的命令,因此不能在所有語言的平台上相容。還有,有效串連可能不一定叫“本地串連”,另外不能在98下使用。

    另外附上用SetupAPI實現的代碼,這種方式更具有通用性,推薦使用。

#include <SetupAPI.h>
#include <cfgmgr32.h>   // cfgmgr32.h 在Microsoft Windows 2000 DDK 中.
#pragma comment(lib,"setupapi.lib")

BOOL IsDisableable(DWORD dwDevID, HDEVINFO hDevInfo) ;
BOOL IsDisabled(DWORD dwDevID, HDEVINFO hDevInfo) ;
BOOL StateChange( DWORD dwNewState, DWORD dwDevID, HDEVINFO hDevInfo) ;

//////////////////////////////////////////////////////////////////////////
// 獲得裝置註冊表中的內容
//////////////////////////////////////////////////////////////////////////
BOOL GetRegistryProperty( HDEVINFO DeviceInfoSet,
                        PSP_DEVINFO_DATA DeviceInfoData,
                        ULONG Property,
                        PVOID Buffer,
                        PULONG Length )
{
    while ( !SetupDiGetDeviceRegistryProperty( DeviceInfoSet,
                                               DeviceInfoData,
                                               Property,
                                               NULL,
                                               (BYTE *)*(TCHAR **)Buffer,
                                               *Length,
                                               Length))
    {
        // 長度不夠則重新分配緩衝區
        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
        {
            if (*(LPTSTR *)Buffer)
                LocalFree(*(LPTSTR *)Buffer);

            *(LPTSTR *)Buffer = (PCHAR)LocalAlloc(LPTR,*Length);
        }
        else
        {
            return false;
        }
    }

    return (BOOL)(*(LPTSTR *)Buffer)[0];
}

BOOL EnableDevice(DWORD dwDevID, HDEVINFO hDevInfo)
{
    return StateChange(DICS_ENABLE,dwDevID,hDevInfo);
}

BOOL DisableDevice(DWORD dwDevID, HDEVINFO hDevInfo)
{
    return StateChange(DICS_DISABLE,dwDevID,hDevInfo);
}

BOOL ControlDevice(DWORD dwDevID, HDEVINFO hDevInfo)
{
    BOOL bCanDisable;
    bCanDisable = (IsDisableable(dwDevID,hDevInfo) && (!IsDisabled(dwDevID,hDevInfo)));
    if(bCanDisable)
        return DisableDevice(dwDevID,hDevInfo);
    else
        return EnableDevice(dwDevID,hDevInfo);
}

void EnumNetCards()
{        
   
    DWORD Status, Problem;
    LPTSTR Buffer = NULL;
    DWORD BufSize = 0;

    // 返回所有裝置資訊
    HDEVINFO hDevInfo = SetupDiGetClassDevs(NULL,NULL,0,DIGCF_PRESENT|DIGCF_ALLCLASSES) ;

    if (INVALID_HANDLE_VALUE == hDevInfo )       
        return;

   
    SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)};

   
       

    //////////////////////////////////////////////////////////////////////////
    // 枚舉裝置
    //////////////////////////////////////////////////////////////////////////
    for ( DWORD DeviceId=0;
        SetupDiEnumDeviceInfo( hDevInfo,DeviceId,&DeviceInfoData);
        DeviceId++)
    {

        // 獲得裝置的狀態
        if (CM_Get_DevNode_Status(&Status, &Problem, DeviceInfoData.DevInst ,0) != CR_SUCCESS)
            continue;
               

        // 擷取裝置類名
        TCHAR szDevName [MAX_PATH] = _T("") ;
        if (GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_CLASS , &Buffer, (PULONG)&BufSize))
        {
            lstrcpyn( szDevName, Buffer, MAX_PATH ) ;           
        }

        if ( lstrcmp( szDevName, _T("Net") ) == 0 )           
        {            
            TCHAR szName [MAX_PATH] = _T("") ;
            if (GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_ENUMERATOR_NAME , &Buffer, (PULONG)&BufSize))
            {
                lstrcpyn( szName, Buffer, MAX_PATH ) ;
            }

            if ( lstrcmp( szName, _T("ROOT") ) != 0 )               
            {

                if (GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_DRIVER , &Buffer, (PULONG)&BufSize))
                {
                    lstrcpyn( szName, Buffer, MAX_PATH ) ;

                    // 擷取裝置描述
                    if (GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_DEVICEDESC , &Buffer, (PULONG)&BufSize))
                    {
                       
                        lstrcpyn( szName, Buffer, MAX_PATH ) ;

                       
                        if(ControlDevice(DeviceId,hDevInfo))
                        {
                            printf("Successful/n");
                        }
                        else
                        {
                            printf("FAILED/n");       
                        }
                       
                    }                   
                }
            }
        }
    }

    SetupDiDestroyDeviceInfoList(hDevInfo);
}

BOOL StateChange( DWORD dwNewState, DWORD dwDevID, HDEVINFO hDevInfo)
{
    SP_PROPCHANGE_PARAMS PropChangeParams;
    SP_DEVINFO_DATA        DevInfoData = {sizeof(SP_DEVINFO_DATA)};
    SP_DEVINSTALL_PARAMS devParams;

    //查詢裝置資訊
    if (!SetupDiEnumDeviceInfo( hDevInfo, dwDevID, &DevInfoData))
    {
        OutputDebugString("SetupDiEnumDeviceInfo FAILED");
        return FALSE;
    }

    //設定裝置屬性變化參數
    PropChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
    PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
    PropChangeParams.Scope = DICS_FLAG_GLOBAL; //使修改的屬性儲存在所有的硬體屬性檔案
    PropChangeParams.StateChange = dwNewState;
    PropChangeParams.HwProfile = 0;

    //改變裝置屬性
    if (!SetupDiSetClassInstallParams( hDevInfo,
                                        &DevInfoData,
                                        (SP_CLASSINSTALL_HEADER *)&PropChangeParams,
                                        sizeof(PropChangeParams)))
    {
        OutputDebugString("SetupDiSetClassInstallParams FAILED");
        return FALSE;
    }
   
   
    PropChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
    PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
    PropChangeParams.Scope = DICS_FLAG_CONFIGSPECIFIC;//使修改的屬性儲存在指定的屬性檔案
    PropChangeParams.StateChange = dwNewState;
    PropChangeParams.HwProfile = 0;

    //改變裝置屬性並調用安裝服務
    if (!SetupDiSetClassInstallParams( hDevInfo,
                                       &DevInfoData,
                                       (SP_CLASSINSTALL_HEADER *)&PropChangeParams,
                                       sizeof(PropChangeParams)) ||
        !SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hDevInfo, &DevInfoData))
    {
        OutputDebugString("SetupDiSetClassInstallParams or SetupDiCallClassInstaller FAILED");
        return TRUE;
    }
    else
    {
        //判斷是否需要重新啟動
        devParams.cbSize = sizeof(devParams);
        if (!SetupDiGetDeviceInstallParams( hDevInfo, &DevInfoData, &devParams))
        {
            OutputDebugString("SetupDiGetDeviceInstallParams FAILED");
            return FALSE;
        }

        if (devParams.Flags & (DI_NEEDRESTART|DI_NEEDREBOOT))
        {
            OutputDebugString("Need Restart Computer");
            return TRUE;
        }
        return TRUE;
    }
}

BOOL IsDisableable(DWORD dwDevID, HDEVINFO hDevInfo)
{
    SP_DEVINFO_DATA DevInfoData = {sizeof(SP_DEVINFO_DATA)};
    DWORD    dwDevStatus,dwProblem;
    if(!SetupDiEnumDeviceInfo(hDevInfo,dwDevID,&DevInfoData))
    {
        OutputDebugString("SetupDiEnumDeviceInfo FAILED");
        return FALSE;
    }
    //查詢裝置狀態
    if(CM_Get_DevNode_Status(&dwDevStatus,&dwProblem,DevInfoData.DevInst,0)!=CR_SUCCESS)
    {
        OutputDebugString("CM_GET_DevNode_Status FAILED");
        return FALSE;
    }
    return ((dwDevStatus & DN_DISABLEABLE) && (dwProblem != CM_PROB_HARDWARE_DISABLED));
}

BOOL IsDisabled(DWORD dwDevID, HDEVINFO hDevInfo)
{
    SP_DEVINFO_DATA DevInfoData = {sizeof(SP_DEVINFO_DATA)};
    DWORD    dwDevStatus,dwProblem;
    if(!SetupDiEnumDeviceInfo(hDevInfo,dwDevID,&DevInfoData))
    {
        OutputDebugString("SetupDiEnumDeviceInfo FAILED");
        return FALSE;
    }

    //查詢裝置狀態
    if(CM_Get_DevNode_Status(&dwDevStatus,&dwProblem,DevInfoData.DevInst,0)!=CR_SUCCESS)
    {
        OutputDebugString("CM_GET_DevNode_Status FAILED");
        return FALSE;
    }
    return ((dwDevStatus & DN_HAS_PROBLEM) && (dwProblem == CM_PROB_DISABLED));
}

int main(int argc, char* argv[])
{       
    EnumNetCards() ;
    return 0 ;

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.