New
#40
Sorry. I'll try again.
Root_Directory_Desktop_Folder_RegFilesWin10.zip
Hey Brink can you show or point me to a manual that explains what the corresponding numbers are for -WindowStyle? You have the number 1. Where did you find that and what does 1 mean? I want to know what the corresponding numbers are for all the possible options. Hidden = what.... 0?
Just a great job you did. Also, if you get a chance to post I'll send you my own version of this that reopens explorer to the folder or file you activated the context menu from.
@Brink;2222436; (I don't know how this forum's "mention" syntax works, so I quoted a post of yours below just in case.)
I've posted a code revision to this thread once before, but I believe I've found a better way of doing things: format strings.
Also, I'm also now in the habit of capitalizing internal cmd.exe commands, and I made some changes to the spacing to make it easier to look at. Here's what I changed the registry files to include...
Code:[HKEY_CLASSES_ROOT\DesktopBackground\shell\CommandPrompt\shell\cmd1\command] @="cmd /k CD /D \"%V\"" [HKEY_CLASSES_ROOT\Directory\shell\CommandPrompt\shell\cmd1\command] @="cmd /k CD /D \"%L\"" [HKEY_CLASSES_ROOT\Directory\Background\shell\CommandPrompt\shell\cmd1\command] @="cmd /k CD /D \"%V\"" [HKEY_CLASSES_ROOT\Drive\shell\CommandPrompt\shell\cmd1\command] @="cmd /k CD /D \"%L\""
I'm not entirely sure whyPUSHD
was used prior, but I think it's because it was the best way to navigate to the proper directory in an admin prompt andPUSHD
was used on the non-admin part for consistency. But since that's no longer necessary,CD /D
should be used.
Code:[HKEY_CLASSES_ROOT\DesktopBackground\shell\CommandPrompt\shell\cmd2\command] @="cmd /c SET/P=\"%V\" <NUL | powershell -NoP -W 1 -NonI -NoL \"SaPs cmd -Args ('/k {0}CD /D {0}{1}{0}{0}' -f [char]34,[string]$Input) -Verb RunAs\"" [HKEY_CLASSES_ROOT\Directory\shell\CommandPrompt\shell\cmd2\command] @="cmd /c SET /P=\"%L\" <NUL | powershell -NoP -W 1 -NonI -NoL \"SaPs cmd -Args ('/k {0}CD /D {0}{1}{0}{0}' -f [char]34,[string]$Input) -Verb RunAs\"" [HKEY_CLASSES_ROOT\Directory\Background\shell\CommandPrompt\shell\cmd2\command] @="cmd /c SET /P=\"%V\" <NUL | powershell -NoP -W 1 -NonI -NoL \"SaPs cmd -Args ('/k {0}CD /D {0}{1}{0}{0}' -f [char]34,[string]$Input) -Verb RunAs\"" [HKEY_CLASSES_ROOT\Drive\shell\CommandPrompt\shell\cmd2\command] @="cmd /c SET /P=\"%L\" <NUL | powershell -NoP -W 1 -NonI -NoL \"SaPs cmd -Args ('/k {0}CD /D {0}{1}{0}{0}' -f [char]34,[string]$Input) -Verb RunAs\""
First of all, instead of usingECHO | SET /P=""
, I'm now usingSET /P="" <NUL
. It does the same thing, but without piping. Note that<NUL
means usingNUL
as stdin, opposed to>NUL
which redirects output toNUL
.
Second, I'm not sure why I was invoking an extra cmd.exe process previously by using/c
andSTART
instead of just using/k
. I'm thinking it might have been a mistake on my part since trying to work around the quote parsing issue tends to fry my brain. So that's gone.
And finally, my new strategy is to pass a single argument toSaPs
(Start-Process) in the form of a format string:
('/k {0}CD /D {0}{1}{0}{0}' -f [char]34,[string]$Input)
{0}
refers to the first item listed after the-f
(format) operator, which is[char]34
(a quotation mark).
{1}
refers to the second item listed after the-f
(format) operator, which is[string]$Input
(the input powershell received from stdin, which is the path piped out ofSET /P
).$Input
has to be converted to a string for this to work correctly, which is why it's casted to[string]
. (In the old code,$([char]34+$Input+[char]34)
, the string conversion happened automatically as a consequence of joining it with the quote characters.)
As a sidenote, using a formatted string to pass quotes via[char]34
gets around the quote parsing issue when invoking powershell from cmd. You would need to use triple-quotes for the equivalent functionality.
Here's what the format string would look like:
('/k \"\"\"CD /D \"\"\"{0}\"\"\"\"\"\"' -f [string]$Input)
Because this is approach is messy and hard to look at, I prefer using[char]34
as a format item.
https://learn.microsoft.com/en-us/do...tframework-4.0
Last edited by jungf; 09 Jun 2023 at 03:45.
@jungf
None of these methods will work on a folderpath string that contains non ASCII character symbols. Especially on slower computers, the method outlined in this tutorial also causes a noticeable delay with an intermediate window flash (i.e. a window that closes immediately after it opens) before the command window opens, as it relies on PowerShell to do its job. And when you try to customize your command window by choosing e.g. different colors and fonts, any changes you made to it will be lost after you close it. So, I made a complete solution to all of these problems. You can choose between adding an option to open the command window here, either as a standard user or as an admin, and you can also do the same for PowerShell 5. It uses the Shift + right-click (extended) context menu, but you can adjust the code to make it use the normal right-click context menu instead if that's what you prefer to use. See my post here:
Open command window here as administrator - Add in Windows 10
I'm well aware of the window flash, that really can't be helped without running something like a vbs script. I'd prefer the window flash over relying on external files, especially since the winmgmt service that vbs scripts rely upon is known to break occasionally.
As for the non-ASCII symbols, I was not aware of this. I'll try to come up with a fix.
EDIT: Well I'm able to get Windows PowerShell to interpret the path correctly by setting CHCP 65001 before the pipe, but nothing I've tried makes it pass the string back out to a new admin cmd successfully, despite messing with things like $OutputEncoding and using .NET methods to convert the string's encoding to the Windows Codepage. How frustrating.
- - - Updated - - -
Ugly as hell but it works:
It has to launch cmd from an elevated PowerShell, which unfortunately means it has to launch PowerShell twice, though the second launch is hidden.Code:[HKEY_CLASSES_ROOT\DesktopBackground\shell\CommandPrompt\shell\cmd2\command] @="cmd /c CHCP 65001>NUL && SET /P=\"%V\" <NUL | powershell -NoP -W 1 -NonI -NoL \"SaPs powershell -Args '-NoP','-W',1,'-NonI','-NoL',('SaPs cmd -WorkingDirectory ([WildcardPattern]::Escape(''{0}''))' -f $Input.Replace('''','''''')) -Verb RunAs -WindowStyle 1\"" [HKEY_CLASSES_ROOT\Directory\shell\CommandPrompt\shell\cmd2\command] @="cmd /c CHCP 65001>NUL && SET /P=\"%L\" <NUL | powershell -NoP -W 1 -NonI -NoL \"SaPs powershell -Args '-NoP','-W',1,'-NonI','-NoL',('SaPs cmd -WorkingDirectory ([WildcardPattern]::Escape(''{0}''))' -f $Input.Replace('''','''''')) -Verb RunAs -WindowStyle 1\"" [HKEY_CLASSES_ROOT\Directory\Background\shell\CommandPrompt\shell\cmd2\command] @="cmd /c CHCP 65001>NUL && SET /P=\"%V\" <NUL | powershell -NoP -W 1 -NonI -NoL \"SaPs powershell -Args '-NoP','-W',1,'-NonI','-NoL',('SaPs cmd -WorkingDirectory ([WildcardPattern]::Escape(''{0}''))' -f $Input.Replace('''','''''')) -Verb RunAs -WindowStyle 1\"" [HKEY_CLASSES_ROOT\Drive\shell\CommandPrompt\shell\cmd2\command] @="cmd /c CHCP 65001>NUL && SET /P=\"%L\" <NUL | powershell -NoP -W 1 -NonI -NoL \"SaPs powershell -Args '-NoP','-W',1,'-NonI','-NoL',('SaPs cmd -WorkingDirectory ([WildcardPattern]::Escape(''{0}''))' -f $Input.Replace('''','''''')) -Verb RunAs -WindowStyle 1\""
-WorkingDirectory is used to set the initial cmd directory, but this only works from an elevated PowerShell. Unfortunately, SaPs (Start-Process) will interpret this path with wildcard characters enabled, so it's wrapped in [WildcardPattern]::Escape.
Lastly, because we want it interpreted literally, it's wrapped in apostrophes, but because a path can include those, they have to be escaped, leading to the rather ugly $Input.Replace('''','''''')
Thus far I haven't been able to find a directory this fails on though.
Last edited by jungf; 09 Jun 2023 at 02:58.