场景

  1. 修改注册表和禁用系统服务可以通过批处理,是否可以通过Python来处理?
  2. 能否写一个Python脚本来禁用WIN7WIN10的自动更新?

说明

  1. 我在禁用自动更新批处理脚本里用批处理实现了两个功能:1.修改注册表的自动更新;2.禁用Windows Update启动。批处理能运行的前提是系统有sc,net,reg这3个命令,没有因系统的版本而被删除.
  2. 而使用Python写的脚本调用WIN32的函数来达到目的,这些API都是系统必须自带的,一定会存在,所以不用担心以上命令不存在。
  3. 对系统服务操作部分使用了pywin32库,这个库是第三方库,需要另外安装pip install pywin32, 如果安装不成功,可以单独去下载release版本安装包,注意对应的CPU版本amd64对应64位系统。,pywin32没有提供对本地组策略进行操作,使用C++操作IGroupPolicyObject时并没有成功执行. 由于时间费了太多不划算不解决编码修改本地组策略的两个值。有哪位同行有时间的可以实现这部分.

禁用 WIN7 和 WIN10 需要4个步骤.

# 方案一:
# 1、[Python实现]Windows+R,输入“regedit”回车,打开注册表编辑器,定位到  
# HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows在
# 「Windows」节点下新建一个名为「WindowsUpdate」的项在「WindowsUpdate」项下新建一个名为「AU」的项
# 在「HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU」下
# 新建一个名为「AUOptions」的 32 位 DWORD 值,双击该值,将数值设置为2.
#
# 2. [Python实现]鼠标右键“win”图标在弹出的菜单栏中选择“运行”选项,打开运行窗口后输入“services.msc”,回车.
# 在打开的窗口中找到“windows Update”启用选项.
# 在弹出的小窗口中的启动类型选项处点击选择“禁用”,点击“确定”
# https://www.zhihu.com/question/65332770

# 方案二:
# 1. [Python实现]按以下路径依次展开HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer项。
#    在右侧窗口新建DWORD值,将其数值名称命名为:NoWindowsUpdate,数值数据设置为:1
# 2. [未实现]请您同时按下微软徽标WIN键和R键,输入gpedit.msc回车,打开:计算机配置->管理模板->Windows组件->Windosw Update(更新),在右侧将配置自动更新和允许自动更新立即安装的状态改为已禁用
# https://answers.microsoft.com/zh-hans/windows/forum/windows_10-update/%E5%A6%82%E4%BD%95%E5%85%B3%E9%97%ADwin10%E7%B3%BB/9b324287-0453-4af6-9bc0-0b221ef476f2

代码

  1. 以下通过添加注册表两个禁用更新键值和关闭禁用Windows Update来达到禁用WIN10WIN7自动更新的目的.

forbid-autoupdate.py

import winreg
import subprocess
import os
import win32service
import pywintypes


def TestWinReg():
    explorer = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,"SOFTWARE\\Policies\\Microsoft\\Windows")

    try:
        i = 0
        while 1:
          name = winreg.EnumKey(explorer,i)
          print(repr(name))
          i += 1

    except WindowsError as err:
        print("OS error: {0}".format(err))

def AddForbidUpdateRegKeyValue(key,subKey,itemName,itemType,itemvalue):
    try:
        with winreg.CreateKey(key,subKey) as keyHandle:
            winreg.SetValueEx(keyHandle,itemName,0,itemType,itemvalue)
    except OSError as err:
        print("error: ",repr(err))
        pass

def RestoreUpdateAutoRegKeyValue(key,subKey,itemName):
    try:
        with winreg.OpenKey(key,subKey,0,winreg.KEY_SET_VALUE) as keyHandle:
            winreg.DeleteValue(keyHandle,itemName)
    except OSError as err:
        print("error: ",repr(err))
        pass

def AddServiceStartForbid(serviceName):
    # SC_MANAGER_ALL_ACCESS

    scHandle = None
    serviceHandle = None

    try:
        scHandle = win32service.OpenSCManager(None,None,win32service.SC_MANAGER_ALL_ACCESS)
        serviceHandle = win32service.OpenService(scHandle,serviceName,win32service.SERVICE_ALL_ACCESS )

        serviceStatus = win32service.QueryServiceStatus(serviceHandle)
        if (serviceStatus[1] != win32service.SERVICE_STOPPED):
            serviceStatus = win32service.ControlService(serviceHandle,win32service.SERVICE_CONTROL_STOP)
        print("serviceStatus: ",serviceStatus)

        win32service.ChangeServiceConfig(serviceHandle,win32service.SERVICE_NO_CHANGE,
            win32service.SERVICE_DISABLED,win32service.SERVICE_NO_CHANGE,None,None,0,None,None,None,None)
        
    except pywintypes.error  as err:
        print("error: ",repr(err))
    finally:
        if serviceHandle != None:
            win32service.CloseServiceHandle(serviceHandle)

        if scHandle != None:
            win32service.CloseServiceHandle(scHandle)

    # subprocess.run(["net","stop",serviceName])
    # subprocess.run(["sc","config",serviceName,"start=","disabled"])
    pass

def RestoreServiceStartManual(serviceName):

    scHandle = None
    serviceHandle = None

    try:
        scHandle = win32service.OpenSCManager(None,None,win32service.SC_MANAGER_ALL_ACCESS)
        serviceHandle = win32service.OpenService(scHandle,serviceName,win32service.SERVICE_ALL_ACCESS )

        win32service.ChangeServiceConfig(serviceHandle,win32service.SERVICE_NO_CHANGE,
            win32service.SERVICE_DEMAND_START,win32service.SERVICE_NO_CHANGE,None,None,0,None,None,None,None)
        
    except pywintypes.error  as err:
        print("error: ",repr(err))
    finally:
        if serviceHandle != None:
            win32service.CloseServiceHandle(serviceHandle)

        if scHandle != None:
            win32service.CloseServiceHandle(scHandle)

   

if __name__ == "__main__":

    AddForbidUpdateRegKeyValue(winreg.HKEY_LOCAL_MACHINE,
        "SOFTWARE\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU",
        "AUOptions",winreg.REG_DWORD,2)

    AddForbidUpdateRegKeyValue(winreg.HKEY_LOCAL_MACHINE,
        "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer",
        "NoWindowsUpdate",winreg.REG_DWORD,1)
    
    AddServiceStartForbid("wuauserv")

    # RestoreServiceStartManual("wuauserv")

    # RestoreUpdateAutoRegKeyValue(winreg.HKEY_LOCAL_MACHINE,
    #     "SOFTWARE\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU","AUOptions")
    
    # RestoreUpdateAutoRegKeyValue(winreg.HKEY_LOCAL_MACHINE,
    #     "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer","NoWindowsUpdate")
    # value, type = winreg.QueryValueEx(explorer, "DesktopProcess")
    # print("user is", repr(value))

打包

可以用pyinstaller来打包为一个EXE文件,当然pyinstaller也是第三方库. 或者官方下载安装包.

pip install pyinstaller

命令行执行以下命令,会生成forbid-autoupdate.exe文件

pyinstaller -F  forbid-autoupdate.py --uac-admin