В основном это фон, пропустите следующие 3 абзаца для вопроса:
Я разработал инструмент, который вызывает некоторые установщики, изменяет элементы реестра и перемещает файлы, чтобы помочь мне протестировать продукт, который имеетдовольно быстрый цикл обновления.Пока все хорошо, у меня есть графический интерфейс, который выполняется в отдельном процессе и бизнес-логике, чтобы предотвратить его блокировку из-за GIL, все работает и т. Д., Но у меня есть проблемы с частью моего кода, где я делаю вызовы msiexec.
В частности, это часть удаления, которая вызывает у меня беспокойство.В настоящее время GUID не изменяется, поэтому я могу удалить продукт с помощью os.system('msiexec /x "{GUID}" /passive')
.На самом деле все немного сложнее, так как я использую subprocess.Popen и опрашиваю его до тех пор, пока он не завершится из цикла событий, чтобы обеспечить параллелизм с другими шагами.
Меня беспокоит, что в случае изменения GUID, очевидно, это не будет работать.Я не хочу указывать msiexec непосредственно на источник установки, так как это означало бы, что это не сработало бы, если бы я «потерял» файл msi, который я храню во временном каталоге.
То, что я ищу, - это способ запроса по имени программы, чтобы получить GUID, или даже обертка для msiexec, которая сделала бы все это, включая удаление, для меня.Я думал о сканировании через реестр, но модуль _winreg кажется очень медленным, поэтому я предпочел бы избежать этого, если это вообще возможно.Если есть лучший способ сканирования реестра, я на все уши, так как это ускорит и другие части инструмента.
Update0
Производительность на этом критически важна, так какодна из целей разработки - сделать процесс, которому инструмент следует, быстрее любого другого метода, ручного или иного, чтобы добиться массового внедрения.
Update1
Я пробовалнебольшое изменение версии реестра ниже, однако оно последовательно возвращает None
.Я не совсем уверен, как это происходит - кажется, что он не может открыть соответствующий ключ, поскольку я вставил точку останова после оператора with
, который никогда не достигается ...
def get_guid_by_name(name):
from _winreg import (OpenKey,
QueryInfoKey,
EnumKey,
QueryValueEx,
HKEY_LOCAL_MACHINE,
)
with OpenKey(HKEY_LOCAL_MACHINE,
r'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall') as key:
subkeys, _0, _1 = QueryInfoKey(key) # The breakpoint here is never reached
del _0, _1
for i in range(subkeys):
subkey = EnumKey(key, i)
if subkey[0] != '{' or subkey[-1] != '}':
continue
with OpenKey(key, subkey) as _subkey:
if name in QueryValueEx(_subkey, 'DisplayName')[0]:
return subkey
return None
print get_guid_by_name('Microsoft Visual Studio')
Обновление2
Ударьте это - я дурак, который недостаточно тщательно проверяет свои отступы - print get_guid_by_name('Microsoft Visual Studio')
был в пределах get_guid_by_name
...