Add a custom context menu via vbScript

Reverend Jim 0 Tallied Votes 1K Views Share

I find that I occasionaally have special projects where it would be nice to have a context menu for files. I tend to write housekeeping scripts and it is convenient to be able to run these scripts against one or more files at a time without having to navigate and run through the command line. For example, I have accumulated a large number of articles and ebooks. I file them with a consistent naming convention, to wit

Author Name - Title.ext

where the author name is in the form "First Last" if I have not yet read the article or book, and "Last, First" if I have. A convenient tool would allow me to right click on a file name and select "Swap Names" from a context menu. Adding such a menu turns out to be trivial. The script in this code snippet demonstrates how this can be done. Customizing this snippet to add your own custom menu item and code is as simple as writing a function, renaming the script and providing the text for the context menu.

Installing or removing the context menu is as simple as typing (in a command shell running as Admin)

swapnames -install
swapnames -uninstall

Comments and suggestions are always welcome.

'
'  Name:
'
'    Swapnames.vbs
'
'  Description:
'
'    This script should be used on files with names in the format "author - title.ext".
'    When user on a file like this, the script swaps the author first and last names.
'    In other words, if the file name is
'
'      Asimov, Isaac - The Bicentennial Man & Other Stories.lit
'
'    then running the script will rename the file to
'
'      Isaac Asimov - The Bicentennial Man & Other Stories.lit
'
'    and running it again will return the file to the original name. 
'
'  Usage:
'
'    This script is added to the Explorer context menu for files. Before you use this
'    script for the first time you have to run it with Admin rights from the command
'    line as follows:
'
'swap -enable
'
'    This will add an entry to the registry under HKCR\*\shell. Running
'
'    swap -disable
'
'    will remove the registry entries
'
'    To run the script against a file just right click the file and select Swap Names.
'    You can select multiple files but I suggest no more than ten at a time to avoid
'    maxing out the command line.
'
'  Notes:
'
'    This may seem like a pretty useless script, however, I have a large number of
'    ebooks and I keep track of which books I have read and which I haven't by the
'    format of the author's name. If it is FIRST LAST then I have not read it. If it is
'    LAST, FIRST then I have.
'
'    And even if the script itself does not suit your needs, you can still use the
'    technique to add your own custom file handler to the explorer context menu.
'
'    To use this script to add other context handlers you should only have to modify
'    three things:
'
'      1 - change the name of this script file
'      2 - change the value of SCRDESC
'      3 - change the code in the DoProcess function
'
'  Audit:
'
'    2013-06-24  rj  original code
'

SCRNAME = Wscript.ScriptFullName			'fully qualified name of this script		
SCRDESC = "Swap Names"						'text that appears in context menu			

Set wso = CreateObject("Wscript.Shell")
Set fso = CreateObject("Scripting.FileSystemObject")

'process each file selected by the user

For Each arg In Wscript.Arguments

    Select Case true
        Case Lcase(arg) = "-install"   : InstallShellExtension()
        Case Lcase(arg) = "-uninstall" : UninstallShellExtension
        Case Else                      : DoProcess arg
	End Select

Next

Function DoProcess (arg)

	'For a file name to be "swappable" it should contain a "-". For book	
	'files, the "-" separates the author name (first field) from the rest	
	'of the title (which may contain one or more "-"). Split off the author	
	'field and determine whether it is "first last" or "last, first", then	
	'swap.																	

	Dim file: file = fso.GetBaseName(arg)
	Dim extn: extn = fso.GetExtensionName(arg)
	Dim swap: swap = True

	'only process file if name is like "Author - Title.ext"

	If Instr(file,"-") > 0 Then

		flds = Split(file,"-")
		flds(0) = Trim(flds(0))
		
		'If the author name contains a comma then assume it is in the form	
		'"Last, First" otherwise assume "First Last". Note that it assumes	
		'last names are single-word.										

		Select Case True
		
			Case InStr(flds(0),",") > 0		'Last, First					
				newname = Trim(Mid(flds(0),Instr(flds(0),",")+2)) & " " _
					    & Trim(Mid(flds(0),1,Instr(flds(0),",")-1))
			Case InStr(flds(0)," ") > 0		'First Last						
				newname = Trim(mId(flds(0),InStrRev(flds(0)," ")+1)) & ", " _
					    & Trim(mid(flds(0),1,InStrRev(flds(0)," ")-1))
			Case Else
				swap = False
				
		End Select

		If swap Then
			newname = newname & Mid(file,InStr(file,"-")-1) & "." & extn
			On Error Resume Next
			fso.MoveFile arg, newname
			If err.Number <> 0 Then
				MsgBox arg, vbOkOnly,"Could not rename" & vbCrLf & arg & vbCrLf & "to " & newname
				err.Clear
			End If
		End If
		
	end if

End Function

Function InstallShellExtension()

	'install shell extension (requires admin access)

	On Error Resume Next
	
	If ExtensionExists() Then
		MsgBox "The " & SCRDESC & " extension is already installed", vbOkOnly, SCRNAME
	Else
		wso.RegWrite "HKCR\*\shell\" & SCRDESC & "\",SCRDESC,"REG_SZ"
		wso.RegWrite "HKCR\*\shell\" & SCRDESC & "\command\", "wscript """ & SCRNAME & """ ""%1"""
		If err.Number = 0 Then 
			MsgBox "The " & SCRDESC & " extension has been installed"
		Else
			MsgBox err.Description & vbCrLf & "You need to run this as Administrator", vbOkOnly, SCRNAME
		End If
	End If

End Function

Function UninstallShellExtension()

	'uninstall shell extension (requires admin access)

	On Error Resume Next
	
	If ExtensionExists() Then
		wso.RegDelete "HKCR\*\shell\" & SCRDESC & "\command\"
		wso.RegDelete "HKCR\*\shell\" & SCRDESC & "\"
		If err.Number = 0 then 
			MsgBox "The " & SCRDESC & " extension has been uninstalled", vbOkOnly, SCRNAME
		Else
			MsgBox err.Description & vbCrLf & "You need to run this as Administrator", vbOkOnly, SCRNAME
		End If
	Else
		MsgBox "The " & SCRDESC & " extension is not currently installed", vbOkOnly, SCRNAME
	End If

End Function

Function ExtensionExists ()

	'returns True if the shell extension is installed

	Dim val
	On Error Resume Next
	err.Clear
	val = wso.RegRead("HKCR\*\shell\" & SCRDESC & "\")
	ExtensionExists = (err.Number = 0)
	On Error Goto 0

End Function