File "linkbatch.bas"
Path: /linkbatch/linkbatch.bas
File size: 14.57 KB
MIME-type:
Charset: utf-8
' !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
' After compilation, drag & drop this executable onto "setdos.exe" !
' !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#COMPILE EXE "linkbatch.exe"
#RESOURCE "linkbatch.pbr"
#DIM ALL
'------------------------------------------------------------------------------
' Usage: linkbatch "c:\path\to\*.lnk" -Opt1:Field1 "arg 1" "arg 2" -Opt2:Field2...
'------------------------------------------------------------------------------
' List of '-Opt' options:
' -p = print (display) ; no argument
' -w = write (overwrite) ; 1 argument = "any string"
' -r = string replacement ; 2 arguments = "source string" "target string"
'------------------------------------------------------------------------------
' List of Fields:
' exe = the target .exe path and name
' arg = the .exe arguments
' dir = working directory
' rem = remark or comment
' ico = icon path (can be .dll, .exe, .ico)
' idx = icon index, zero based
'------------------------------------------------------------------------------
' Notes:
' You can operate on a single .lnk, or on all shortcuts in a folder (*.lnk)
' You can chain as many operations as wanted
' Options and Fields are case insensitive: you can write -r:exe or -R:EXE
' Arguments need double quotes only if they contain spaces
' linkbatch does not make any backup! Make manual backups or be extra careful
'------------------------------------------------------------------------------
'------------------------------------------------------------------------------
' ** Includes **
'------------------------------------------------------------------------------
#INCLUDE ONCE "WIN32API.INC"
#INCLUDE ONCE "DOSPRINT.INC"
#INCLUDE ONCE "SHORTCUT.INC"
'------------------------------------------------------------------------------
'------------------------------------------------------------------------------
' ** Main Application Entry Point **
'------------------------------------------------------------------------------
FUNCTION PBMAIN()
LOCAL lnk AS LINKTYPE
LOCAL tgt AS STRING ' linkbatch tgt -optn:field arg1 arg2 -optn:field arg1 ...
LOCAL tgt() AS STRING ' tgt = tgt() in case of multiple files
LOCAL ope AS STRING ' ope = -optn:feild
LOCAL optn AS STRING
LOCAL feild AS STRING
LOCAL arg1 AS STRING
LOCAL arg2 AS STRING
LOCAL e AS STRING
LOCAL i, j AS LONG
LOCAL n AS LONG
IF COMMAND$ = "" THEN
CALL FreeConsole() ' Win32 mode -> hide console
?"This utility is to be called from the command line."+$CR+$CR _
+"Please execute Win+R > ""cmd"" and type:"+$CR+"linkbatch /?" _
, %MB_ICONINFORMATION, "linkbatch"
END IF
' Any argument: parse!
tgt = TRIM$(COMMAND$(1), ANY $SPC+$TAB+$DQ)
' No valid shortcut as first argument > show full usage
IF RIGHT$(LCASE$(tgt), 4) <> ".lnk" THEN
ShowFullUsage()
EXIT FUNCTION
END IF
'**************************************************************************
' Test existence of target file(s) to operate
'**************************************************************************
' Special case: when called without path, add current path:
IF INSTR(tgt, "\") = 0 THEN tgt = RTRIM$(CURDIR$, "\") + "\" + tgt
IF INSTR(tgt, "*") = 0 AND INSTR(tgt, "?") = 0 THEN
' Treating a single file
REDIM tgt(0)
IF NOT EXISTS(tgt) THEN GOTO ErrFile
tgt(0) = tgt
ELSE
' Treating multiple files
n = -1
e = DIR$(tgt)
WHILE e <> ""
INCR n
REDIM PRESERVE tgt(n)
tgt(n) = PATHNAME$(PATH, tgt) + e
e = DIR$(NEXT)
WEND
DIR$ CLOSE
IF n < 0 THEN GOTO ErrFile
END IF
n = 2
'**************************************************************************
DO ' Analyze all arguments for errors
'**************************************************************************
' Check valid "-Optn:Field" operation syntax
ope = TRIM$(LCASE$(COMMAND$(n)), ANY $SPC+$TAB+$DQ)
IF LEFT$(ope,1) <> "-" OR MID$(ope,3,1) <> ":" THEN GOTO ErrOpe
' Get Optn from "-Optn:Field" and test against available options: -p -w -r
optn = MID$(ope,2,1)
IF INSTR("pwr", optn) = 0 THEN GOTO ErrOpe
' Get Field from "-Optn:Field" and test against allowed fields
feild = MID$(ope,4)
IF feild <> "exe" AND feild <> "arg" AND feild <> "dir" _
AND feild <> "rem" AND feild <> "ico" AND feild <> "idx" THEN GOTO ErrOpe
' All good > analyze arguments
IF optn = "w" THEN
' -w = write = 1 non-empty argument needed
INCR n
arg1 = TRIM$(COMMAND$(n), ANY $SPC+$TAB+$DQ)
IF arg1 = "" OR LEFT$(arg1, 1) = "-" THEN GOTO ErrArg
ELSEIF optn = "r" THEN
' -r = replace = 2 non-empty arguments needed
INCR n
arg1 = TRIM$(COMMAND$(n), ANY $SPC+$TAB+$DQ)
IF arg1 = "" OR LEFT$(arg1, 1) = "-" THEN GOTO ErrArg
INCR n
arg2 = TRIM$(COMMAND$(n), ANY $SPC+$TAB+$DQ)
' arg2 can actually be an empty string, if we want to
' remove something, e.g. linkbatch shortcut.lnk -r:exe " (x86)" ""
' to replace "C:\Program Files (x86)\myprog.exe"
' with "C:\Program Files\myprog.exe" ...
IF LEFT$(arg2, 1) = "-" THEN GOTO ErrArg
ELSEIF optn = "p" THEN
' -p = print = no argument needed
END IF
INCR n
LOOP UNTIL COMMAND$(n) = ""
'**************************************************************************
' We completed the analysis without meeting any error :)
' --> for each target file, run the parsing again
' and this time execute the operations!
'**************************************************************************
'**************************************************************************
FOR i = 0 TO UBOUND(tgt) ' For each target file
DosPrint "File: " + tgt(i)
' Parse path and filename
lnk.zLinkFolder = PATHNAME$(PATH , tgt(i))
lnk.zLinkName = PATHNAME$(NAMEX, tgt(i))
' And read shortcut information
ReadShortcut(lnk)
n = 2
DO ' Treat all operations
' Get Optn and Field from "-Optn:Field"
ope = TRIM$(COMMAND$(n), ANY $SPC+$TAB+$DQ)
optn = LCASE$(MID$(ope,2,1))
feild = LCASE$(MID$(ope,4))
' Execute operation!
SELECT CASE optn
CASE "p" ' -p = print (no argument)
SELECT CASE feild
CASE "exe" : DosPrint "- " + feild + " = " + lnk.zExeName
CASE "arg" : DosPrint "- " + feild + " = " + lnk.zArguments
CASE "dir" : DosPrint "- " + feild + " = " + lnk.zWorkDir
CASE "rem" : DosPrint "- " + feild + " = " + lnk.zComment
CASE "ico" : DosPrint "- " + feild + " = " + lnk.zIconFile
CASE "idx" : DosPrint "- " + feild + " = " + FORMAT$(lnk.IconIndex)
END SELECT
CASE "w" ' -w = write (1 argument)
INCR n
arg1 = TRIM$(COMMAND$(n), ANY $SPC+$TAB+$DQ)
SELECT CASE feild
CASE "exe" : e = $DQ + lnk.zExeName + $DQ : lnk.zExeName = arg1
CASE "arg" : e = $DQ + lnk.zArguments + $DQ : lnk.zArguments = arg1
CASE "dir" : e = $DQ + lnk.zWorkDir + $DQ : lnk.zWorkDir = arg1
CASE "rem" : e = $DQ + lnk.zComment + $DQ : lnk.zComment = arg1
CASE "ico" : e = $DQ + lnk.zIconFile + $DQ : lnk.zIconFile = arg1
CASE "idx" : e = FORMAT$(lnk.IconIndex) : lnk.IconIndex = VAL(arg1)
END SELECT
DosPrint "- " + feild + ": " + e + " <<< " + IIF$(LEFT$(e,1)=$DQ,$DQ,"") + arg1 + IIF$(LEFT$(e,1)=$DQ,$DQ,"")
CASE "r" ' -r = replace (2 arguments)
INCR n
arg1 = TRIM$(COMMAND$(n), ANY $SPC+$TAB+$DQ)
INCR n
arg2 = TRIM$(COMMAND$(n), ANY $SPC+$TAB+$DQ)
SELECT CASE feild
CASE "exe"
j = INSTR(LCASE$(lnk.zExeName), LCASE$(arg1))
IF j = 0 THEN
DosPrint "- " + feild + ": did not find any " + $DQ + arg1 + $DQ + " to replace"
ELSE
e = lnk.zExeName
lnk.zExeName = LEFT$(e, j-1) + arg2 + MID$(e, j+LEN(arg1))
DosPrint "- " + feild + ": " + $DQ + e + $DQ + " <<< " + $DQ + lnk.zExeName + $DQ
END IF
CASE "arg"
j = INSTR(LCASE$(lnk.zArguments), LCASE$(arg1))
IF j = 0 THEN
DosPrint "- " + feild + ": did not find any " + $DQ + arg1 + $DQ + " to replace"
ELSE
e = lnk.zArguments
lnk.zArguments = LEFT$(e, j-1) + arg2 + MID$(e, j+LEN(arg1))
DosPrint "- " + feild + ": " + $DQ + e + $DQ + " <<< " + $DQ + lnk.zArguments + $DQ
END IF
CASE "dir"
j = INSTR(LCASE$(lnk.zWorkDir), LCASE$(arg1))
IF j = 0 THEN
DosPrint "- " + feild + ": did not find any " + $DQ + arg1 + $DQ + " to replace"
ELSE
e = lnk.zWorkDir
lnk.zWorkDir = LEFT$(e, j-1) + arg2 + MID$(e, j+LEN(arg1))
DosPrint "- " + feild + ": " + $DQ + e + $DQ + " <<< " + $DQ + lnk.zWorkDir + $DQ
END IF
CASE "rem"
j = INSTR(LCASE$(lnk.zComment), LCASE$(arg1))
IF j = 0 THEN
DosPrint "- " + feild + ": did not find any " + $DQ + arg1 + $DQ + " to replace"
ELSE
e = lnk.zComment
lnk.zComment = LEFT$(e, j-1) + arg2 + MID$(e, j+LEN(arg1))
DosPrint "- " + feild + ": " + $DQ + e + $DQ + " <<< " + $DQ + lnk.zComment + $DQ
END IF
CASE "ico"
j = INSTR(LCASE$(lnk.zIconFile), LCASE$(arg1))
IF j = 0 THEN
DosPrint "- " + feild + ": did not find any " + $DQ + arg1 + $DQ + " to replace"
ELSE
e = lnk.zIconFile
lnk.zIconFile = LEFT$(e, j-1) + arg2 + MID$(e, j+LEN(arg1))
DosPrint "- " + feild + ": " + $DQ + e + $DQ + " <<< " + $DQ + lnk.zIconFile + $DQ
END IF
CASE "idx"
IF lnk.IconIndex <> VAL(arg1) THEN
DosPrint "- " + feild + ": skipping icon index not equal to " + FORMAT$(VAL(arg1))
ELSE
e = FORMAT$(lnk.IconIndex)
lnk.IconIndex = VAL(arg2)
DosPrint "- " + feild + ": " + e + " <<< " + FORMAT$(VAL(arg2))
END IF
END SELECT
END SELECT
INCR n
LOOP UNTIL COMMAND$(n) = ""
' Save modified shortcut
WriteShortcut(lnk)
DosPrint ""
NEXT i
' Normal termination
FUNCTION = 0
EXIT FUNCTION
'**************************************************************************
'******
ErrFile:
'******
DosPrint "Error: no matching file " + $DQ + tgt + $DQ
FUNCTION = 1
EXIT FUNCTION
'******
ErrOpe:
'******
DosPrint "Error: invalid ""-Opt:Field"" operation " + $DQ + ope + $DQ
DosPrint ""
ShowShortUsage()
FUNCTION = 2
EXIT FUNCTION
'******
ErrArg:
'******
DosPrint "Error: invalid argument, or number of arguments, for " + $DQ + ope + $DQ
DosPrint ""
ShowShortUsage()
FUNCTION = 3
EXIT FUNCTION
END FUNCTION
'------------------------------------------------------------------------------
'------------------------------------------------------------------------------
SUB ShowShortUsage()
DosCol 10, 0
DosPrint "Usage: linkbatch ""c:\path\to\*.lnk"" -Opt1:Field1 ""arg 1"" ""arg 2"" -Opt2:Field2..."
DosPrint " -Opt = -p (print, 0 arg), -w (write, 1 arg), -r (replace, 2 args)"
DosPrint " Fields = exe, arg, dir, rem, ico, idx
DosPrint " You can type ""linkbatch /?"" for more details"
DosCol 7, 0
END SUB
'------------------------------------------------------------------------------
'------------------------------------------------------------------------------
SUB ShowFullUsage()
DosCol 10, 0
DosPrint "Usage: linkbatch ""c:\path\to\*.lnk"" -Opt1:Field1 ""arg 1"" ""arg 2"" -Opt2:Field2..."
DosPrint ""
DosPrint "List of '-Opt' options:"
DosPrint " -p = print (display) ; no argument"
DosPrint " -w = write (overwrite) ; 1 argument = ""any string"""
DosPrint " -r = string replacement ; 2 arguments = ""source string"" ""target string"""
DosPrint ""
DosPrint "List of shortcut ':Fields':"
DosPrint " :exe = target .exe path and name"
DosPrint " :arg = executable arguments"
DosPrint " :dir = working directory"
DosPrint " :rem = remark or comment"
DosPrint " :ico = icon path (.dll, .exe, .ico)"
DosPrint " :idx = icon index, zero based"
DosPrint ""
DosPrint "Notes:"
DosPrint " You can operate on a single .lnk, or on all shortcuts in a folder (*.lnk)"
DosPrint " You can chain as many operations as wanted"
DosPrint " Options and Fields are case insensitive: you can write -r:exe or -R:EXE"
DosPrint " Target .lnk and arguments need double quotes only if they contain spaces"
DosPrint " linkbatch does not make any backup! Please backup your shortcuts manually"
DosCol 7, 0
END SUB
'------------------------------------------------------------------------------
'------------------------------------------------------------------------------
FUNCTION EXISTS(BYVAL fileOrFolder AS STRING) AS LONG
LOCAL Dummy&
Dummy& = GETATTR(fileOrFolder)
FUNCTION = (ERRCLEAR = 0)
END FUNCTION
'------------------------------------------------------------------------------