Python winreg обновляет ЧТО-ТО, но не реестр Windows

Я использую Winreg для чтения, записи и изменения реестра Windows. Моя программа меняет множество различных настроек, чтобы исправить вещи, которые меня раздражают в настройках Windows по умолчанию. Когда я запускаю его, кажется, что он работает. Изменения сохраняются даже между запусками Flask, даже после перезапуска Проводника Windows и компьютера.

Но каждый раз, когда я проверяю реестр, изменений нет. Я уже проверил, что все 64битное. Я запускаю VScode от имени администратора (и запускаю там flask через терминал). На всякий случай я запустил его и в терминале администратора вне vscode.

Что бы я ни пытался, он сообщает мне, что меняет реестр, хотя на самом деле это не так. Меня это совершенно сбивает с толку. Я попытался снова открыть проводник Windows, закрыть и снова открыть реестр и перезапустить систему. Ничто не имело значения.

Что касается настроек, в которых я создал значение и установил для него атрибут «данные», оно сохраняется между сеансами, и я могу проверить его в своем коде, как если бы оно хранилось ГДЕ-ТО.

Это код:

ПРИМЕЧАНИЕ. Если вас вообще беспокоят изменения в реестре, указанные ниже, создайте резервную копию реестра, прежде чем запускать это.

import winreg

def hive_name(hive):
    if hive == winreg.HKEY_CURRENT_USER:
        return "HKEY_CURRENT_USER"
    elif hive == winreg.HKEY_LOCAL_MACHINE:
        return "HKEY_LOCAL_MACHINE"
    elif hive == winreg.HKEY_CLASSES_ROOT:
        return "HKEY_CLASSES_ROOT"
    elif hive == winreg.HKEY_USERS:
        return "HKEY_USERS"
    elif hive == winreg.HKEY_PERFORMANCE_DATA:
        return "HKEY_PERFORMANCE_DATA"
    elif hive == winreg.HKEY_CURRENT_CONFIG:
        return "HKEY_CURRENT_CONFIG"
    else:
        return "UNKNOWN_HIVE"

def open_or_create_key(hive, path):
    try:
        # Open the registry key for reading and writing in 64-bit view
        key = winreg.OpenKey(hive, path, 0, winreg.KEY_READ | winreg.KEY_WRITE | winreg.KEY_WOW64_64KEY)
        print(f"Key opened: {hive_name(hive)}\\{path}")
    except FileNotFoundError:
        # Handle if the key doesn't exist
        print(f"Creating key: {hive_name(hive)}\\{path}")
        key = winreg.CreateKeyEx(hive, path, 0, winreg.KEY_READ | winreg.KEY_WRITE | winreg.KEY_WOW64_64KEY)
    except PermissionError:
        # Handle if there are permission issues
        print(f"Permission denied while accessing the key: {hive_name(hive)}\\{path}")
        key = None
    except Exception as e:
        # Handle any other exceptions
        print(f"An error occurred: {e}")
        key = None
    return key

def get_value(key,which):
    try:
        value, _ = winreg.QueryValueEx(key, which)
        print(f"Current value: {value}")
    except FileNotFoundError:
        print("Current value: <not set>")
    except Exception as e:
        print(f"An error occurred while querying the value: {e}")

def set_value(key,which,what):
    try:
        winreg.SetValueEx(key, which, 0, winreg.REG_DWORD, what)
        print (which, "was set to", what)
    except FileNotFoundError:
        print (which, "could not be set to", what)

def close_key(key):
    if key:
        winreg.CloseKey(key)
        print("Key closed.")

# Test the open_or_create_key function
if __name__ == "__main__":

    print("# This key does exist on my system and has tons of values")
    print("# Expected Output: Key opened: HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced")
    key = open_or_create_key(winreg.HKEY_CURRENT_USER, r"Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced")
    print("# Value name DisallowShaking is NOT in my registry.")
    print("# Expected Output: Current value: <not set> ")
    # Prevents the windows "feature" of minimizing everything if you "shake" a window while dragging. Does nothing if the value isn't actually set.
    get_value(key,"DisallowShaking")
    print("# Value name HideFileExt IS in my registry.")
    print("# Expected Output: HideFileExt set to X (where X is the value set in the code) - needs to be checked in the registry to see if it changed between runs")
    # enables or disables hiding of file extensions. 0 to not hide it.
    set_value(key,"HideFileExt",1)
    close_key(key)

    # This restores the Windows 10 right-click context menu to your system in Windows 11 if the key is present. It has no effect when left
    print("# Neither {86ca1aa0-34aa-4e8b-a509-50c905bae2a2} nor InprocServer32 exist in my registry.")
    print("# Expected Output: Creating Key: Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32")
    key = open_or_create_key(winreg.HKEY_CURRENT_USER, r"Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32")
    close_key(key)

    # Setting this key and vlue restores the Windows 10 Windows Explorer ribbon. 
    print("# The Blocked key does not exist in my registry.")
    print("# Expected Output: Creating Key: SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked")
    key = open_or_create_key(winreg.HKEY_CURRENT_USER, r"SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked")
    print("# If the key were created, then I can test for value {e2bf9676-5f8f-435c-97eb-11607a5bedf7} which should not exist yet.")
    print("# Expected Output: An error occurred while querying the value:  ")
    get_value(key,"{e2bf9676-5f8f-435c-97eb-11607a5bedf7}")
    set_value(key,"{e2bf9676-5f8f-435c-97eb-11607a5bedf7}", 1)
    close_key(key)

Когда я запускаю вышеуказанное (в терминале VsCode с VsCode, запущенным от имени администратора), я получаю следующий вывод:

# This key does exist on my system and has tons of values
# Expected Output: Key opened: HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced
Key opened: HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced
# Value name DisallowShaking is NOT in my registry.
# Expected Output: Current value: <not set>
Current value: 1
# Value name HideFileExt IS in my registry.
# Expected Output: HideFileExt set to X (where X is the value set in the code) - needs to be checked in the registry to see if it changed between runs
HideFileExt was set to 1
Key closed.
# Neither {86ca1aa0-34aa-4e8b-a509-50c905bae2a2} nor InprocServer32 exist in my registry.
# Expected Output: Creating Key: Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32
Key opened: HKEY_CURRENT_USER\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32
Key closed.
# The Blocked key does not exist in my registry.
# Expected Output: Creating Key: SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked
Key opened: HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked
# If the key were created, then I can test for value {e2bf9676-5f8f-435c-97eb-11607a5bedf7} which should not exist yet.
# Expected Output: An error occurred while querying the value:
Current value: <not set>
Key closed.

Несмотря на это, состояние моего реестра после выполнения вышеописанного выглядит следующим образом:

  • DisallowShaking НЕ был создан

  • HideFileExt НЕ был установлен в 1

  • ключ Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32 НЕ создан

  • ключ SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked НЕ создан

  • значения {e2bf9676-5f8f-435c-97eb-11607a5bedf7} явно не существует, но выводит, как если бы оно было.

И каким-то образом государство сохраняется. Я добавил «set_value» к последнему значению ({e2bf9676-5f8f-435c-97eb-11607a5bedf7}) при последующем запуске, и установленное мной значение сохранялось между запусками программы. И ключ, и значение до сих пор не существуют в моем реестре.

Распространенными ответами являются проблемы с 64-разрядными версиями и 32-разрядными версиями, которые не используются (система, Python и Regedit являются 64-разрядными). Я проверил «VirtualStore» — я проверил ВЕСЬ реестр на наличие текста, содержащего одно из установленных мной значений, но его там нет (за исключением случаев, когда я запускаю код... тогда он думает, что это так).

На чем вы основываете предположение, что ключа нет? Кроме того, это предположение неверно после однократного запуска сценария.

CristiFati 22.06.2024 02:35

Проверяем ключ с помощью Regedit. На всякий случай я проверил это с помощью PowerShell. И не имеет значения, сколько раз я запускаю сценарий, потому что он определяет наличие ключа, хотя его нет, и никогда не достигает строки «создать».

not_a_generic_user 22.06.2024 04:29

Windows и Python оба 64-битные? Вы пробовали это с другими ключами реестра, из того же куста и из другого?

Michael Butscher 22.06.2024 09:03

Если Python по умолчанию не загружает 32-битную версию, да. Все 64 битное. Что касается других ключей, я работаю над инструментом с набором из более чем 30 различных ключей реестра, которые я меняю по одному. Каким-то образом состояние сохраняется, когда я переключаю изменения между загрузками программы, поэтому данные переключаются ГДЕ-ТО.

not_a_generic_user 22.06.2024 15:26

Я нашел тестовую строку, чтобы проверить, является ли она 64-битной, и так оно и есть.

not_a_generic_user 22.06.2024 15:29

Сама Windows выполняет множество перенаправлений реестра, что затрудняет проверку того, где что-то происходит на самом деле. Используйте уникальное значение, которое можно найти.

Mark Ransom 22.06.2024 16:27

Некоторые ключи и значения не существуют в реестре, поэтому их следует создать. После запуска кода я проверил реестр из корня в поисках значений, но их там не было. @МаркРансом

not_a_generic_user 22.06.2024 20:01

Запустите procmon, чтобы посмотреть, что происходит.

Luke 24.06.2024 08:06

Вы пытались нажать F5 в regedit, чтобы обновить содержимое? Он не вносит активные изменения, сделанные за пределами средства просмотра.

James 24.06.2024 16:39

@Джеймс, согласно моему сообщению: «Я пробовал снова открыть Проводник Windows, закрыть и снова открыть реестр, а также перезапустить систему. Ничего не изменилось». Я также пробовал сначала нажать f5, прежде чем все это сделать.

not_a_generic_user 25.06.2024 00:23

@Люк, как мне использовать procmon, чтобы что-нибудь обнаружить в этом случае?

not_a_generic_user 25.06.2024 00:24

Он скажет вам, действительно ли вы читаете/пишите то, что, по вашему мнению, читаете/пишите.

Luke 25.06.2024 07:55

У каждого пользователя есть свой HKCU, так что, может быть, вам стоит попробовать это? superuser.com/questions/46399/…

x6dec3fb8 25.06.2024 08:57

@ x6dec3fb8, я обыскал весь реестр в поисках некоторых ключей и значений, но их там нет.

not_a_generic_user 26.06.2024 06:24

Возможно, vscode делает что-то странное. Вместо этого попробуйте запустить скрипт из командной строки. Я не пробовал использовать vscode, так как не использую его, но у меня код отлично работает из командной строки (Windows 10).

Luke 26.06.2024 15:35

@Люк, я попробовал запустить его с терминала, но это не имело никакого значения.

not_a_generic_user 27.06.2024 00:29

Что ж, я думаю, ваш единственный вариант — запустить procmon и посмотреть, откуда считываются и куда записываются данные реестра.

Luke 27.06.2024 08:19

вы пытались переустановить Python? это может быть ошибка в Winreg, какую версию вы используете?

GTK 27.06.2024 21:21

@GTK использует 3.10.11. Когда я проверил свою систему, я заметил, что у меня тоже есть версия 3.11.5150, и там явно указано (64 бит). Ранее я использовал команду, чтобы убедиться, что она 64-битная, но я все равно обновился до 3.12 и тоже проверил ее (согласно этим инструкциям): stackoverflow.com/questions/1405913/…. Я пересобрал свой venv, установил flask, и теперь он работает! Ты нашел это! Если вы скажете это как ответ, я приму это. За этот вопрос назначена награда, которая принадлежит вам.

not_a_generic_user 28.06.2024 00:15

Думаю, старая добрая переустановка снова спасла положение, я опубликую ее в качестве ответа!

GTK 28.06.2024 00:36

Я думаю, вам нужно переустановить Python.

Karol 30.06.2024 14:22
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
21
198
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Согласно моему комментарию, я предполагаю, что, скорее всего, это была проблема со старой версией python/winreg, поскольку перезапуск/переустановка всегда решает подобные загадочные проблемы.

Хотя между версиями 3.10 и 3.12 были изменения в том, как Winreg управляет дескрипторами ключей реестра, это не должно иметь к этому никакого отношения.

Мне так и не удалось воспроизвести проблему с Python 3.10.11 или 3.12.11, возможно, это просто ошибочная/поврежденная установка Python?

Если быть точным, согласно комментарию выше, я удалил Python 3.10, установил 3.12 и пересобрал свою установку venv и flask, используя: python -m venv venv pip install flask

not_a_generic_user 28.06.2024 01:30

просто чтобы уточнить, версия, на которой вы запускали код, была 3.10, а не 3.11? а ты пробовал и с global/venv, и ни с тем, ни с другим не помогло? поскольку никто не смог воспроизвести проблему, очень сложно точно определить, что происходит.

GTK 28.06.2024 01:38

Я пробовал только с 3.10. Я собирался обновиться до 3.11, но заметил, что версии 3.12 уже нет. Итак, я установил 3.12, пересобрал venv и колбу, и все заработало.

not_a_generic_user 28.06.2024 01:41

Я сомневаюсь, что flask/venv имеет к этому какое-то отношение, кроме того, я установил именно ту версию, которую вы использовали, но все равно не смог воспроизвести проблему.

GTK 28.06.2024 02:48

Не имею представления. Но переустановка помогла.

not_a_generic_user 28.06.2024 02:56

Да, я последовал твоему шагу. все работает хорошо.

Karol 30.06.2024 14:23

Другие вопросы по теме