Seite 1 von 1

[windows] Dateiverküpfungen anzeigen/ändern (ohne win32api)

Verfasst: Donnerstag 1. Februar 2007, 10:43
von jens

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-


"""
Dateiverknüpfungen Anzeigen und setzten unter Windows.

Nutzt:
    reg.exe, assoc.exe

Hilfe zum Thema:
http://www.google.de/search?hl=de&as_qdr=all&q=%22Befehlszeilenreferenz+AZ%22+site%3Amicrosoft.com&btnG=Suche&meta=lr%3Dlang_de
http://www.microsoft.com/technet/prodtechnol/windowsserver2003/de/library/ServerHelp/552ed70a-208d-48c4-8da8-2e27b530eac7.mspx?mfr=true
"""

import os, sys, subprocess

#_____________________________________________________________________________

SIMULATION = False
#~ SIMULATION = True

DEBUG = False
#~ DEBUG = True

#_____________________________________________________________________________

def subprocess2(command, cwd=None):
    """
    Wenn process.stdout.read() blockiert, ist der subprocess noch nicht
    beendet. Evtl. wartet er auf eingaben?
    Hilfreich kann hierbei "print process.stdout.readline()" sein ;)
    """
    if DEBUG:
        print "-"*79
        print command
        print "-"*79
    if SIMULATION:
        print "(cmd simulation only)"
        return

    try:
        process = subprocess.Popen(
            command,
            bufsize = 1,
            cwd     = cwd,
            shell   = True,
            stdout  = subprocess.PIPE,
            stderr  = subprocess.STDOUT
        )
    except Exception, e:
        print "subprocess Error:", e
        sys.exit()

    #~ print process.stdout.readline()

    # Ausgaben
    output = process.stdout.read()
    return output.strip()

#_____________________________________________________________________________

def reg_add(key, value, reg_type="REG_SZ"):
    cmd = 'reg add "%s" /f /ve /t %s /d "%s"' % (key, reg_type, value)
    subprocess2(cmd)

def reg_delete(key):
    cmd = 'reg delete "%s" /f' % key
    subprocess2(cmd)

def reg_query(key, subtree=False):
    cmd = 'reg query "%s"' % key
    if subtree:
        cmd += " /s"
    result = subprocess2(cmd)
    result = result.split(os.linesep)
    result = os.linesep.join(result[2:])
    return result

#_____________________________________________________________________________

def set_filetype(ext, filetype):
    key = "HKCR\%s" % ext
    reg_add(key, filetype)

def set_filetype_command(filetype, shelltype, command):
    key = "HKCR\%s\shell\%s\command" % (filetype, shelltype)
    reg_add(key, command)

def file_assoc(ext, filetype, shelltype, command):
    """
    Verknüpft eine Endung mit einem Dateitypen und setzt dabei
    eine shell-type mit command.
    Beispiele:
    file_assoc(".py", "Python.File", "open", 'c:\python\python.exe "%1" %*')
    """
    assert ext.startswith(".")
    assert shelltype in ("open", "edit")

    filetype = filetype.replace(" ", "_") # Darf keine Leerzeichen haben (?)

    set_filetype(ext, filetype)
    set_filetype_command(filetype, shelltype, command)
    print

#_____________________________________________________________________________

def del_file_assoc(ext):
    """
    Löscht eine Dateiendung
    """
    assert ext.startswith(".")
    key = "HKCR\%s" % ext
    reg_delete(key)

def del_filetype(filetype):
    """
    Löscht einen Dateitypen Eintrag *komplett*
    """
    key = "HKCR\%s" % filetype
    reg_delete(key)

#_____________________________________________________________________________

def get_filetype(ext):
    """
    Liefert den Dateityp anhand der Endung zurück
    """
    cmd = 'assoc %s' % ext
    result = subprocess2(cmd)
    try:
        return result.split("=")[1]
    except IndexError, e:
        print "Error:", e
        print result

def display_shell_commands(filetype):
    """
    Listet vorhandene shell-Kommandos zu einem Dateityp auf.
    """
    key = "HKCR\%s\shell" % filetype
    result = reg_query(key, subtree=True)
    result = result.split(os.linesep+os.linesep)
    for line in result:
        if not "command" in line:
            continue

        print line
        print

def file_info(ext):
    """
    Zeigt Informationen zu einer Dateiendung.
    """
    print "\n-----[Fileinfo for '%s']-----" % ext
    assert ext.startswith(".")

    filetype = get_filetype(ext)
    print "'%s' files are associated with filetype '%s'" % (ext, filetype)
    print

    display_shell_commands(filetype)
    print "-"*79

#_____________________________________________________________________________


if __name__ == "__main__":
    print "Neue Endung einfügen."
    file_assoc(".000", "AAA test", "open", "python %1")

    file_info(".000")

    print "\nDaten wieder löschen."
    del_file_assoc(".000")
    del_filetype("AAA test")

    file_info(".000")

    file_info(".py")

Verfasst: Donnerstag 1. Februar 2007, 11:52
von jens
Hier mal eine Variante die _winreg benutzt. Da _winreg aber echt übel ist, habe ich keine Lust alle Features zu implementieren.

Man kann nur eine neue Verknüpfung erstellen.
Anzeigen kann man sich nur den Dateityp der an einer Endung gebunden ist, mehr nicht.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-

"""
Dateiverknüpfungen setzten unter Windows mit _winreg
"""

import os, sys

import _winreg as winreg

#_____________________________________________________________________________

SIMULATION = False
#~ SIMULATION = True

#~ DEBUG = False
DEBUG = True

#_____________________________________________________________________________

def reg_add(sub_key, value, key=winreg.HKEY_CLASSES_ROOT,
                                                    reg_type=winreg.REG_SZ):
    reg_key = winreg.CreateKey(key, sub_key)
    winreg.SetValueEx(reg_key, None, None, reg_type, value)
    winreg.CloseKey(reg_key)

def reg_query(sub_key, key=winreg.HKEY_CLASSES_ROOT):
    if DEBUG:
        print "query key '%s'" % sub_key

    reg_key = winreg.OpenKey(key, sub_key)
    result = winreg.EnumValue(reg_key, 0)
    return result[1]

#_____________________________________________________________________________

def set_filetype(ext, filetype):
    if DEBUG:
        print "associated '%s' with '%s'." % (ext, filetype)

    reg_add(ext, filetype)

def set_filetype_command(filetype, shelltype, command):
    if DEBUG:
        print "set for '%s' the '%s'-shell-command to: '%s'" % (
            filetype, shelltype, command
        )

    sub_key = "%s\shell\%s\command" % (filetype, shelltype)
    reg_add(sub_key, command)

def file_assoc(ext, filetype, shelltype, command):
    """
    Verknüpft eine Endung mit einem Dateitypen und setzt dabei
    eine shell-type mit command.
    Beispiele:
    file_assoc(".py", "Python.File", "open", 'c:\python\python.exe "%1" %*')
    """
    assert ext.startswith(".")
    assert shelltype in ("open", "edit")

    filetype = filetype.replace(" ", "_") # Darf keine Leerzeichen haben (?)

    set_filetype(ext, filetype)
    set_filetype_command(filetype, shelltype, command)
    print

#_____________________________________________________________________________

def file_info(ext):
    """
    Zeigt Informationen zu einer Dateiendung.
    """
    print "\n-----[Fileinfo for '%s']-----" % ext
    assert ext.startswith(".")

    filetype = reg_query(ext)
    print "'%s' files are associated with filetype '%s'" % (ext, filetype)
    print

#_____________________________________________________________________________


if __name__ == "__main__":
    #~ print "Neue Endung einfügen."
    file_assoc(".000", "AAA test", "open", "python %1")

    file_info(".000")

Verfasst: Donnerstag 1. Februar 2007, 17:05
von lunar
Wie wäre es, wenn du die "Windows Scipting Library" benutzt? Die bietet über das Objekt "WScript.Shell" komfortablen Zugriff auf die Registrierung und ist zudem bei jedem Windows-System installiert, da sie zum Standardsystem gehört.

Die Nutzung ist einigermaßen einfach:

Code: Alles auswählen

import win32.com
shell = win32com.client.Dispatch('WScript.Shell')
# Suchassitent deaktivieren!
keypath = r'HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\CabinetState\Use Search Asst'
shell.RegWrite(keypath, "no", "REG_SZ");
lunar

Verfasst: Donnerstag 1. Februar 2007, 17:20
von jens
Also eigentlich brauche ich das für wine. Um da Verknüpfungen zu erstellen. Ich weiß nicht ob da Windows-Scripting vorhanden ist, ich tippe auf "nein" ;)

Verfasst: Donnerstag 1. Februar 2007, 17:26
von sape
Jens, nettes Script :) *Added-in-my-Lib*

lg

Verfasst: Donnerstag 1. Februar 2007, 19:17
von lunar
jens hat geschrieben:Also eigentlich brauche ich das für wine. Um da Verknüpfungen zu erstellen. Ich weiß nicht ob da Windows-Scripting vorhanden ist, ich tippe auf "nein" ;)
Uii, was machst du denn alles mit Wine, dass du extra Python darin installierst und dazu auch noch dieses Script entwickelst?

Verfasst: Donnerstag 1. Februar 2007, 19:37
von jens

Verfasst: Dienstag 6. März 2007, 11:17
von jens
jens hat geschrieben:Hier mal eine Variante die _winreg benutzt. Da _winreg aber echt übel ist, habe ich keine Lust alle Features zu implementieren.
Hab gerade dazu ein Cookbook Eintrag gesehen: http://aspn.activestate.com/ASPN/Cookbo ... ipe/502268
Damit geht vielleicht einiges einfacher...