Search code examples
windowssdkregistry

How to register a windows file extension via the sdk on window 10.x


Note: this question is not about dart but the windows registry.

I've implemented a library and tooling (called dcli) to write cli apps in the dart language.

When a user types the name of a dart script on the command line I need windows to start dcli and pass the dart script and any command line arguments.

e.g.

hellow.dart a b c

Will result in the following command being run

dcli.bat hellow.dart a b c

I need to do this via the 'C' registry api (I'm calling the registry api from dart using its foreign function interface (ffi) which allows it to call C entry points). This part of the problem is already solved and I can successfully add registry keys from dart.

My problem is knowing what registry settings to create because, particularly with the advent of windows 10, the documentation is a mess.

This is my rather poor attempt so far.


     // create a ProgID for dcli 'noojee.dcli'
    regSetString(HKEY_CURRENT_USER, 
         r'\Software\Classes\noojee.dcli',
        defaultRegistryValueName, 'dcli');

    // associate the .dart extension with dcli's prog id
    regSetString(HKEY_CURRENT_USER, r'\Software\Classes\.dart',
        defaultRegistryValueName, 'noojee.dcli');

    regSetString(HKEY_CURRENT_USER, 
           r'SOFTWARE\Classes\.dart\OpenWithProgids',
        'noojee.dcli.dart', '');

    // this path doesn't look correct
    regSetExpandString(
        HKEY_CURRENT_USER,
        r'dcli\shell\open\command',
        defaultRegistryValueName,
        'c:\path\to\dcli.bat  %1 %2 %3 %4 %5 %6 %7 %8 %9');


    regSetString(
        HKEY_CURRENT_USER,
r'SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.dart\OpenWithList',
        'a',
        'dcli.bat');

    regSetString(
        HKEY_CURRENT_USER,
        r'SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.dart',
        'MRUList',
        'a');

    regSetNone(
        HKEY_CURRENT_USER,
        r'SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.dart\OpenWithProgids',
        'noojee.dcli');

One thing that confuses me is the use of HKEY_CLASSES_ROOT. The doco appears to say that it is read only but then goes on to show examples creating keys under it.

I have the added complication that vscode with the dart-code extension likes to add its own association (which makes no sense) and I need to override this if it exists but ideally make it an alternative on the explorer menu.


Solution

  • Thanks to @Anders I arrived at the following:

    Note: defaultRegistryValueName is just an empty string ''.

    
     const progIdPath = r'Software\Classes\.dart\OpenWithProgids';
    
      if (regKeyExists(HKEY_CURRENT_USER, progIdPath)) {
        regDeleteKey(HKEY_CURRENT_USER, progIdPath);
      }
    
      regCreateKey(HKEY_CURRENT_USER, progIdPath);
    
      regSetString(HKEY_CURRENT_USER, progIdPath, 'noojee.dcli', '');
    
      const commandPath = r'Software\Classes\noojee.dcli\shell\open\command';
      if (regKeyExists(HKEY_CURRENT_USER, commandPath)) {
        regDeleteKey(HKEY_CURRENT_USER, commandPath);
      }
    
      regCreateKey(HKEY_CURRENT_USER, commandPath);
      regSetString(
          HKEY_CURRENT_USER,
          commandPath,
          defaultRegistryValueName,
          '"${DCliPaths().pathToDCli}" '
          '"%1"%*');
    

    The only issues is that the %* doesn't seem to be doing anything useful. From the doco I've found it should expand any no. of args (e.g. more than 9) however I only ever get 8 (as %1 is the command itself) and "%1" yeilds the same result as "%1"%*