import _winreg
import re
import os
import subprocess

def gen(f,key):
    index = 0
    while True:
        try:
            yield f(key, index)
        except EnvironmentError:
            break
        index += 1
        
def subkeys(key):
    return [name for name in gen(_winreg.EnumKey,key)]
def values(key):
    return [name for name in gen(_winreg.EnumValue,key)]

def isWin64():
    return 'PROGRAMFILES(X86)' in os.environ

class UninstallKey:
    mainkey = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
    @classmethod
    def fetchUninstallablePrograms(cls,pattern):
        pattern = re.compile(pattern)
        def check_uninstallable(key,value):
            try:
                _winreg.QueryValueEx(key,value)
                return True
            except:
                return False
        result = []
        access_types = [_winreg.KEY_READ|view for view in (_winreg.KEY_WOW64_64KEY,_winreg.KEY_WOW64_32KEY)] if isWin64() else (_winreg.KEY_READ,)
        for access_type in access_types:
            try:
                mainkey = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,cls.mainkey,0,access_type)
                items = subkeys(mainkey)
                result.extend([cls(_winreg.OpenKey(mainkey,name),name) for name in items if pattern.search(name) and check_uninstallable(_winreg.OpenKey(mainkey,name),'UninstallString')])
            except:
                pass
        result.sort(key=lambda x: x.name)
        return result
    def __init__(self,key,keyname):
        self.keyname = keyname
        try:
            self.name, valuetype = _winreg.QueryValueEx(key, "DisplayName")
            self.name = str(self.name).strip()
            if not self.name: self.name = keyname
            #print self.name, valuetype
        except:
            self.name = self.keyname
        self.command, valuetype = _winreg.QueryValueEx(key, "UninstallString")
    def __cmp__(self, other):
        result = cmp(self.name,other.name)
        if result: return result
        return cmp(self.command,other.command)
            
if __name__=='__main__':
    keys = UninstallKey.fetchUninstallablePrograms('.')
    #print _winreg.REG_SZ
    for key in keys:
        print key.name
    #subprocess.call(keys[0].command)
