Context Menu options using CMD.exe or Powershell

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
Squashman
Expert
Posts: 4486
Joined: 23 Dec 2011 13:59

Context Menu options using CMD.exe or Powershell

#1 Post by Squashman » 21 Jul 2018 00:03

Thought this might be a fun thread to start. Saw someone doing this on StackOverFlow. I helped them resolve the Date Time Stamp Context Menu. SST helped them with the file path to the clipboard.

File path to clipboard

Code: Select all

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Classes\*\shell\FilePath2clip\command]
@="cmd /Q /e:on /c \"for %%a in (\"%1\") do set /p \"=%%~dpa\"<nul | clip\""
Rename File with Date and Time Stamp

Code: Select all

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Classes\*\shell\Time_Stamp_FileName\command]
@="cmd /Q /V:ON /E:ON /C \"set TIME=%%TIME: =0%% & set \"DateTimeFn=%%DATE:~10,4%%-%%DATE:~4,2%%-%%DATE:~7,2%%_!TIME:~0,2!-!TIME:~3,2!-!TIME:~6,2!\" &FOR %%G IN (\"%1\") do rename \"%1\" \"%%~nG_!DateTimeFn!%%~xG\" \""


Hope everyone can share some more.

Compo
Posts: 600
Joined: 21 Mar 2014 08:50

Re: Context Menu options using CMD.exe

#2 Post by Compo » 21 Jul 2018 10:48

As an opening comment, I think that the SO answer from sst was overly complex for the task, given that %W does what was needed, (the other two answers show it in use)!

Here's something from an answer I used here, which creates a context menu entry for making a new directory with today's date:

Code: Select all

@Powershell -NoP -C "New-Item 'HKCU:\Software\Classes\Directory\Background\shell\MkStampedDir' -Value 'NOW Folder Here' -Force"; "New-Item 'HKCU:\Software\Classes\Directory\Background\shell\MkStampedDir\command' -Value '\"C:\Windows\system32\WindowsPowerShell\v1.0\Powershell.exe\" -NoP -C \"$dt = get-date -f {yyyy-MMM-dd HHmm}; MD \"\"%V\"\"\$dt\"\"\"' -Force"
(I decided to include it in this thread because it uses PowerShell for the datestamp)

If you wanted a reg file, which to me is a backwards step from using REG.EXE, due to the fact Windows wants elevation, then something like this would do:

Code: Select all

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Classes\Directory\Background\shell\MkStampedDir]
@="NOW Folder Here"

[HKEY_CURRENT_USER\Software\Classes\Directory\Background\shell\MkStampedDir\command]
@="\"C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\Powershell.exe\" -NoP -C \"$dt = get-date -f {yyyy-MMM-dd HHmm}; MD \"\"%V\"\"\\$dt\"\"\""

sst
Posts: 93
Joined: 12 Apr 2018 23:45

Re: Context Menu options using CMD.exe

#3 Post by sst » 21 Jul 2018 13:06

PowerShell while powerful is not a right choice for shell tasks given the crazy slow startup time on first use after boot, probably the user must be more careful to not accidentally click on that item.

I was pretty sure that there are other variables, as I mentioned about %V, but didn't take the time to investigate them, my answer was in part influenced by OP's confusion and misinterpretation of shell and cmd variables, that something like %~dp1 can be used directly.
Anyway good to know about %W

To me the whole task is nearly useless, in whatever way, simple or complex. One can get the path, simply by coping it from address bar, so while It is true that this particular task and the like can be done in a more simple and efficient way, but the overly complex one can used as the basis for doing much more complex tasks, like what Squashman did for renaming. The other answer ruined the simplicity by piping echo to set /p to dismiss the prompt, invoking one more extra cmd, Your answer is overly simple, appended new line, usually is not the thing one likes to see in clipboard.

Compo
Posts: 600
Joined: 21 Mar 2014 08:50

Re: Context Menu options using CMD.exe or Powershell

#4 Post by Compo » 21 Jul 2018 13:45

sst, the point of my very simplified answer to the SO question was the use of %W and I'm also aware that it included a possibly unwanted new line, although it wasn't stated, (only the doublequotes), which mine didn't have, or a possibly unwanted trailing backslash. BTW, the powershell example I provided was supposed to be copied/pasted at the prompt, so it shouldn't be accidentally clicked on.

I think that the PowerShell start up time on first boot, whilst valid, isn't an issue in real terms. Even if it's the first time I used PowerShell today; given my typing speed/accuracy, I couldn't right click, select New, select Folder and type and enter without mistake, todays date, even if I knew it in advance, quicker than the couple of seconds it takes! If you're really concerned with speed, then as implied in my post above, converting the entry to a batch file using REG.EXE would mean you didn't have to wait for the UAC prompt when wanting to merge the reg file, especially as the entry is for the current user and not a protected registry location. (TBF, the examples above should probably be provided in batch file format given this sites' main focus.)

As I stated, I only added the example above because of its use of PowerShell in retrieving/formatting date entries, to support Squashmans' thread.

TBH I find most context menu entries a waste of time, especially given that the more you have, the more you have to scan to find and select the one you need!

sst
Posts: 93
Joined: 12 Apr 2018 23:45

Re: Context Menu options using CMD.exe or Powershell

#5 Post by sst » 22 Jul 2018 19:22

Compo wrote:
21 Jul 2018 13:45
BTW, the powershell example I provided was supposed to be copied/pasted at the prompt, so it shouldn't be accidentally clicked on.
I was referring to usage in context menu as your registry example implies that.
Compo wrote:
21 Jul 2018 13:45
... even if I knew it in advance, quicker than the couple of seconds it takes.
I've seen systems that PS first time startup takes more than one minute. On my Win10 laptop, PS sometimes takes between 30 to 40 seconds to get ready and on my other PC about 10 seconds, sometimes more sometimes less. It is highly variable between systems with different software/hardware configurations. I agree that on subsequent usages, the time to perform the task is nearly instant but the first time delay for a right click task which is not time consuming in nature and is expected to be done very quickly, might causes the user to at least postpone using that handy context menu to a later time and creates the folder by hand for that one time, and then makes that decision over and over again.

I was just expressing my personal opinion regarding the matter generally, which partly shaped by the experiences I had with users. And here I referred to folder creation just as an example of a simple task, So it is not and was not a criticism of your post or your solution involving PowerShell. After all the title of this thread asks for using both CMD and PowerShell.

sst
Posts: 93
Joined: 12 Apr 2018 23:45

Re: Context Menu options using CMD.exe or Powershell

#6 Post by sst » 22 Jul 2018 21:23

I thought it might be useful to have a hash calculator in context menu using certutil.
So I've created 3 types on them. One is for use on individual files, right click on a file choose copy hash, to calculate the hash and copy it to clipboard.
The second and third is available in context menu of directories for generating list of files along with their hash value with a predefined format and copy it to the clipboard, one performs the task only on files which are the direct child of the selected directory and the other will perform the task on the whole subdirectory tree.

I chose SHA1 as the hash algorithm, changing the algorithm is the simple task of performing search and replace over "SHA1".

I appended the registry script to a very simple stub batch code which uses REG.EXE to import the embedded script, addressing the concerns mentioned by Compo regarding UAC prompt by REGEDIT.
It can be easily used to convert a REG script to a self importer script. e.g:

Code: Select all

type Unicode.reg>Ansi.reg & copy ImportStub.bat+Ansi.reg SelfImport.bat & del Ansi.reg
Hash ContextMenus Script:

Code: Select all

:: CmdHashCntxMenu.bat
:: Hash Files/Directories Context Menu
:: SelfImporter Registry Script
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "TIME="
set "id=%TIME: =0%"
set "id=%~nx0.%id:~0,2%%id:~3,2%%id:~6,2%%id:~-2%"
set "RegFile=%TEMP%\RegImport.%id%.reg.tmp"
(
    echo REGEDIT4
    echo,
    type "%~f0"
)>"%RegFile%" && (
    echo Importing registry script...
    reg import "%RegFile%"
    del /f /q "%RegFile%"
)
pause
goto :EOF
<End of batch script>
Windows Registry Editor Version 5.00

;-------------------------------------------------------------------------------------------------------

## <File SHA1 Value to Clipboard - Comment related sections to exclude from import>
[HKEY_CURRENT_USER\Software\Classes\*\shell\CopyFileHashClip]
@="Copy SHA1 Hash"

[HKEY_CURRENT_USER\Software\Classes\*\shell\CopyFileHashClip\Command]
@="cmd.exe /q /d /c \"title Calculating SHA1 hash&cd /d \"%%SystemRoot%%\\system32\" & echo Generating SHA1 hash over \"%1\" ...& for /f \"delims=\" %%a in ('certutil -hashfile \"%1\" SHA1 ^| find /v \":\"') do set \"_$hash=%%a\"&call set \"_$hash=%%_$hash: =%%\"&<nul set /p \"=%%_$hash%%\" | clip\""

;; Uninstaller - Uncomment to remove the entry from registry
;[-HKEY_CURRENT_USER\Software\Classes\*\shell\CopyFileHashClip]

;-------------------------------------------------------------------------------------------------------

## <DIR SHA1 List to Clipboard - Comment all related to exclude from import>
[HKEY_CURRENT_USER\Software\Classes\Directory\shell\CmdHashListClip]
@="SHA1 List to Clipboard"

[HKEY_CURRENT_USER\Software\Classes\Directory\shell\CmdHashListClip\Command]
@="cmd.exe /d /c \"title Generating SHA1 Hash List to Clipboard...&cd /d \"%%SystemRoot%%\\system32\"&echo Generating SHA1 hash List over files in directory of \"%1\"...&(for /f \"eol=* delims=\" %%f in ('dir \"%1\" /b/a-d 2^^^>nul') do @(for /f \"delims=\" %%h in ('certutil -hashfile \"%1\\%%f\" SHA1 ^^^| find /v \":\"') do @(set \"_$hash=%%h\"&call set \"_$hash=%%_$hash: =%%\"&echo \"%1\\%%f\"...>conOUT$&set \"_$file=%1\\%%f\"&<nul call set /p \"=%%_$file%%:SHA1:%%_$hash%%\"&echo,)))|clip\""

;; Uninstaller - Uncomment to remove the entry from registry
;[-HKEY_CURRENT_USER\Software\Classes\Directory\shell\CmdHashListClip]


;-------------------------------------------------------------------------------------------------------

## <DIR SHA1 List to Clipboard (Tree) - Comment related sections to exclude from import>
[HKEY_CURRENT_USER\Software\Classes\Directory\shell\CmdHashListClipTree]
@="SHA1 List to Clipboard (Tree)"

[HKEY_CURRENT_USER\Software\Classes\Directory\shell\CmdHashListClipTree\Command]
@="cmd.exe /d /c \"title Generating SHA1 Hash List to Clipboard... (Tree)&cd /d \"%%SystemRoot%%\\system32\"&echo Generating SHA1 hash List over files in directory tree of \"%1\"...&(for /f \"delims=\" %%f in ('dir \"%1\" /s/b/a-d 2^^^>nul') do @(for /f \"delims=\" %%h in ('certutil -hashfile \"%%f\" SHA1 ^^^| find /v \":\"') do @(set \"_$hash=%%h\"&call set \"_$hash=%%_$hash: =%%\"&echo \"%%f\"...>conOUT$&set \"_$file=%%f\"&<nul call set /p \"=%%_$file%%:SHA1:%%_$hash%%\"&echo,)))|clip\""

;; Uninstaller - Uncomment to remove the entry from registry
;[-HKEY_CURRENT_USER\Software\Classes\Directory\shell\CmdHashListClipTree]
When I was testing the menu, on one particular directory I couldn't get it to work, nothing was in clipboard, then I saw that clip.bat file in the directory, So I decided to first change the current directory to %SystemRoot%\system32 to be safe.

I opted to not pass /e:on or /v:off to cmd, if I want to cover the edge cases then I have to handle the child cmd instances of pipes and FOR /F as well, and that would turn the one-liner command to a very complex and unmanageable beast, and if don't want to handle the childs then there is no point in passing those parameters to the main cmd.

Update 2018-07-23
The directory context menu command which is processing files within the selected directory and not the sub directories, skipped file names beginning with semicolon(;) - Not common for file names but possible - Fixed that.
Last edited by sst on 23 Jul 2018 08:03, edited 3 times in total.

Squashman
Expert
Posts: 4486
Joined: 23 Dec 2011 13:59

Re: Context Menu options using CMD.exe or Powershell

#7 Post by Squashman » 22 Jul 2018 21:56

sst wrote:
22 Jul 2018 21:23
When I was testing the menu, on one particular directory I couldn't get it to work, nothing was in clipboard, then I saw that clip.bat file in the directory, So I decided to first change the current directory to %SystemRoot%\system32 to be safe.
Couldn't you have just defined the full path to CLIP.EXE instead of doing a change directory?

Or use the NoDefaultCurrentDirectoryInExePath variable to keep it from finding any programs in the current directory?

sst
Posts: 93
Joined: 12 Apr 2018 23:45

Re: Context Menu options using CMD.exe or Powershell

#8 Post by sst » 22 Jul 2018 22:53

Squashman wrote:
22 Jul 2018 21:56
Couldn't you have just defined the full path to CLIP.EXE instead of doing a change directory?

Or use the NoDefaultCurrentDirectoryInExePath variable to keep it from finding any programs in the current directory?
NoDefaultCurrentDirectoryInExePath causes cmd to use %PATH% instead of .;%PATH% still there in no guarantee that other software have not added own directory to the start of the path list.
Providing the full path is another option but I have to it for certutil.exe and find.exe as well, The line will get a little more longer but that's not a problem.

I thought about this before and I couldn't find any potential issue changing directory to system32 as the script will not attempt to write anything to disk so even if UAC is disabled it causes no harm, besides that, the user can easily right click on any of the files or directories inside %SystemRoot% and executes the command so windows or system32 will automatically become the current directory even if I don't do it myself.

I can do it as you said by providing full path but I'd like to know the issues or risks you see in changing the current directory to system32

EDIT
Now I see your point (I hope so :D ), for just one executable, yes your are right, I should use full path instead of changing the directory, I just didn't want to make a workaround based on the experience on my own system and doing it only for clip.exe I mainly did it to keep the line shorter and more manageable. If it was a batch file I wouldn't do any thing about it or would have been used full paths for all executables if necessary, But for a normal user it would be very difficult if not impossible to diagnose a registry command, So the shorter solution cd...

Post Reply