랜선과 와이파이를 번갈아 써야 하거나, 망 분리 환경에서 내부망 랜카드와 인터넷 랜카드를 하나씩만 켜야 하는 PC가 있습니다. 매번 제어판의 네트워크 연결 창을 열어 오른쪽 클릭으로 "사용 안 함"을 누르는 건 꽤 귀찮은 일이라, 콤보박스에서 하나 고르면 그 어댑터만 켜지고 나머지는 꺼지게 만들어 봤습니다. 해 보니 WMI 덕분에 코드가 정말 간단합니다.
준비
WMI를 쓰려면 프로젝트 참조에 System.Management 를 추가하고 코드 파일 위에 Imports System.Management 를 넣어야 합니다. 그리고 어댑터를 켜고 끄는 건 시스템 설정을 바꾸는 작업이라 관리자 권한으로 실행해야 합니다. 일반 권한으로 돌리면 예외 없이 그냥 아무 일도 안 일어나는 것처럼 보여서 한참 헤맬 수 있으니, 앱 매니페스트에 관리자 권한 요구를 넣어 두는 게 편합니다.
어댑터 목록 채우기
폼의 Load 이벤트 같은 곳에 넣습니다.
ComboBox2.Items.Clear()
Dim wmiQuery = New SelectQuery("SELECT * FROM Win32_NetworkAdapter " & "WHERE NetConnectionId != null ") '& "AND Manufacturer != 'Microsoft' "
Using mosSearcher = New ManagementObjectSearcher(wmiQuery)
For Each moItem As ManagementObject In mosSearcher.[Get]()
ComboBox2.Items.Add(DirectCast(moItem("NetConnectionId"), [String]))
Next
End Using
Win32_NetworkAdapter 에는 장치 관리자에 숨어 있는 가상 어댑터까지 잔뜩 들어 있습니다. NetConnectionId 는 네트워크 연결 창에 보이는 이름("이더넷", "Wi-Fi" 같은)인데, 실제 연결로 등록된 어댑터만 이 값이 있어서 != null 조건으로 걸러 내면 사용자가 아는 목록만 남습니다. 주석으로 남긴 Manufacturer != 'Microsoft' 조건을 살리면 마이크로소프트가 만든 가상 어댑터까지 빼고 실제 하드웨어만 볼 수 있습니다.
고른 것만 켜고 나머지는 끄기
Private Sub ComboBox2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox2.SelectedIndexChanged
Dim wmiQuery = New SelectQuery("SELECT * FROM Win32_NetworkAdapter " & "WHERE NetConnectionId != null ") '& "AND Manufacturer != 'Microsoft' "
Using mosSearcher = New ManagementObjectSearcher(wmiQuery)
For Each moItem As ManagementObject In mosSearcher.[Get]()
Using moItem
If DirectCast(moItem("NetConnectionId"), [String]) = ComboBox2.SelectedItem Then
moItem.InvokeMethod("Enable", Nothing)
Else
moItem.InvokeMethod("Disable", Nothing)
End If
End Using
Next
End Using
End Sub
같은 조건으로 어댑터를 다시 조회해서 이름이 선택한 항목과 같으면 Enable, 아니면 Disable 메서드를 부릅니다. WMI 클래스의 메서드는 InvokeMethod("이름", 인자) 로 호출하고, 이 두 메서드는 인자가 없어서 Nothing 을 넘깁니다.
쓰기 전에 생각할 것
이 코드는 선택한 것 말고 전부를 끕니다. VPN 어댑터나 가상 머신용 어댑터처럼 꺼지면 곤란한 것도 목록에 있으면 같이 꺼지니, 실제 PC에서 쓸 때는 목록에서 빼거나 끌 대상만 따로 정해 두는 게 안전합니다. 특히 원격 데스크톱으로 접속한 PC에서 돌리면 지금 접속에 쓰는 랜카드가 꺼지면서 연결이 끊기고, 다시 켤 방법이 없어집니다.
InvokeMethod 는 결과 코드를 반환하므로, 제대로 바뀌었는지 확인하려면 반환값을 받아 0인지 보면 됩니다. 0이 아니면 권한 문제인 경우가 대부분입니다. 그리고 어댑터를 켜도 IP를 받고 연결되기까지 몇 초 걸리니, 전환 직후 바로 인터넷 요청을 보내는 코드가 이어진다면 잠깐 기다리는 처리를 넣어 두세요.