본문 바로가기

Autohotkey강좌

Autohotkey#49, 고정IP/유동IP Setting 자동화

반응형

https://youtu.be/DaPmUbUik_w

 

- YouTube

 

www.youtube.com

일하는 환경이 자주 바뀌는 분들의 경우, 유동IP와 고정IP간에 변환을 자주 변경해 줘야 하는 경우가 많이 있다. 그럴 때마다 매번, 네트웍 어댑터 설정에 들어가서 TCP/IP설정을 변경해 주는 과정은 대략 다음과 같다.

네트워크 및 인터넷 -> 어댑터 옵션 변경 -> 

네트워크 및 인터넷 

=>

어댑터 옵션 변경

=> 마우스 우클릭 => 속성 => 

=> 인터넷 프로토콜 버전 4(TCP/IPv4)

이렇게 진입해서 원하는 IP로 변경하면 되는데, 매번 이렇게 바꾸는 것은 엄청 귀찮은 일입니다.

그래서 사용자의 네트워크 어댑터를 읽어 와서, 원하는 IP를 설정하도록 구성하려고 합니다.

UI의 구성은 다음과 같이 하겠습니다.

LAN어댑터 항목은 사용자의 네트워크 어댑터를 모두 읽어 와서 보여주도록 하고, 나머지 항목은 원하는 IP주소, Gateway, DNS서버 주소 등을 설정할 수 있도록 EDIT창으로 받아 들입니다. 원하는 값이 모두 입력되었다면 아래쪽의 고정IP Change와 유동IP Change중에서 선택해서 누르면 해당 방식으로 설정하도록 합니다. 마지막으로 우하귀쪽에는 Save Setting버튼을 넣어서 현재 가지고 있는 설정값을 저장할 수 있도록 해서 다음에 실행할 때는 해당 값을 읽어 오도록 기능을 구현하려고 합니다.

먼저 LAN어댑터를 읽어 오기 위해서는 어떻게 해야 할까요? 똑똑한 분들이 잘 만들어 놓은 실행파일이 있습니다. 바로 

iphlpapi.dll의 GetAdaptersAddresses함수입니다. 우리는 그저 아래처럼 가져다 쓰면 됩니다. 

DllCall("iphlpapi.dll\GetAdaptersAddresses", "uint", 2, "uint", 0, "ptr", 0, "ptr", 0, "uint*", size)

에러날 경우를 대비하여 아래처럼 함수로 구현해 놓은 것이 있으므로 우리는 감사히 생각하며 가져다 사용하면 되겠습니다. (만들어 주신 고수님들 정말 감사합니다.)
GetAdaptersAddresses()
{
static ERROR_SUCCESS         := 0
static ERROR_BUFFER_OVERFLOW := 111

if (DllCall("iphlpapi.dll\GetAdaptersAddresses", "uint", 2, "uint", 0, "ptr", 0, "ptr", 0, "uint*", size) = ERROR_BUFFER_OVERFLOW)
{
VarSetCapacity(buf, size, 0)
if (DllCall("iphlpapi.dll\GetAdaptersAddresses", "uint", 2, "uint", 0, "ptr", 0, "ptr", &buf, "uint*", size) = ERROR_SUCCESS)
{
addr := &buf, IP_ADAPTER_ADDRESSES_LH := []
while (addr)
{
IP_ADAPTER_ADDRESSES_LH[A_Index, "FriendlyName"] := StrGet(NumGet(addr + 8, A_PtrSize * 8, "uptr"), "utf-16")
addr := NumGet(addr + 8, "uptr")
}
return IP_ADAPTER_ADDRESSES_LH, VarSetCapacity(buf, 0)
}
VarSetCapacity(buf, 0)
}
return ""
}

이 함수를 기본으로 ReadAdapter()함수를 만들어 보면 다음과 같습니다.

ReadAdapter()
{
Adapters := GetAdaptersAddresses()
mylist :=
for k, v in Adapters
if k = 1
mylist := v.FriendlyName . "|"
else
mylist .= "|" . v.FriendlyName
return mylist
}
return

얻어진 내용을 mylist에 저장해서 반환하도록 합니다. 그리고 첫번째 항목을 default로 설정하도록 ||를 연속으로 넣어 지도록 합니다. 이렇게 얻어진 list를 DropDownList로 추가합니다.

mydroplist := ReadAdapter()
ReadSetting()
Gui, Add, Text, x30 y30 w100 h20, LAN 어댑터 ;
Gui, Add, DropDownList, x150 y30 w150 h999 vadapter, % mydroplist

중간에 ReadSetting()함수는 기존에 저장해 놓은 설정파일이 있다면 읽어오도록 다음과 같이 구현합니다.

ReadSetting()
{
  global ip, gw, sm, dns1, dns2
  IfExist %A_ScriptDir%\ipipconfig.ini
  {
    Loop
    {
      FileReadLine, param, %A_ScriptDir%\ipconfig.ini, %A_Index%
      if ErrorLevel
        break
      par :=StrSplit(param,[":","`r`n"])

      switch par[1]
      {
      case "ip" :
        ip := par[2]
        continue
      case "gw" :
        gw := par[2]
        continue
      case "dns1" :
        dns1 := par[2]
        continue
      case "dns2" :
        dns2 := par[2]
        continue
      case "sm" :
        sm := par[2]
        continue
      default :
        break
      }
    }
    Guicontrol,, ip, %ip%
    Guicontrol,, gw, %gw%
    Guicontrol,, sm, %sm%
    Guicontrol,, dns1, %dns1%
    Guicontrol,, dns2, %dns2%
  } else {
    ip = 192.168.0.200
    sm = 255.255.255.0 
    gw = 192.168.0.1
    dns1 =8.8.8.8
    dns2 =8.8.4.4
  }
}
return

else항목에는 해당 설정파일이 없을 경우 지정할 값을 넣어 주면 됩니다.

이제 Save Setting버튼을 눌렀을때 해야 할 일을 구현합니다.

ButtonSaveSetting:
{
  Gui, Submit, nohide

  IfExist %A_ScriptDir%\ipconfig.ini
    FileDelete, %A_ScriptDir%\ipconfig.ini
  ip := "ip:" + ip
  sm := "sm:" + sm 
  gw := "gw:" + gw
  dns1 := "dns1:" + dns1 
  dns2 := "dns2:" + dns2
  FileAppend, %ip%`r`n, %A_ScriptDir%\ipconfig.ini
  FileAppend, %sm%`r`n, %A_ScriptDir%\ipconfig.ini
  FileAppend, %gw%`r`n, %A_ScriptDir%\ipconfig.ini
  FileAppend, %dns1%`r`n, %A_ScriptDir%\ipconfig.ini
  FileAppend, %dns2%, %A_ScriptDir%\ipconfig.ini
}
return

이제 고정IpChange버튼을 눌렀을때 해야 할 일을 구현해 줍니다.

Button고정IpChange:
{
  Gui, Submit, nohide
  RunWait ,*RunAs %comspec% /c netsh -c interface ipv4 set address name="%adapter%" source=static addr=%ip% mask=%sm% gateway=%gw% gwmetric=0  ,, Hide
; RunWait ,*RunAs %comspec% /c netsh -c interface ip set dns name="%adapter%" source=static addr=%dns1% register=PRIMARY  ,, Hide
  RunWait ,*RunAs %comspec% /c netsh -c interface ip ADD dnsservers name="%adapter%" address=%dns1% INDEX=1  ,, Hide
  RunWait ,*RunAs %comspec% /c netsh -c interface ip ADD dnsservers name="%adapter%" address=%dns2% INDEX=2  ,, Hide
  MsgBox , 고정IP로 설정하였습니다.
}
return

특히 관리자권한으로 실행하지 않으면 해당 내용이 반영이 되지 않기 때문에  RunWait, *RunAs %comspec% ... 과 같이 실행해 줘야 제대로 설정됩니다. 특히 DNS서버설정의 경우 기존에 흔히 알고 있는 방식대비해서 다른 방식이므로 주의깊게 봐 주시기 바랍니다.

다음은 유동IpChange버튼이 눌렸을때 동작입니다. 고정IP대비 간단합니다.

Button유동IpChange:
{
  Gui, Submit, nohide
  RunWait ,*RunAs %comspec% /c netsh -c interface ip set address name="%adapter%" source=dhcp,, Hide
  RunWait ,*RunAs %comspec% /c netsh -c interface ip set dns name="%adapter%" source=dhcp  ,, Hide
  MsgBox , 유동IP로 설정하였습니다.
}
return

이제 End, ESC버튼이 눌리거나 GuiClose나 GuiEscape가 발생했을 경우  App을 종료하도록 처리해 줍니다.

ButtonEnd:
{
  ExitApp
}
return

GuiClose:
GuiEscape:
ExitApp
return

ESC::goto, ButtonEnd
return

나머지는 기본적인 GUI항목이므로 간단히 보시면 되겠습니다.

아래는 스크립트와 실행파일입니다.

IP_SettingV1.0.ahk
0.00MB
IP_SettingV1.0.exe
0.60MB

 

반응형