|
# -*- coding: utf-8 -*- |
|
|
|
# Erstellt einen Eintrag im Context-Menü des Explorers: CCD-Verzeichnis erstellen |
|
# bei Click wird im gewählten Verzeichnis eine CCD-Verzeichnisstrukur |
|
# (bin, build, lib, source, resources) erstellt. |
|
|
|
import os.path |
|
import pythoncom |
|
from win32com.shell import shell, shellcon |
|
import win32gui |
|
import win32con |
|
|
|
IContextMenu_Methods = ["QueryContextMenu", "InvokeCommand", "GetCommandString"] |
|
IShellExtInit_Methods = ["Initialize"] |
|
|
|
# HKCR Key Affected object types |
|
# * All files |
|
#AllFileSystemObjects All regular files and file folders |
|
# Folder All folders, virtual and filesystem |
|
# Directory File folders |
|
#Directory\Background Directory-Background (Folder is open, one clicks on the white background...) |
|
# Drive Root folders of all system drives |
|
# Network Entire network |
|
# NetShare All network shares |
|
|
|
TYPES = [ |
|
'Directory\\Background', |
|
'Directory', |
|
] |
|
SUBKEY = 'CCD-Verzeichnis' |
|
|
|
CCDFOLDERS = [ |
|
'source', |
|
'bin', |
|
'build', |
|
'lib', |
|
'resource', |
|
] |
|
|
|
def alertError(hwnd, exc): |
|
win32gui.MessageBox(hwnd, str(exc), str(exc.__class__), win32con.MB_OK) |
|
|
|
|
|
class ShellExtension: |
|
_reg_progid_ = "CCD.Verzeichnisersteller.ShellExtension.ContextMenu" |
|
_reg_desc_ = "CCD-Verzeichnis Shell Extension (context menu)" |
|
_reg_clsid_ = "{5C664DC4-5ADA-4385-9DEB-EDB51320A668}" |
|
|
|
_com_interfaces_ = [shell.IID_IShellExtInit, shell.IID_IContextMenu] |
|
_public_methods_ = IContextMenu_Methods + IShellExtInit_Methods |
|
|
|
def Initialize(self, folder, dataobj, hkey): |
|
self.dataobj = dataobj |
|
|
|
def QueryContextMenu(self, hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags): |
|
try: |
|
msg = 'CCD-Verzeichnis ersellen' |
|
|
|
idCmd = idCmdFirst |
|
items = [] |
|
if (uFlags & 0x000F) == shellcon.CMF_NORMAL: |
|
items.append(msg) |
|
elif uFlags & shellcon.CMF_VERBSONLY: |
|
items.append(msg) |
|
elif uFlags & shellcon.CMF_EXPLORE: |
|
items.append(msg) |
|
else: |
|
pass |
|
|
|
win32gui.InsertMenu(hMenu, indexMenu, |
|
win32con.MF_SEPARATOR|win32con.MF_BYPOSITION, |
|
0, None) |
|
indexMenu += 1 |
|
for item in items: |
|
win32gui.InsertMenu(hMenu, indexMenu, |
|
win32con.MF_STRING|win32con.MF_BYPOSITION, |
|
idCmd, item) |
|
indexMenu += 1 |
|
idCmd += 1 |
|
|
|
win32gui.InsertMenu(hMenu, indexMenu, |
|
win32con.MF_SEPARATOR|win32con.MF_BYPOSITION, |
|
0, None) |
|
indexMenu += 1 |
|
return idCmd-idCmdFirst |
|
|
|
except Exception, e: |
|
alertError(None, e) |
|
raise |
|
|
|
|
|
def InvokeCommand(self, ci): |
|
mask, hwnd, verb, params, dir, nShow, hotkey, hicon = ci |
|
|
|
try: |
|
if self.dataobj is None: |
|
#background-click |
|
fname = dir |
|
else: |
|
#get Files from dragObject |
|
files = self.getDragFiles() |
|
if not files: |
|
return |
|
fname = files[0] |
|
|
|
self.CreateCCDFolderStructure(hwnd, fname) |
|
except Exception, e: |
|
alertError(hwnd, e) |
|
raise |
|
return |
|
|
|
|
|
def GetCommandString(self, cmd, typ): |
|
return "Erstellt eine CCD-Verzeichnisstruktur" |
|
|
|
|
|
def getDragFiles(self): |
|
# Format the DataObject using a formatec, then get DragQueryFile from it... |
|
format_etc = win32con.CF_HDROP, None, 1, -1, pythoncom.TYMED_HGLOBAL |
|
sm = self.dataobj.GetData(format_etc) |
|
num_files = shell.DragQueryFile(sm.data_handle, -1) |
|
files = [shell.DragQueryFile(sm.data_handle, i) for i in range(num_files)] |
|
return files |
|
|
|
|
|
def CreateCCDFolderStructure(self, hwnd, folder): |
|
ok = win32gui.MessageBox(hwnd, u'wirklich eine CCD-Struktur ersellen in\n' + folder, |
|
u'Erstellen bestägen', |
|
win32con.MB_YESNO|win32con.MB_ICONQUESTION|win32con.MB_TASKMODAL|win32con.MB_SETFOREGROUND) |
|
if ok != win32con.IDYES: |
|
return |
|
|
|
if not os.path.isdir(folder): |
|
alertError(hwnd, folder + u'\nist kein Verzeichnis. Abgebrochen.') |
|
|
|
try: |
|
for ccd in CCDFOLDERS: |
|
dir = os.path.join(folder, ccd) |
|
os.mkdir(dir) |
|
except Exception, e: |
|
alertError(hwnd, e) |
|
raise |
|
return |
|
|
|
def DllRegisterServer(): |
|
import _winreg |
|
for typ in TYPES: |
|
key = _winreg.CreateKey(_winreg.HKEY_CLASSES_ROOT, "%s\\shellex" % typ) |
|
subkey = _winreg.CreateKey(key, "ContextMenuHandlers") |
|
subkey2 = _winreg.CreateKey(subkey, SUBKEY) |
|
_winreg.SetValueEx(subkey2, None, 0, _winreg.REG_SZ, ShellExtension._reg_clsid_) |
|
print ShellExtension._reg_desc_, "registration complete." |
|
|
|
|
|
def DllUnregisterServer(): |
|
import _winreg |
|
for typ in TYPES: |
|
try: |
|
key = _winreg.DeleteKey(_winreg.HKEY_CLASSES_ROOT, "%s\\shellex\\ContextMenuHandlers\\%s" % (typ, SUBKEY)) |
|
except WindowsError, details: |
|
import errno |
|
if details.errno != errno.ENOENT: |
|
raise |
|
print ShellExtension._reg_desc_, "unregistration complete." |
|
|
|
|
|
def main(argv): |
|
from win32com.server import register |
|
register.UseCommandLine(ShellExtension, |
|
finalize_register = DllRegisterServer, |
|
finalize_unregister = DllUnregisterServer) |
|
|
|
if __name__=='__main__': |
|
import sys |
|
main(sys.argv) |