Я использую 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» — я проверил ВЕСЬ реестр на наличие текста, содержащего одно из установленных мной значений, но его там нет (за исключением случаев, когда я запускаю код... тогда он думает, что это так).
Проверяем ключ с помощью Regedit. На всякий случай я проверил это с помощью PowerShell. И не имеет значения, сколько раз я запускаю сценарий, потому что он определяет наличие ключа, хотя его нет, и никогда не достигает строки «создать».
Windows и Python оба 64-битные? Вы пробовали это с другими ключами реестра, из того же куста и из другого?
Если Python по умолчанию не загружает 32-битную версию, да. Все 64 битное. Что касается других ключей, я работаю над инструментом с набором из более чем 30 различных ключей реестра, которые я меняю по одному. Каким-то образом состояние сохраняется, когда я переключаю изменения между загрузками программы, поэтому данные переключаются ГДЕ-ТО.
Я нашел тестовую строку, чтобы проверить, является ли она 64-битной, и так оно и есть.
Сама Windows выполняет множество перенаправлений реестра, что затрудняет проверку того, где что-то происходит на самом деле. Используйте уникальное значение, которое можно найти.
Некоторые ключи и значения не существуют в реестре, поэтому их следует создать. После запуска кода я проверил реестр из корня в поисках значений, но их там не было. @МаркРансом
Запустите procmon, чтобы посмотреть, что происходит.
Вы пытались нажать F5 в regedit, чтобы обновить содержимое? Он не вносит активные изменения, сделанные за пределами средства просмотра.
@Джеймс, согласно моему сообщению: «Я пробовал снова открыть Проводник Windows, закрыть и снова открыть реестр, а также перезапустить систему. Ничего не изменилось». Я также пробовал сначала нажать f5, прежде чем все это сделать.
@Люк, как мне использовать procmon, чтобы что-нибудь обнаружить в этом случае?
Он скажет вам, действительно ли вы читаете/пишите то, что, по вашему мнению, читаете/пишите.
У каждого пользователя есть свой HKCU, так что, может быть, вам стоит попробовать это? superuser.com/questions/46399/…
@ x6dec3fb8, я обыскал весь реестр в поисках некоторых ключей и значений, но их там нет.
Возможно, vscode делает что-то странное. Вместо этого попробуйте запустить скрипт из командной строки. Я не пробовал использовать vscode, так как не использую его, но у меня код отлично работает из командной строки (Windows 10).
@Люк, я попробовал запустить его с терминала, но это не имело никакого значения.
Что ж, я думаю, ваш единственный вариант — запустить procmon и посмотреть, откуда считываются и куда записываются данные реестра.
вы пытались переустановить Python? это может быть ошибка в Winreg, какую версию вы используете?
@GTK использует 3.10.11. Когда я проверил свою систему, я заметил, что у меня тоже есть версия 3.11.5150, и там явно указано (64 бит). Ранее я использовал команду, чтобы убедиться, что она 64-битная, но я все равно обновился до 3.12 и тоже проверил ее (согласно этим инструкциям): stackoverflow.com/questions/1405913/…. Я пересобрал свой venv, установил flask, и теперь он работает! Ты нашел это! Если вы скажете это как ответ, я приму это. За этот вопрос назначена награда, которая принадлежит вам.
Думаю, старая добрая переустановка снова спасла положение, я опубликую ее в качестве ответа!
Я думаю, вам нужно переустановить Python.
Согласно моему комментарию, я предполагаю, что, скорее всего, это была проблема со старой версией 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
просто чтобы уточнить, версия, на которой вы запускали код, была 3.10, а не 3.11? а ты пробовал и с global/venv, и ни с тем, ни с другим не помогло? поскольку никто не смог воспроизвести проблему, очень сложно точно определить, что происходит.
Я пробовал только с 3.10. Я собирался обновиться до 3.11, но заметил, что версии 3.12 уже нет. Итак, я установил 3.12, пересобрал venv и колбу, и все заработало.
Я сомневаюсь, что flask/venv имеет к этому какое-то отношение, кроме того, я установил именно ту версию, которую вы использовали, но все равно не смог воспроизвести проблему.
Не имею представления. Но переустановка помогла.
Да, я последовал твоему шагу. все работает хорошо.
На чем вы основываете предположение, что ключа нет? Кроме того, это предположение неверно после однократного запуска сценария.