# 34.3. `winreg` - Windows注册表访问

这些函数将Windows注册表API暴露给Python。代替使用整数作为注册表句柄，handle object用于确保句柄正确关闭，即使程序员忽略明确关闭它们。

在版本3.3中更改：此模块中的几个函数用于引发`WindowsError`，现在是`OSError`的别名。

## 34.3.1. Functions

该模块提供以下功能：

`winreg.``CloseKey`(hkey)

  关闭以前打开的注册表项。hkey参数指定先前打开的键。

  注意

  如果hkey未使用此方法关闭（或通过`hkey.Close()`），则当python销毁hkey时它会关闭 。

`winreg.``ConnectRegistry`(computer_name, key)

  与另一台计算机上的预定义注册表句柄建立连接，并返回handle object。

  computer_name是远程计算机的名称，格式为`r"\\computername"`。如果`None`，则使用本地计算机。

  键是要连接的预定义句柄。

  返回值是打开的键的句柄。如果函数失败，则会引发`OSError`异常。

  在版本3.3中更改：请参见上述above。

`winreg.``CreateKey`(key, sub_key)

  创建或打开指定的键，返回handle object。

  键是已打开的键，或者是预定义的HKEY_* constants之一。

  sub_key是一个字符串，用于命名此方法打开或创建的键。

  如果键是预定义键之一，则sub_key可以是`None`。在这种情况下，返回的句柄是传递给函数的相同的键句柄。

  如果键已经存在，则此函数将打开现有键。

  返回值是打开的键的句柄。如果函数失败，则会引发`OSError`异常。

  在版本3.3中更改：请参见上述above。

`winreg.``CreateKeyEx`(key, sub_key, reserved=0, access=KEY_WRITE)

  创建或打开指定的键，返回handle object。

  键是已打开的键，或者是预定义的HKEY_* constants之一。

  sub_key是一个字符串，用于命名此方法打开或创建的键。

  保留是保留的整数，必须为零。默认值为零。

  访问是一个整数，指定描述密钥所需的安全访问的访问掩码。默认值为`KEY_WRITE`。有关其他允许的值，请参见Access Rights。

  如果键是预定义键之一，则sub_key可以是`None`。在这种情况下，返回的句柄是传递给函数的相同的键句柄。

  如果键已经存在，则此函数将打开现有键。

  返回值是打开的键的句柄。如果函数失败，则会引发`OSError`异常。

  版本3.2中的新功能。

  在版本3.3中更改：请参见上述above。

`winreg.``DeleteKey`(key, sub_key)

  删除指定的键。

  键是已打开的键，或者是预定义的HKEY_* constants之一。

  sub_key是一个字符串，它必须是由键参数标识的键的子键。此值不能为`None`，并且键可能没有子键。

  此方法无法删除带有子键的键。

  如果方法成功，则删除整个键（包括其所有值）。如果方法失败，则会引发`OSError`异常。

  在版本3.3中更改：请参见上述above。

`winreg.``DeleteKeyEx`(key, sub_key, access=KEY_WOW64_64KEY, reserved=0)

  删除指定的键。

  注意

  `DeleteKeyEx()`函数使用RegDeleteKeyEx Windows API函数实现，该函数专用于64位版本的Windows。请参阅RegDeleteKeyEx文档。

  键是已打开的键，或者是预定义的HKEY_* constants之一。

  sub_key是一个字符串，它必须是由键参数标识的键的子键。此值不能为`None`，并且键可能没有子键。

  保留是保留的整数，必须为零。默认值为零。

  访问是一个整数，指定描述密钥所需的安全访问的访问掩码。默认值为`KEY_WOW64_64KEY`。有关其他允许的值，请参见Access Rights。

  此方法无法删除带有子键的键。

  如果方法成功，则删除整个键（包括其所有值）。如果方法失败，则会引发`OSError`异常。

  在不受支持的Windows版本上，会出现`NotImplementedError`。

  版本3.2中的新功能。

  在版本3.3中更改：请参见上述above。

`winreg.``DeleteValue`(key, value)

  从注册表项中删除命名的值。

  键是已打开的键，或者是预定义的HKEY_* constants之一。

  value是标识要删除的值的字符串。

`winreg.``EnumKey`(key, index)

  枚举打开的注册表项的子项，返回一个字符串。

  键是已打开的键，或者是预定义的HKEY_* constants之一。

  index是一个整数，用于标识要检索的键的索引。

  该函数在每次被调用时检索一个子键的名称。它通常被重复调用，直到出现`OSError`异常，表明没有更多的值可用。

  在版本3.3中更改：请参见上述above。

`winreg.``EnumValue`(key, index)

  枚举打开的注册表项的值，返回元组。

  键是已打开的键，或者是预定义的HKEY_* constants之一。

  index是一个整数，用于标识要检索的值的索引。

  该函数在每次被调用时检索一个子键的名称。它通常被重复调用，直到出现`OSError`异常，表示没有更多的值。

  结果是一个3个项目的元组：

  指数 | 含义
  --- | ---
  `0` | 标识值名称的字符串
  `1` | 保存值数据的对象，其类型取决于底层注册表类型
  `2` | 标识值数据类型的整数（请参阅`SetValueEx()`的文档中的表格）

  在版本3.3中更改：请参见上述above。

`winreg.``ExpandEnvironmentStrings`(str)

  在像`REG_EXPAND_SZ`的字符串中扩展环境变量占位符`%NAME%`：

      >>> ExpandEnvironmentStrings('%windir%')
      'C:\\Windows'

`winreg.``FlushKey`(key)

  将键的所有属性写入注册表。

  键是已打开的键，或者是预定义的HKEY_* constants之一。

  没有必要调用`FlushKey()`来更改键。注册表更改由注册表使用其惰性刷新器刷新到磁盘。注册表更改也在系统关闭时刷新到磁盘。与`CloseKey()`不同，`FlushKey()`方法仅在所有数据都已写入注册表时才返回。如果应用程序需要绝对确定注册表更改在磁盘上，则应调用`FlushKey()`。

  注意

  如果你不知道是否需要`FlushKey()`调用，它可能不是。

`winreg.``LoadKey`(key, sub_key, file_name)

  在指定的键下创建子键，并将来自指定文件的注册信息存储到该子键中。

  键是由`ConnectRegistry()`或常量`HKEY_USERS`或`HKEY_LOCAL_MACHINE`返回的句柄。

  sub_key是标识要加载的子项的字符串。

  file_name是要从中加载注册表数据的文件的名称。此文件必须使用`SaveKey()`函数创建。在文件分配表（FAT）文件系统下，文件名可能没有扩展名。

  如果调用进程不具有`SE_RESTORE_PRIVILEGE`权限，则对`LoadKey()`的调用失败。请注意，权限与权限不同 - 有关详细信息，请参阅RegLoadKey文档。

  如果键是由`ConnectRegistry()`返回的句柄，则file_name中指定的路径是相对于远程计算机的。

`winreg.``OpenKey`(key, sub_key, reserved=0, access=KEY_READ)
`winreg.``OpenKeyEx`(key, sub_key, reserved=0, access=KEY_READ)

  打开指定的键，返回handle object。

  key是已打开的键，或者是预定义的HKEY_* constants之一。

  sub_key是标识要打开的子键的字符串。

  reserved是保留的整数，必须为零。默认值为零。

  access是一个整数，指定描述密钥所需的安全访问的访问掩码。默认值为`KEY_READ`。有关其他允许的值，请参见Access Rights。

  结果是指定键的新句柄。

  如果函数失败，则会引发`OSError`。

  在版本3.2中更改：允许使用命名参数。

  在版本3.3中更改：请参见上述above。

`winreg.``QueryInfoKey`(key)

  返回有关键的信息，作为元组。

  键是已打开的键，或者是预定义的HKEY_* constants之一。

  结果是一个3个项目的元组：

  指数 | 含义
  --- | ---
  `0` | 一个整数，给出此键具有的子键数量。
  `1` | 一个整数，给出此键所具有的值的数量。
  `2` | 最近一次修改的时间的整数（如果可用），为自1601年1月1日以来的纳秒（单位为100纳秒)。

`winreg.``QueryValue`(key, sub_key)

  检索键的未命名值，作为字符串。

  键是已打开的键，或者是预定义的HKEY_* constants之一。

  sub_key是一个字符串，它保存与该值相关联的子项的名称。如果此参数`None`或为空，则函数将检索由`SetValue()`方法为由键标识的键设置的值。

  注册表中的值具有名称，类型和数据组件。此方法检索键的第一个值为NULL的数据。但底层API调用不返回类型，因此，如果可能，请始终使用`QueryValueEx()`。

`winreg.``QueryValueEx`(key, value_name)

  检索与打开的注册表项相关联的指定值名称的类型和数据。

  键是已打开的键，或者是预定义的HKEY_* constants之一。

  value_name是一个字符串，表示要查询的值。

  结果是一个2个项目的元组：

  指数 | 含义
  --- | ---
  `0` | 注册表项的值。
  `1` | 为此值提供注册表类型的整数（请参阅`SetValueEx()`的文档中的表）

`winreg.``SaveKey`(key, file_name)

  将指定的键及其所有子键保存到指定的文件。

  键是已打开的键，或者是预定义的HKEY_* constants之一。

  file_name是要将注册表数据保存到的文件的名称。此文件不能已存在。如果此文件名包含扩展名，则不能通过`LoadKey()`方法在文件分配表（FAT）文件系统上使用。

  如果键表示远程计算机上的键，则file_name描述的路径是相对于远程计算机的。此方法的调用者必须拥有`SeBackupPrivilege`安全权限。请注意，权限与权限不同 - 有关详情，请参阅用户权限和权限之间的冲突文档。

  此函数将security_attributes的NULL传递给API。

`winreg.``SetValue`(key, sub_key, type, value)

  将值与指定的键相关联。

  键是已打开的键，或者是预定义的HKEY_* constants之一。

  sub_key是一个字符串，用于命名与该值相关联的子项。

  type是一个指定数据类型的整数。目前，这必须是`REG_SZ`，这意味着只支持字符串。使用`SetValueEx()`函数支持其他数据类型。

  value是一个指定新值的字符串。

  如果sub_key参数指定的键不存在，则SetValue函数将创建它。

  值长度受可用内存的限制。长整型值（大于2048字节）应存储为文件名，该文件名存储在配置注册表中。这有助于注册表执行效率。

  由键参数标识的键必须已通过`KEY_SET_VALUE`访问打开。

`winreg.``SetValueEx`(key, value_name, reserved, type, value)

  将数据存储在打开的注册表项的值字段中。

  键是已打开的键，或者是预定义的HKEY_* constants之一。

  value_name是一个字符串，用于命名与该值相关联的子项。

  保留可以是任何 - 零始终传递到API。

  type是一个指定数据类型的整数。有关可用类型，请参见Value Types。

  value是一个指定新值的字符串。

  此方法还可以为指定的键设置附加值和类型信息。由键参数标识的键必须已通过`KEY_SET_VALUE`访问打开。

  要打开密钥，请使用`CreateKey()`或`OpenKey()`方法。

  值长度受可用内存的限制。长整型值（大于2048字节）应存储为文件名，该文件名存储在配置注册表中。这有助于注册表执行效率。

`winreg.``DisableReflectionKey`(key)

  对运行在64位操作系统上的32位进程禁用注册表反射。

  键是已打开的键，或者是预定义的HKEY_* constants之一。

  如果在32位操作系统上执行，通常将引发`NotImplemented`。

  如果键不在反射列表上，则函数将成功但不起作用。禁用键的反射不会影响任何子键的反映。

`winreg.``EnableReflectionKey`(key)

  恢复指定的禁用键的注册表反射。

  键是已打开的键，或者是预定义的HKEY_* constants之一。

  如果在32位操作系统上执行，通常将引发`NotImplemented`。

  恢复键的反射不会影响任何子键的反映。

`winreg.``QueryReflectionKey`(key)

  确定指定键的反射状态。

  键是已打开的键，或者是预定义的HKEY_* constants之一。

  如果禁用反射，则返回`True`。

  如果在32位操作系统上执行，通常将引发`NotImplemented`。

## 34.3.2. Constants

定义了许多`_winreg`函数中使用的常量。

### 34.3.2.1. HKEY_* Constants

`winreg.``HKEY_CLASSES_ROOT`

  从属于此键的注册表项定义文档的类型（或类）以及与这些类型相关联的属性。Shell和COM应用程序使用存储在此键下的信息。

`winreg.``HKEY_CURRENT_USER`

  从属于此键的注册表项定义当前用户的首选项。这些首选项包括环境变量的设置，有关程序组的数据，颜色，打印机，网络连接和应用程序首选项。

`winreg.``HKEY_LOCAL_MACHINE`

  此键下属的注册表项定义计算机的物理状态，包括有关总线类型，系统内存和已安装的硬件和软件的数据。

`winreg.``HKEY_USERS`

  从属于此键的注册表项定义本地计算机上新用户的默认用户配置和当前用户的用户配置。

`winreg.``HKEY_PERFORMANCE_DATA`

  此密钥下的注册表项允许您访问性能数据。数据实际上不是存储在注册表中；注册表函数使系统从其源收集数据。

`winreg.``HKEY_CURRENT_CONFIG`

  包含有关本地计算机系统的当前硬件配置文件的信息。

`winreg.``HKEY_DYN_DATA`

  此键在98之后的Windows版本中不使用。

### 34.3.2.2. Access Rights

有关详细信息，请参阅注册表项安全性和访问权限。

`winreg.``KEY_ALL_ACCESS`

  合并STANDARD_RIGHTS_REQUIRED，`KEY_QUERY_VALUE`，`KEY_SET_VALUE`，`KEY_CREATE_SUB_KEY`，`KEY_ENUMERATE_SUB_KEYS`，`KEY_NOTIFY` `KEY_CREATE_LINK`访问权限。

`winreg.``KEY_WRITE`

  合并STANDARD_RIGHTS_WRITE，`KEY_SET_VALUE`和`KEY_CREATE_SUB_KEY`访问权限。

`winreg.``KEY_READ`

  合并STANDARD_RIGHTS_READ，`KEY_QUERY_VALUE`，`KEY_ENUMERATE_SUB_KEYS`和`KEY_NOTIFY`值。

`winreg.``KEY_EXECUTE`

  等效于`KEY_READ`。

`winreg.``KEY_QUERY_VALUE`

  需要查询注册表项的值。

`winreg.``KEY_SET_VALUE`

  需要创建，删除或设置注册表值。

`winreg.``KEY_CREATE_SUB_KEY`

  需要创建注册表项的子项。

`winreg.``KEY_ENUMERATE_SUB_KEYS`

  必需枚举注册表项的子项。

`winreg.``KEY_NOTIFY`

  需要为注册表项请求更改通知，或者为注册表项的子项请求更改通知。

`winreg.``KEY_CREATE_LINK`

  保留供系统使用。

#### 34.3.2.2.1. 64位特定

有关详细信息，请参阅访问备用注册表视图。

`winreg.``KEY_WOW64_64KEY`

  表示64位Windows上的应用程序应在64位注册表视图上运行。

`winreg.``KEY_WOW64_32KEY`

  表示64位Windows上的应用程序应在32位注册表视图上运行。

### 34.3.2.3. Value Types

有关详细信息，请参阅注册表值类型。

`winreg.``REG_BINARY`

  任何形式的二进制数据。

`winreg.``REG_DWORD`

  32位数。

`winreg.``REG_DWORD_LITTLE_ENDIAN`

  小端格式的32位数字。

`winreg.``REG_DWORD_BIG_ENDIAN`

  以big-endian格式的32位数字。

`winreg.``REG_EXPAND_SZ`

  Null终止的字符串，包含对环境变量的引用（`%PATH%`）。

`winreg.``REG_LINK`

  Unicode符号链接。

`winreg.``REG_MULTI_SZ`

  以NULL结束的字符串序列，以两个空字符结束。（Python会自动处理此终止。）

`winreg.``REG_NONE`

  没有定义值类型。

`winreg.``REG_RESOURCE_LIST`

  设备驱动程序资源列表。

`winreg.``REG_FULL_RESOURCE_DESCRIPTOR`

  硬件设置。

`winreg.``REG_RESOURCE_REQUIREMENTS_LIST`

  硬件资源列表。

`winreg.``REG_SZ`

  以null结尾的字符串。

## 34.3.3. Registry Handle Objects

此对象包装一个Windows HKEY对象，当对象被销毁时自动关闭它。为了保证清除，可以调用对象上的`Close()`方法或`CloseKey()`函数。

此模块中的所有注册表函数都返回这些对象之一。

在这个模块中接受句柄对象的所有注册表函数也接受一个整数，但鼓励使用句柄对象。

句柄对象为`__bool__()`提供语义

    if handle:
        print("Yes")

将打印`Yes`如果句柄当前有效（尚未关闭或分离）。

该对象还支持比较语义，因此如果句柄对象都引用相同的底层Windows句柄值，则它们将比较true。

句柄对象可以转换为整数（例如，使用内建`int()`函数），在这种情况下返回基本的Windows句柄值。您还可以使用`Detach()`方法返回整数句柄，并且还从句柄对象中断开Windows句柄。

`PyHKEY.``Close`()

  关闭基础Windows句柄。

  如果句柄已经关闭，则不会产生错误。

`PyHKEY.``Detach`()

  从句柄对象分离Windows句柄。

  结果是一个整数，它在分离之前保存句柄的值。如果句柄已经被分离或关闭，这将返回零。

  调用此函数后，句柄有效无效，但句柄未关闭。当您需要底层的Win32句柄存在超过句柄对象的生命周期时，您将调用此函数。

`PyHKEY.``__enter__`()
`PyHKEY.``__exit__`(*exc_info)

  HKEY对象实现`__enter__()`和`__exit__()`，从而支持`with`语句的上下文协议：

      with OpenKey(HKEY_LOCAL_MACHINE, "foo") as key:
          ...  # work with key

  will automatically close key when control leaves the `with` block.