Search code examples
pythonwinreg

creating a "@" entry with python using winreg


I'm trying to convert the following registry tweak to python using winreg:

REGEDIT4
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\IniFileMapping\Autorun.inf]
@="@SYS:Does_Not_Exist"

The pain is in the '@' which I can't seem to replicate. Looking at examples in C# they use e.g. the empty string '' to enter @. If I manually import the above and use EnumValue() of winreg this entry also shows up as ''. But I can't seem to do something similar in python winreg and I found no workaround so far.

Code showing the problem:

from winreg import *
import os
import platform

import sys, time
import win32api as wa, win32con as wc, win32service as ws

def registrySetKey(hive, regpath, key, type, value):
    try:
        reg = OpenKey(hive, regpath, 0, KEY_ALL_ACCESS)
    except EnvironmentError:
        try:
            reg = CreateKey(hive, regpath, 0, KEY_ALL_ACCESS)
            SetValueEx(reg, key, None, type, value)
            CloseKey(reg)
        except:
            print("*** Unable to register path %s, key %s!" % (regpath, key))
            return
        print("--- Python", version, "is now registered!")
        return
    try:
        if (QueryValue(reg, key) == value):
            return
    except:
        SetValueEx(reg, key, None, type, value)
    CloseKey(reg)


reg = CreateKey(HKEY_LOCAL_MACHINE, r'Software\Microsoft\Windows NT\CurrentVersion\IniFileMapping\Autorun.inf')

# This does not work
registrySetKey(HKEY_LOCAL_MACHINE, 
               r'Software\Microsoft\Windows NT\CurrentVersion\IniFileMapping\Autorun.inf', 
               '', REG_SZ, '@SYS:Does_Not_Exist')

After the manual import the name of the entry is (Default), using that also doesn't work.

Regards, Sven


Solution

  • The function you are using would work with your call, but you need to add the following for when the value does not currently match, i.e. it is not currently actually setting anything:

    else:
        SetValueEx(reg, key, None, type, value)
    

    So the full function would be as follows:

    from winreg import *
    import os
    import platform
    
    import sys, time
    import win32api as wa, win32con as wc, win32service as ws
    
    def registrySetKey(hive, regpath, key, type, value):
        try:
            reg = OpenKey(hive, regpath, 0, KEY_ALL_ACCESS)
        except EnvironmentError:
            try:
                reg = CreateKey(hive, regpath, 0, KEY_ALL_ACCESS)
                SetValueEx(reg, key, None, type, value)
                CloseKey(reg)
            except:
                print("*** Unable to register path %s, key %s!" % (regpath, key))
                return
            print("--- Python", version, "is now registered!")
            return
        try:
            if (QueryValue(reg, key) == value):
                return
            else:
                SetValueEx(reg, key, None, type, value)     # added
        except:
            SetValueEx(reg, key, None, type, value)
        CloseKey(reg)
    
    
    reg = CreateKey(HKEY_LOCAL_MACHINE, r'Software\Microsoft\Windows NT\CurrentVersion\IniFileMapping\Autorun.inf')
    
    registrySetKey(HKEY_LOCAL_MACHINE, 
                   r'Software\Microsoft\Windows NT\CurrentVersion\IniFileMapping\Autorun.inf', 
                   '', REG_SZ, '@SYS:Does_Not_Exist') 
    

    Depending on your version of Windows it will probably have modified the following key as a result of doing this:

    HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\IniFileMapping\Autorun.inf