-->

[파이썬] winreg 모듈을 사용한 레지스트리 등록 (윈도우 자동업데이트 해제)

 

파이썬으로 윈도우 레지스트리를 다뤄보는 이유는 보통 윈도우 배치파일(.bat) 을 생성할 때 필요하기 때문이다. 이번 포스팅에서는 파이썬 winreg 모듈을 사용해 '윈도우10 자동 업데이트 비활성화'를 가정하고 이를 위한 레지스트리 키를 생성하고 값을 등록해보려 한다. 

 

 

winreg 모듈

winreg는 윈도우 레지스터리에 관한 API를 제공하는 파이썬 모듈로 아래 링크에서 제공되는 API를 확인할 수 있다.

 


Python 공식 홈페이지, winreg

 

winreg — Windows registry access — Python 3.8.1 documentation

winreg — Windows registry access These functions expose the Windows registry API to Python. Instead of using an integer as the registry handle, a handle object is used to ensure that the handles are closed correctly, even if the programmer neglects to expl

docs.python.org

 

 

참고로 winreg는 내장 모듈이기 때문에, 따로 설치할 필요가 없다.

 

파이썬3 버전부터 모듈이름이 변경되었는데, 파이썬2 버전은 모듈 이름이 '_winreg' 이고 파이썬3 버전은 'winreg'이다. 옛날에 썼던 _winreg 관련 코드를 보면서 당연히 pip 설치겠거니 하고 설치하려는데 설치가 안돼서 내장 모듈이구나 하고 _winreg를 임포트시켜봤는데 안돼서 조금 삽질을 했다. 구글링하고나서, 파이썬3 에서 모듈 이름이 winreg로 변경된 걸 알게됐다.

 


파이썬2 : _winreg

파이썬3: winreg

 

 

레지스트리 키 생성

키 생성 전, 'SOFTWARE>Policies>Microsoft>Windows'를 확인하면 WindowsUpdate 키가 없는 것을 볼수있다.

 

SOFTWARE>Policies>Microsoft>Windows

 

 

레지스트리 키 생성에는 winreg 모듈의 CreateKey 함수를 사용한다. 윈도우10 자동 업데이트 비활성화를 위해선, 총 2개의 키를 생성해야 한다.

 

나만 그랬는지는 모르겠지만 key, sub_key 구분을 정확히 어디서부터 시켜줘야 하는지? 좀 헷갈렸었는데, 밑에 실제 코드와 위 링크해놓은 winreg 함수 사용법 페이지를 보면서 함수 사용법을 익히는게 좋을 것 같다.

 


from winreg import *

# 레지스트리 키 생성
CreateKey(key, sub_key)

 

'SOFTWARE>Policies>Microsoft>Windows' 경로에 WindowsUpdate 키를 먼저 생성하고 그다음, 생성한 WindowsUpdate 키 하위에 다시 AU 키를 생성한다(AU는 Auto Update 를 의미한다).

 


SOFTWARE>Policies>Microsoft>Windows>WindowsUpdate

SOFTWARE>Policies>Microsoft>Windows>WindowsUpdate>AU

 

 

코드는 아래와 같다.

 


#-*- coding: utf-8 -*-
from winreg import *

winup_path=r"SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"

# 'WindowsUpdate' 키 생성
CreateKey(HKEY_LOCAL_MACHINE,winup_path)

# 'WindowsUpdate'하위의 'AU' 키 생성
au_path=winup_path+r"\AU"
CreateKey(HKEY_LOCAL_MACHINE,au_path)

 

위 코드를 (관리자 권한으로) 실행하면 아래와 같이 키가 생성된 것을 볼 수 있다.

 

SOFTWARE>Policies>Microsoft>Windows 하위 키 생성

 

 

레지스트리 연결 및 키 열기

실제로 레지스트리 키에 값을 등록하기 전에 레지스트리에 연결하고 키를 여는 작업이 필요하다. 각각 아래와 같이 winreg 함수를 사용하면 된다. ConnectRegistry 함수를 이용해서 레지스트리 핸들을 얻고 해당 핸들을 Openykey의 첫번째 인자로 넘겨주는 방식으로 사용한다. 

 


from winreg import *
    
# 레지스트리와 연결 생성 후 핸들 얻음
reg_handle = ConnectRegistry(None, key)

# 레지스트리 핸들을 이용해서 키를 엶
key = OpenKey(reg_handle, sub_key, reserved=0, access=KEY_READ)

 

실제 사용할 코드는 아래와 같다. 기본 access가 KEY_READ이기 때문에 KEY_WRITE 으로 변경해준다.

 


#-*- coding: utf-8 -*-
from winreg import *

winup_path=r"SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"

# HKEY_LOCAL_MACHINE와 연결 생성 후 핸들 얻음
reg_handle = ConnectRegistry(None, HKEY_LOCAL_MACHINE)

# 얻은 행동을 사용해 WRITE 권한으로 레지스트리 키를 엶
au_path = winup_path + r"\AU"
key = OpenKey(reg_handle, au_path, 0, KEY_WRITE)

 

 

레지스트리 키 값 등록

이제 AU키에 아래와 같은 값을 등록해주면 된다.

 


값 이름: NoAutoUpdate

값 데이터: 1

단위: 16진수

 

 

키 값을 등록할 때는 winreg의 SetValueEx 함수를 사용하면 된다. OpenKey 함수의 반환 값으로 받은 결과를 SetValueEx의 첫번째 인자로 주면, 해당 키에 대한 값을 저장할 수 있다.

 

from winreg import *

# 열린 레지스트리 키에 대해 지정된 값을 저장
SetValueEx(key, value_name, reserved, type, value)

 

참고로, SetValue 함수를 사용하지 않고 SetValueEx 함수를 사용하는 이유는 SetValue의 경우 데이터 타입으로 REG_SZ와 같은 string 타입만 지원하기 때문이다. 다른 타입을 사용하려면 SetValueEx 를 사용하라고 나와있다.

 

SetValue 와 SetValueEx 의 차이 (출처: python docs)

 

 

실제 사용할 코드는 아래와 같다.

 


#-*- coding: utf-8 -*-
from winreg import *

# 레지스트리 키 값을 등록
SetValueEx(key, "NoAutoUpdate", 0, REG_DWORD, 0x1)

 

그럼 아래와 같이 원했던 값이 생성되어 있는 것을 볼 수 있다.

 

 

 

전체 코드

맨 마지막에 CloseKey로 키를 닫아주면 끝이다. 전체 코드는 아래와 같다.

 


#-*- coding: utf-8 -*-
from winreg import *

winup_path=r"SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"

def make_registry():

    # 'WindowsUpdate' 키 생성
    CreateKey(HKEY_LOCAL_MACHINE,winup_path)
    
    # 'WindowsUpdate' 하위의 'AU' 키 생성
    au_path=winup_path+r"\AU"
    CreateKey(HKEY_LOCAL_MACHINE,au_path)


def register_registry():
    
    # HKEY_LOCAL_MACHINE와 연결 생성 후 핸들 얻음
    reg_handle = ConnectRegistry(None, HKEY_LOCAL_MACHINE)
    
    # 얻은 행동을 사용해 WRITE 권한으로 레지스트리 키를 엶
    au_path = winup_path + r"\AU"
    key = OpenKey(reg_handle, au_path, 0, KEY_WRITE)

    #레지스트리 값을 등록
    try:
        SetValueEx(key,"NoAutoUpdate",0, REG_DWORD, 0x1)
    except EnvironmentError:
        print("Encountered problems writing into the Registry...")

    #레지스트리를 닫음
    CloseKey(key)
    CloseKey(reg)


make_registry()
register_registry()

 

댓글

Designed by JB FACTORY