Search code examples
delphiregistryfile-associationdelphi-10.4-sydney

State of the art way to register/unregister a file type with my own application for the current user in Windows10?


I have found several methods to register a file type with my own application (double-clicking that file type in Windows Explorer looads that file in my application). Several are very old and seem to be deprecated, others are unclear and lack practical usage examples and thus are prone to misunderstandings.

  1. @AndreasRejbrand has published an accepted solution here: How to associate a program with a file type, but only for the current user?
    a) There is no complimentary way to UNREGISTER the file type.
    b) It is not clear what 'MyAppDataFile' means.
    c) There are no practical usage examples.

  2. The DSiWin32 library contains the methods DSiRegisterUserFileAssoc and DSiUnregisterUserFileAssoc:
    a) procedure DSiRegisterUserFileAssoc(const extension, progID, description, defaultIcon, openCommand: string);
    aa) It is not clear what the progID parameter means.
    ab) It is not clear how to pass the defaultIcon parameter.
    ac) It is not clear how to pass the openCommand parameter.
    b) procedure DSiUnregisterUserFileAssoc(const progID: string);
    ba) It is not clear what the progID parameter means and how to format it.
    c) it would be nice to have a practical usage example.

BTW, this is the code from @AndreasRejbrand:

with TRegistry.Create do
  try
    RootKey := HKEY_CURRENT_USER;
    if OpenKey('\Software\Classes\.myfile', true) then
      WriteString('', 'MyAppDataFile');
    if OpenKey('\Software\Classes\MyAppDataFile', true) then
      WriteString('', 'My Very Own Text File Type');
    if OpenKey('\Software\Classes\MyAppDataFile\DefaultIcon', true) then
      WriteString('', 'C:\WINDOWS\notepad.exe');
    if OpenKey('\Software\Classes\MyAppDataFile\shell\open\command', true) then
      WriteString('', 'C:\WINDOWS\notepad.exe "%1"');
  finally
    Free;
  end;
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0);

Can anyone provide CLEAR "fool-proof" practical usage examples for both approaches? Which one is better?

EDIT: With "practical USAGE examples" I mean: A procedure/function with example parameters.


Solution

  • It's not clear to me what the OP is actually asking, but in the comments there are a few requests for clarifications and I am not able to fit such explanations in comments, so instead I create a (possibly temporary) CW answer here.

    Suppose you want all files with extension .stext to be called Super Text File in Explorer, be opened with C:\Program Files\Super Editor\superedit.exe, and have the icon C:\Program Files\Super Editor\docicon.ico, then you would use the following code:

    with TRegistry.Create do
      try
        RootKey := HKEY_CURRENT_USER;
        if OpenKey('\Software\Classes\.stext', true) then
          WriteString('', 'SuperTextFile');
        if OpenKey('\Software\Classes\SuperTextFile', true) then
          WriteString('', 'Super Text File');
        if OpenKey('\Software\Classes\SuperTextFile\DefaultIcon', true) then
          WriteString('', 'C:\Program Files\Super Editor\docicon.ico');
        if OpenKey('\Software\Classes\SuperTextFile\shell\open\command', true) then
          WriteString('', '"C:\Program Files\Super Editor\superedit.exe" "%1"');
      finally
        Free;
      end;
    SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0);
    

    The SuperTextFile string works as a connection between the file extension part and the file type part. You could call it jmkrfnjk if you like instead.

    If, instead, you want to open the files in Notepad, use the path to notepad.exe instead in the last WriteString.

    This might not be the most sophisticated approach (probably it is the Win 9x approach), but it still works, doesn't it? And I would be surprised if it will not continue to be valid for the entire future of the Win32 desktop platform.

    The DSiRegisterUserFileAssoc routine does exactly the same thing as the code above, so both methods are exactly equivalent.

    For all details on the state of the art, see the documentation.