This program is a simple Win32 command submitter. It uses a set of macros similar
to those used by the QEditor program, strings such as '{b}'. The macros are replaced
with text from a specified file path. Options to change the working directory and
selected environment variables are provided. Two examples are provided in the code.
The program does not collect output or provide input. It does one call to the expand
routine. It can not recognize parameters containing white space. Do2 which follows
does. Module is used by Do2 and ButtonBarV1Ex which follow.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 | #
----------------------------------------------
# Name: Do
# Description: Expand and execute command
## D20H-35 Expand and execute command
#
# Author: Philip S. Rist
# Date: 10/12/2010
# Copyright 2010 by St. Thomas Software
# ----------------------------------------------
# This program is freeware. It may be used
# for any moral purpose. You use it at your
# own risk. St. Thomas Software makes no
# guarantees to its fitness to do anything.
#
# If you feel you must pay for it. Please
# send one million dollars to
#
# The International Rescue Committee
# 122 East 42nd Street
# New York, N.Y. 10168-1289
#
# Ok, we are in a recession. So, make it a half
# million.
# Usage examples:
#
#[HKEY_CLASSES_ROOT\*\Shell\DoBkup]
#@="Backup (Do)"
#"EditFlags"=hex:01,00,00,00
#[HKEY_CLASSES_ROOT\*\Shell\DoBkup\Command]
#@="c:\\sys\\python25\\pythonw.exe c:\\bin\\do.py \"%1\"
c:\\Windows\\system32\\cmd.exe /K copy \"{a}\" \"{u}\\{2}\\{f}\" "
#
#[HKEY_CLASSES_ROOT\*\Shell\DoEdit]
#@="Edit (Do)"
#"EditFlags"=hex:01,00,00,00
#[HKEY_CLASSES_ROOT\*\Shell\DoEdit\Command]
#@="c:\\sys\\python25\\pythonw.exe c:\\bin\\do.py \"%1\"
{o}\\qeditor.exe \"{a}\" "
#
import sys
import os
import getopt
# Used only by the {o} option which you will
# probably want to remove
from _winreg import *
import subprocess
def Expand(pCommand, pFilePath, pSep='\\'):
'Replace all {?} macros in pCommand'
# Split file path into parts
if len(pFilePath) > 0:
lFilePath = os.path.abspath(pFilePath)
lEndPos = lFilePath.rfind(pSep)
lPath = lFilePath[0:lEndPos]
lFileName = lFilePath[lEndPos+1:]
lEndPos = lFileName.rfind(".")
lName = lFileName[:lEndPos]
lFilePart = lPath + pSep + lName
lExtension = lFileName[lEndPos+1:]
lPathParts = lFilePath.split(pSep)
else:
lFilePath = lPath=lFileName=lName=lFilePart=lExtension=""
lPathParts = []
lParts = pCommand.split('{')
if len(lParts) == 1: # no replacements
lCommand = pCommand
else: # scan and replace
commands
lCommand = lParts[0]
for lPart in lParts[1:]: # for each
replacement
lPos = lPart.find('}')
lCh = lPart[0].lower()
if lPos == 1:
lPos = 0
if lCh == 'a': # entire file
path
lInsert = lFilePath
elif lCh == 'b': # file path
except extension
lInsert = lFilePart
elif lCh == 'p': # path to
folder containing file
lInsert = lPath
elif lCh == 'f': # file name
without path
lInsert = lFileName
elif lCh == 'n': # file name
without path or extension
lInsert = lName
elif lCh == 'e': # extension
lInsert = lExtension
elif lCh == 't':
lInsert = "c:\\temp" # temporary
directory
elif lCh == 'i':
lInsert = "c:\\bin" # installation
directory
elif lCh == 'u':
lInsert = "c:\\_Backup" # backup
directory
elif lCh == 'o': # source
directory
# I added a
SourceDir key for each programming
# language
extension. This replacements is
# replaced by
that text.
try:
lKey = OpenKey(HKEY_CLASSES_ROOT, '.' +
lExtension)
lIndex = 1
while lIndex < 10:
try:
lValue = EnumValue(lKey, lIndex)
if lValue[0] == 'SourceDir':
lInsert = lValue[1]
break
except Exception ,e:
lInsert = "c:\\unknown_type"
break
lIndex += 1
else:
lInsert = "c:\\unknown_type"
except Exception, e:
lInsert = "c:\\unknown_type" #
{o}
elif lCh == 'y':
lInsert = "c:\\sys" # System
directory
elif lCh == 'w':
lInsert = "c:\\windows\\system32" # Windows
directory
elif lCh == 'v':
lInsert = "j:\\_Backup" # Archive
directory
elif lCh == 'l':
lInsert = "c:\\Library" # Library
directory
elif lCh == 'g':
lInsert = "c:\\Program Files" # Program
Files directory
elif lCh == '.':
lInsert = os.getcwd() # Current
directory
elif lCh == '*': # System
command
lInsert = 'c:\\windows\\system32\\cmd.exe'
elif lCh == '+': # Python
lInsert = 'c:\\sys\\python25\\python.exe'
#elif lCh == '%':
# try:
# lPos = lPart[1:].find("%")
# if lPos > 1:
# lKey = lPart[1:lPos]
# lInsert = os.environ[lKey]
# lPos += 1
# else:
# lInsert = ''
# except:
# lInsert = ''
elif lCh == '0': # Drive letter
(ie. c:\source\python\new\test.py --> c:\)
lInsert = lPathParts[0]
elif lCh == '1' and len(lPathParts) > 1: # First
level (ie. c:\source\python\new\test.py --> source)
lInsert = lPathParts[1]
elif lCh == '2' and len(lPathParts) > 2: # Second
level (ie. c:\source\python\new\test.py --> python)
lInsert = lPathParts[2]
elif lCh == '3' and len(lPathParts) > 3: # Third
level (ie. c:\source\python\new\test.py --> new)
lInsert = lPathParts[3]
else:
lInsert = '{' + lPart
elif lCh == '-' and lPos == 2:
lPos = 1
lCh = lPart[1]
if lCh == '1' and len(lPathParts) > 2: # Last
level (ie. c:\source\python\new\test.py --> new)
lInsert = lPathParts[-2]
elif lCh == '2' and len(lPathParts) > 3: # Next to
last level (ie. c:\source\python\new\test.py --> python)
lInsert = lPathParts[-3]
elif lCh == '3' and len(lPathParts) > 4: # Second
to last level (ie. c:\source\python\new\test.py --> source)
lInsert = lPathParts[-4]
else:
lInsert = '{' + lPart[lPos+2]
else:
lInsert = '{' + lPart[lPos+2]
lPart = lInsert + lPart[lPos+2:]
lCommand += lPart
return lCommand
def submitnow(pCommand, pFileName):
'Expand and submit command'
lCommand = Expand(pCommand, pFileName)
lCommand = '"' + lCommand + '"'
subprocess.Popen(lCommand, shell=True)
def setenviron(pValue, pFileName):
'Set environment variable'
lParts = pValue.split('=')
if len(lParts) > 1:
lKey = lParts[0]
lValue = lParts[1]
if lValue.find('{') >= 0:
lValue = Expand(lValue, pFileName)
os.environ[lKey] = lValue
else:
os.environ[pValue] = ''
#sys.argv.extend( [ '-d', '{o}\\new', 'c:\\source\\c\\test\\menus.ini',
'c:\\bin\\echop.bat', '{a}', '{p}\\test\\{f}', '{b}.exe',
'{t}\\{n}.bkp',
# '{i}\\{-1}', '{u}\\{-2}', '{.}\\{-3}',
'"{g}\\{2}\\test.{e}"', '{fp}', '{0}\\{3}\\{n}.{e}.txt' ])
# Syntax: [Options] file-path command
if __name__ == '__main__':
(mOptions, mArgs) = getopt.getopt(sys.argv[1:], 'd:e:')
if len(mArgs) > 1:
mFileName = mArgs[0]
mCommand = ' '.join(mArgs[1:])
for (mKey, mValue) in mOptions:
if mKey == '-d': # Set current directory
if mValue.find('}') >= 0:
mValue = Expand(mValue, mFileName)
os.chdir(mValue)
elif mKey == '-e': # Set environment variable
setenviron(mValue, mFileName)
submitnow(mCommand, mFileName)
else:
print 'Command and/or file path missing'
|
This program is written for Python 2.X on a Win32 XP computer. I have not tried it under any other system. I expect it to be relatively easy to convert. The _winreg module is used only for one macro, '{o}' which is replaced by a non-standard path retrieved from the registry. On my system I use it to identify the top folder for each language on my computer, "c:\source\python" for example. It has been run with ActiveState Python 2.5 and 2.7.
It can be used to build file associations where multiple related file paths are required or where the file path required is not the file path associated with the command. Several macros can be used to extract parts of the file path. Others are replaced by related paths. Feel free to modify or add macros. Unrecognized strings are passed through. The module can be imported by a second program which calls the Expand function and then checks for non-standard macros. My GrepTk program adds a '{fp}' macro to request a file path from the user with easygui.
Hopefully this isn't a premature submission. I have been playing with it off and on for six months. If I didn't upload it now it may never get uploaded.
If not useful hopefully it will be interesting.