Windows RegEdit hides and protects entries - windows

I'd like to reset a file association, created using the "Open With" dialog.
I am on Windows 7 ULT.
I have associated *.part files with VLC.exe an I can see that this association is accomplished by a special "UserChoice" entry under HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.part.
However I can only see this by a special registry search tool that browses the registry keys and values using the Win32 API. I can not see the entry in the "Windows Registry Editor" aka RegEdit.
Regedit indirectly knows this key, because if I try an create a new reg key with the path HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.part RegEdit says that the key .part already exists (which is true).
Also I can delete this key using the cmdline tool reg.exe by:
reg delete "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.part" /f /va
If the key wouldn't exist reg.exe would print out an err msg.
Anyhow the key isn't really actually deleted because I can repeat the command over and over again which indicates that the key is still there. Also in Windows Explorer if I select a *.part file and check the file association it says it's still associated with VLC.exe. So it seems to be recretaed immediately anytime i gtes deleted, which indicates a protection mechanism.
So the simple questions is:
How can I really delete this Registry entry and how can I reset this file association?
And, optionally, how can I make RegEdit display it?
I do not want to change it using the "Open With" dialog, because it would create yet another UserChoice entry under ...FileExt.part
But my goal is to add multiple Commands to .part files that I can select with the right click context menu.
This used to work by simply associating the extension with a progid and adding the commands you want to the ProgId's Shell subkey.
Any one any clues?

For what it's worth...
I finally found the reason why the key HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.part was not displayed in my local RegEdit install.
And why I thus could not modify / delete it using RegEdit.
For whatever reason in HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\ I had reg sub keys with square brackets in their name, like: HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.02]
Since RegEdit seems to use this character as a meta character to denote the end of a key name, it didn't seem to have managed displaying all subsequent subkeys properly. It only showed those that alphabetically came before the first key with a ']' in its name.
I realized this by exporting the whole FileExt key into a reg file.
And I also could remove these junk entries with a reg file.
As for how to delete reg entries using reg files see: How to delete registry subkeys using a .reg file
So now I finally could add the additional entries to the part_auto_file key
and the show up in the context menu and even execute. Cheerio. 🤣

Related

Adding a context menu item in Windows for a specific file extension

I am trying to add a context menu item to a DLL file. The reason is that I have written an application which retracts and deployed a managed DLL file to the GAC. The application is all good, but now I want the ability to right-click a DLL and just click "copy to GAC".
I've tried to follow instructions as per this question: How add context menu item to Windows Explorer for folders but to no avail. When I right click a DLL, nothing new is appearing.
I've also tried the following: https://winaero.com/blog/add-register-dll-context-menu-commands-for-dll-files-in-windows-10/#comment-22928 - ran the reg file but no result as well.
Maybe there's a hardcoded restriction on DLL files for such actions?
Here's my current registry setup:
Any guidance would be appreciated.
The general steps to achieve this are as follows:
Fire up regedit
Identify the ProgID for your extension - go to HKCR\.yourextension and take note of the default value (in your case, dllfile)
Navigate to HKCU\Software\Classes (for user) or HKLM\Software\Classes (for all users)
Look for a matching key (in your case dllfile) - if it's not there, create it
Ensure it has a sub-key called shell
Add a sub-key to shell named as the command you want (refer to image below)
Add a sub-key to your new key called command
Modify the (Default) value to be the command you want to execute. %1 will give you the path of the file in context (remember to wrap it in " due to potential white-space in the path)
You seem to have done all the above, so you may be doing something wrong, as this is my result after a quick sanity test:
So, here are a few things I can think of that would make it behave non-intuitively:
You're adding this to HKLM rather than HKCU - due to how inheritance works, I do believe adding it to HKLM would require a restart, or at best, a shell restart
You've added this to HKCU but your dll requires elevated permissions to access
You have some silly syntax error somewhere ;)
The sample command I used to test this was a good old boring "C:\Windows\notepad.exe" "%1"
This is based on andromeda947's answer here:
If you have admin rights you can use HKEY_CLASSES_ROOT\SystemFileAssociations\.yourextension, which is simpler as it doesn't require an intermediate ProgID.
Option 1: edit the registry manually
add a new key at HKEY_CLASSES_ROOT\SystemFileAssociations\.yourextension\shell\your menu entry text\command creating any keys you need to in that path (if there's not one for .yourextension add it; if there's not one for shell add it; etc)
set the default value for command (the last key you created) to C:\path\to\yourapp.exe "%1"
Option 2: I made a tool to do this
you can download it here. This is an example of how to register notepad.exe as a context menu item for dll files.
regwincontext.exe dll "notepad it" C:\Windows\notepad.exe

Add entry to right-click menu for a specific filetype

What I want
I want to add a custom entry to the menu that appears when right-clicking a .jpg/.jpeg for my program (editing images).
What I tried
I added to HKEY_CLASSES_ROOT\jpegfile\shell a key test, in there a second key command and set the (default) value of that to notepad.exe (just for testing). Because no test entry appeared in the menu, I did the same just unter HKEY_CLASSES_ROOT\Directory where it worked!
The file I click is an JPEG and the default value of HKEY_CLASSES_ROOT.jpg is jpegfile.
(Also tested with txtfile but with no success.)
What did I do wrong to add a custom command to specific filetypes only?
What you did was correct. Possible reasons why it didn't work include:
Windows Update has an annoying tendency in Windows 10 to reset file associations to Windows defaults all the time.
You added this facility to the jpegfile key, but the type .jpg may be associated with a different file-type key.
Go to HKEY_CLASSES_ROOT.jpg and see what the association is (alternatively, type ASSOC .jpg in Command Prompt). If it isn't jpegfile, check what it is, in case you actually want to keep that association.
To give you an example, I have a working right-click menu entry for .png files, which runs the pngout utility on them. I did that by editing the Registry. My current association for .png files is FastStone Image Viewer:
So I changed the shell menu for FastStone's file type key:
And now my right-click menu entry works.

Add explorer context menu item for PDF files from delphi

I have my application written in Delphi XE that works with PDF files. Applicaiton is Win32. On start I would like to ensure that there is my item in explorer context menu for PDF files. I would like to be able to specify whether it should be added for active user only or for all users (with UAC I will need to restart with Admin privileges but thats ok).
I started with How to associate a Delphi program with a file type, but only for the current user? and How to add item to windows explorer content menu in delphi? . I tested it with manual registry editing via regedit and it worked fine for "new" extensions. But for .pdf it is more complicated as it will be most probably already present in the registry.
On my PC the .pdf key is referencing AcroExch.Document . But adding shell/something subkey to the AcroExch.Document key is not working because it has CurVer subkey referencing to AcroExch.Document.7. However another PC with another verison of Acrobat had this names a little different. It is no problem for me to follow the CurVer reference but is that a correct approach? And what about situation where no PDF reader is installed, how should I name my keys so Acrobat won't overwrite them when installed?
But more pressing matter is in which root should I put my keys? How to associate a Delphi program with a file type, but only for the current user? is mentioning HKLM (Local Machine) and HKCU (Current user). Its seems rather straightforward but I am unable to set values in HKLM from Delphi. Strangely I can create keys:
var reg:TRegistry;
key := '\Software\Classes\'+keyname+'\shell\'+name+'\command';
reg.CreateKey(key);
but I am getting Access Denied when trying to write the actual value:
reg.OpenKey(key,false);
reg.WriteString('',command);
I am getting the same Access Denied exception even on WinXP, no matter if the applicaiton is running as Admin (Win7), I even tried to set permissions (Everyone full control) for the key via regedit (I can edit the value via regedit without problems). I tried creating the registry with different access modes, all with no luck:
reg := TRegistry.Create(KEY_WRITE or KEY_WOW64_64KEY);
reg := TRegistry.Create(KEY_ALL_ACCESS or KEY_WOW64_64KEY);
reg.Access := KEY_ALL_ACCESS;
reg.Access := KEY_WRITE or KEY_WOW64_64KEY;
reg.Access := KEY_ALL_ACCESS or KEY_WOW64_64KEY;
With HKCU everything works fine.
So I tried writing into HKEY_CLASSES_ROOT and it works and actually puts the keys exactly where I want (into HKLM) if running as Admin. But according to http://msdn.microsoft.com/en-us/library/windows/desktop/ms724475.aspx
The HKEY_CLASSES_ROOT (HKCR) key contains file name extension associations and COM class registration information such as ProgIDs, CLSIDs, and IIDs. It is primarily intended for compatibility with the registry in 16-bit Windows.
I do not like the note about the primary purpose being compatibile with 16-bit Windows. And the actual conditions where the changes will be written is more complicated than I would like.
So basically I have these questions:
What is the advantage of using AcroExch.Document and CurVer instead of pointing directly to AcroExch.Document.7? And what are the "best manners" when adding my keys into this structure? What about the case when the .pdf is not yet associated with anything?
Where should I put my keys and why I am not able to write into HKLM?
Edit:
The problem with Access Denied when writing to HKLM was caused by my error. I did use in previous code openKeyReadOnly and I did not notice that it will swtich the Access property to readonly for all subsequent calls.
To answer your other question, if Adobe is not installed yet then obviously the PDF keys will likely not exist in the Registry yet so you would have to create your own .pdf and ProgID keys so that you can attach your Shell command on it. If Adobe is installed afterwards, it is likely going to wipe out your keys and replace them with its own, so you would have to recreate your Shell command within Adobe's key structure. Your app can query the Registry to check for that condition periodically, such as at startup.
You have asked two separate questions. Since I know the answer to one and not the other, I'm going to answer just one. For future reference, I do recommend that you ask a single question at a time.
Where should I put my keys?
You are correct in discerning that you should not use HKCR. The documentation for HKCR says:
Class registration and file name extension information is stored under
both the HKEY_LOCAL_MACHINE and HKEY_CURRENT_USER keys. The
HKEY_LOCAL_MACHINE\Software\Classes key contains default settings that
can apply to all users on the local computer. The
HKEY_CURRENT_USER\Software\Classes key contains settings that apply
only to the interactive user. The HKEY_CLASSES_ROOT key provides a
view of the registry that merges the information from these two
sources. HKEY_CLASSES_ROOT also provides this merged view for
applications designed for previous versions of Windows.
....
If you write keys to a key under HKEY_CLASSES_ROOT, the system stores
the information under HKEY_LOCAL_MACHINE\Software\Classes. If you
write values to a key under HKEY_CLASSES_ROOT, and the key already
exists under HKEY_CURRENT_USER\Software\Classes, the system will store
the information there instead of under
HKEY_LOCAL_MACHINE\Software\Classes.
So, it is reasonable to use HKCR for reading, but for writing you typically need to exert control over whether to write to HKLM or HKCU. And that means that you cannot write to HKCR.
So, write to HKLM\Software\Classes for machine-wide settings, and HKCU\Software\Classes for user-specific settings.
Note that in Windows 7 and later neither of these keys is redirected and so you do not need to worry about using KEY_WOW64_64KEY. However, in Vista and XP64, and the equivalent server editions, these keys are redirected and reflected. Which means that it might be prudent to use KEY_WOW64_64KEY.

How to add an entry in the Windows context menu for files with a specific extension?

I know that many questions are asked about how customizing the shell context menu, but what I've tried yet doesn't work so I'm adding a new question.
I'd like to add an entry "Open with Log Viewer" in the context menu when right-clicking on files with ".log" extension, to not change the default application associated with .log files (notepad) but allow the user to choose a custom application to open them.
To do this, I opened the registry key HKEY_CLASSES_ROOT\.log, and added some keys shell\OpenWithLogViewer\command with the correct values, but the entry is not displayed when I right-click on a file with .log extension.
Would you know how to fix this?
The key HKEY_CLASSES_ROOT\.log has for default value txtfile, and contains a subkey called PersistentHandler. Can this subkey be the origin of the problem?
Add another registry key (e.g. HKEY_CLASSES_ROOT\logfile), create the shell structure below that key and change the default value of the .log key to logfile. One way to do this is by saving the following lines to a .reg file and merging that file into the registry.
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\.log]
#="logfile"
[HKEY_CLASSES_ROOT\logfile]
[HKEY_CLASSES_ROOT\logfile\shell]
#="OpenWithLogViewer"
; make OpenWithLogViewer the default action
[HKEY_CLASSES_ROOT\logfile\shell\OpenWithLogViewer]
#="Open with &Log Viewer"
; set label and access key
[HKEY_CLASSES_ROOT\logfile\shell\OpenWithLogViewer\command]
#="\"C:\\path\\to\\logviewer.exe\" %1"
This separates the type (logfile) from the extension (.log). That way you can define the possible actions for a type in one place and associate arbitrary extensions with that type.
Note that you can also define this on a per-user basis by using HKEY_CURRENT_USER\Software\Classes instead of HKEY_CLASSES_ROOT. User entries take precedence over system entries. This is useful when you want to change file associations or add custom actions for your own user, but don't have admin privileges on the system.
If you want to add a entry for a file extension you don't "own" and you never want to be the default action then you can use the SystemFileAssociations key:
[HKEY_CLASSES_ROOT\SystemFileAssociations\.log\shell\mycommand]
#="My Command"
[HKEY_CLASSES_ROOT\SystemFileAssociations\.log\shell\mycommand\command]
#="\"c:\\path\\myapp.exe\" \"%1\""
To deal proactively with the consequences of a change to default programs, you can use HKEY_CLASSES_ROOT\SystemFileAssociations to register verbs and other association information. Due to their location after the ProgID in the association array, these registrations are lower priority. These SystemFileAssociationsregistrations are stable even when users change the default programs, and provide a location to register secondary verbs that will always be available for a particular file type.
This key is available on Windows XP and higher...

Windows 7 file extension association

I am referring specifically to windows 7.
I have code that associates a certain extension with my application as proposed by webJose on the following page:
What registry keys are responsible for file extension association?
(However i correctly write to HKEY_CURRENT_USER\Software\Classes instead of HKEY_CLASSES_ROOT as suggested)
The above works initially, or if there are no other programs associated with the extension. However after using the Windows 7 built-in "Choose default program..." (found under the file-right-click context menu under "Open with") it re-associates the extension with whatever new program you choose.
What happens at this point is that "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\\UserChoice" is changed by the system, and so the newly selected program takes over.
Running the above code, to regain control over the extension will not work. The only way to regain control, is by either:
Editing the UserChoice -> Progid value, which is not allowed (neither programmatically nor using regedit.exe - access denied).
Or deleting the UserChoice value and making sure your application is the first in the MRUList value under \OpenWithList (this can be achieved using regedit.exe but not programmatically)
My question is: Is there a way to achieve this programmatically? What registry values can be changed to regain control of an extension, after is associated with another program?
I know it might seem obvious that if a user through explorer sets the associated application to an extension, that it would be expected to do it the same way again to re-associate the extension to a different application.
The problem however is I have a button in my application that uses the above mentioned code to check for extension association with my application. Unfortunately with the above situation, my application displays a message confirming that the extension is already successfully associated when its not! So is there a way around this?
Deleting UserChoice should revert the default program to the standard file association keys (which starts with the ProgID in HKCU). Barring that you could also delete OpenWithList, which would be reverting with extreme prejudice.
Edit:
Check out Registry Key Security and Access Rights on MSDN, particularly the RegSetKeySecurity function. Remember that you'll need to grant yourself administrative control to the key before you can delete it.
Well regarding file assoc in Window 7 a new 'problem' araised.
It's one of this: You've to fight for your rights.
Assuming you like to run
REG.exe DELETE "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.mov\UserChoice" /f /va
You'll get ACCESS DENYED.
When you check security setting of the key in Regedit 'UserChoice' you'll see that there's a setting windows made for you, to deny 'set' for the current user. Well you maybe change/delete this setting in regedit and now you can delete UserChoice.
However for programmer/scripters that setting is a little bitchy since there are now real tools to set ACLs in the registry. However here some workaround that at allows to delete keys with ACCESS DENYED (of course this only works incase you've the right to change permissions):
ResetMovAssoc.cmd
::create 'empty.hiv'
REG ADD "HKCU\emptyKey" /f
REG SAVE "HKCU\emptyKey" empty.hiv /y
#REG DELETE "HKCU\emptyKey" /f >nul
::^-note you can add #[...] >nul to the other entries as well to run them quite
:: Delete Reg key by replacing it with an empty hiv
REG RESTORE "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.mov" empty.hiv
del empty.hiv
To summarize this the major thing here is REG RESTORE + Registry hive file containing just and empty key.
In Regedit that'll equivalent to Import' with a just an empty registry structure file (Note: that's a hive file and not a *.reg file).
My solution was not to try to delete the UserChoice key (only administrators can do it), but to delete the key the ProgId is pointing to. If the user made a choice in the past the ProgId has a value like Applications\*.exe. The non-admin can delete the key in a batch:
REG DELETE HKCR\Applications\*.exe /f
This might be a bit of a hack, but worked for me.
Also on Windows 10, this command can't work:
Reg.exe delete "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.m4v" /f
The solution is to delete the SID key by running a BAT file under TrustedInstaller (with NSudo, PowerRun, etc):
for /f "delims=\ tokens=2" %%A in ('reg query hku ^| findstr /i "S-1-5-21-" ^| findstr /v /i "_Classes"') do set SID=%%A
Reg.exe delete "HKU\%SID%\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.m4v" /f
P.S.: Thanks to #SecurityAndPrivacyGuru for sharing the SID detection command.

Resources