Reputation: 4251
I am trying to find a way to open a non-txt file (in this case, the hosts file) in the default text editor using PowerShell.
I made some progress after seeing this Reddit post, but the $txt_editor
result always returns Notepad.exe, even though Notepad++ is my default editor for txt files.
$hosts_file = "$env:windir\System32\drivers\etc\hosts"
$txt_editor = ((Get-ItemProperty -Path 'Registry::HKEY_CLASSES_ROOT\txtfile\shell\open\command').'(Default)').trimend(" %1")
Start-Process -FilePath $txt_editor -Verb Runas -ArgumentList $hosts_file
This also returns Notepad.exe:
(Get-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.txt\OpenWithList' -Name a).a
If I look at the above location in Registry Editor, I do see Notepad++ listed with the key d
, but I don't know how to tell from only looking at a Registry key what the default text editor is, because the two solutions I saw in Reddit do not work.
I am using Windows 10, and the solution I am looking for will return the actual default text editor file location, so that it can be used to open a file as shown above.
This question still has not received an answer to my actual question, since the only answer doesn't show how to open a non-txt file using the configured default text file editor.
Update: I'm now trying to replicate this on Windows 11, and the registry key HKEY_CLASSES_ROOT\txtfile\shell\open\command
doesn't exist. I need a solution that will include a solution for this aspect as well, if the registry is involved. I configured Notepad++ as the default, and a key was created at HKEY_CLASSES_ROOT\txtfilelegacy\shell\printto\command
.
Upvotes: 6
Views: 16229
Reputation: 13460
Beginning with Windows 8, you will find your file type associations in the registry at HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\<FILE_TYPE>\UserChoice
. There you will find a ProgId
. Get it:
$ProgId = Get-ItemPropertyValue -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.txt\UserChoice -Name ProgId
With the ProgId
you can look for the shell command in HKCR
:
$Command = Get-ItemPropertyValue -Path Registry::HKEY_CLASSES_ROOT\$ProgId\shell\open\command -Name '(Default)'
In the command, replace %1
by your text file, e. g.:
$Command = $Command -replace '%1', 'C:\Windows\System32\drivers\etc\hosts'
You can then execute the command:
cmd /c $Command
This works with notepad++.exe
.
Be aware, that not all programs directly register with a shell command. Some (like notepad.exe
(no ++)) have a DelegateExecute
value that contains a GUID. Afaik, you have to look that up by querying a DLL. As a workaround, you may still be able to guess the shell command by just appending the path of the text file. So, you could use the following logic to get your shell command:
$textfile = 'C:\Windows\System32\drivers\etc\hosts'
if ($Command.Contains('%1')) {
$Command = $Command -replace '%1', $textfile
} else {
$Command += " `"$textfile`""
}
You can then execute the command:
cmd /c $Command
This will at least work for notepad++.exe
and for notepad.exe
.
Upvotes: 1
Reputation: 4251
Using the information in @FoxDeploy's answer, I was able to construct a working PowerShell function.
function Edit-HostsFile {
# Self-elevate if required
if (-Not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')) {
if ([int](Get-CimInstance -Class Win32_OperatingSystem | Select-Object -ExpandProperty BuildNumber) -ge 6000) {
$hosts_file = "$env:windir\System32\drivers\etc\hosts"
# Get the configured application default for editing .txt files.
$txt_app = ((Get-ItemProperty -Path Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.txt\UserChoice -Name ProgId).ProgId)
$txt_editor = ((Get-ItemProperty -Path Registry::HKEY_CLASSES_ROOT\$($txt_app)\shell\open\command).'(Default)').replace(' "%1"', '')
# Open the hosts file in the editor.
Start-Process -FilePath $txt_editor -Verb Runas -ArgumentList $hosts_file
}
}
}
I hadn't gotten a working solution using the information in the answer when I tried a few years ago, but I was able to figure it out after trying again. A more complete solution with code would have been helpful, but it didn't take too long to create.
Upvotes: 1
Reputation: 13537
The Start command (which is an alias for Start-Process
) will launch any file in its default editor.
start .\MyCoolbmp.bmp
#Opens in MSPaint
start .\SomeNotes.txt
#Opens in Notepad
start .\SomeJason.json
#Opens in Visual Studio, go ahead and grab a coffee...
If I had to guess why yours isn't working, it's that the registry key you gave is the one used for the system, while the user's default editor is stored, from Windows 7 and up, within the HKEY_CURRENT_USER hive instead, at this path Windows\CurrentVersion\Explorer\FileExts\.txt\UserChoice'
.
Here's the pertinent values:
$txtKey = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.txt\UserChoice"
Get-ItemProperty -Path $txtKey | tee-object -variable txtPath
Hash : noCJnt8yX5Y=
ProgId : VSCode.txt
This ties over to info found within HKCR:\Applications, where the true path can be found.
get-itemproperty Registry::\HKEY_CLASSES_ROOT\$($txtPath.ProgId)\shell\open\command
(default) : "C:\Program Files\Microsoft VS Code\Code.exe" "%1"
#...
If you grab that (Default) value, now you've got the true path for the editor associated with text files.
To read a bit more on the topic, this blog post is pretty good and goes in detail into how associations work.
Upvotes: 11