Search code examples
windowswolfram-mathematicaregistryfile-associationmathematica-frontend

Creating Palette for switching .NB-associations between installed versions of Mathematica


I would like to create a palette for switching .NB-file associations between installed versions of Mathematica under Windows.

At this moment I have developed the following code for enumerating installed versions of Mathematica and switching between them:

1) Getting list of names of system registry keys of installed versions of Mathematica:

installedVersions = 
 Select[Developer`EnumerateRegistrySubkeys["HKEY_CLASSES_ROOT"], 
  StringMatchQ[#, "Mathematica.NB." ~~ ___] || # === 
     "MathematicaNB" &]

=> {"Mathematica.NB.7.0.1.1213965", "MathematicaNB"}

2) Function that adds command line options -b (disables the splash screen) and -directlaunch (disables the mechanism which launches the most recent Mathematica version installed) to the command line string for launching Mathematica FrontEnd in the system registry:

customizeOpenCommand[id_String] := Module[{value},
   value = 
    Cases[Developer`ReadRegistryKeyValues[
      "HKEY_CLASSES_ROOT\\" ~~ id ~~ "\\shell\\open\\command"], 
     Verbatim[Rule][Null, 
       val_String /; 
        StringFreeQ[val, " -b -directlaunch "]] :> (Null -> 
        StringReplace[val, 
         path__ ~~ "\\Mathematica.exe\"" ~~ __ ~~ "\"%1\"" :> 
          path ~~ "\\Mathematica.exe\" -b -directlaunch \"%1\""])];
   Developer`WriteRegistryKeyValues[
    "HKEY_CLASSES_ROOT\\" ~~ id ~~ "\\shell\\open\\command", value]];

This function can be used as follows:

customizeOpenCommand /@ installedVersions

3) Function for getting current .NB-file association:

Null /. Developer`ReadRegistryKeyValues["HKEY_CLASSES_ROOT\\.nb"]

4) Buttons for switching between all Mathematica versions installed (but I think it probably could be implemented better using Dynamic and SetterBar):

Column[Button[
    Row[{"Associate .NB-files with ", Style[#, Bold], " (", 
      First@Cases[
        Developer`ReadRegistryKeyValues["HKEY_CLASSES_ROOT\\" ~~ #], 
        Verbatim[Rule][Null, str_String] :> str], ")"}], 
    Developer`WriteRegistryKeyValues["HKEY_CLASSES_ROOT\\.nb", 
     Null -> #], Alignment -> Left] & /@ installedVersions]

In addition to the above here is the command which disables sharing of preferences between different Mathematica versions installed (by default all installed versions use one file for storing the FrontEnd settings):

SetOptions[$FrontEnd, "VersionedPreferences" -> True]

So my problem is:

How to create and install a small Palette which will dynamically display the current file associations for .NB-files and will allow to switch between them by clicking a button? I think it probably can be implemented just with SetterBar but I still unexperienced with Dynamic and palette creation.


Solution

  • Up to this moment I have come to the following solution:

    CreatePalette@
      Framed[DynamicModule[{b, installedVersions}, 
        Dynamic[Column[
          Join[{Style["Associate .NB-files with:", Bold], 
            SetterBar[
             Dynamic[val, 
              Function[{v, e}, 
               Developer`WriteRegistryKeyValues["HKEY_CLASSES_ROOT\\.nb", 
                Null -> v]; 
               e = Null /. 
                 Developer`ReadRegistryKeyValues[
                  "HKEY_CLASSES_ROOT\\.nb"], HoldRest], 
              Initialization -> (installedVersions = 
                 Select[Developer`EnumerateRegistrySubkeys[
                   "HKEY_CLASSES_ROOT"], 
                  StringMatchQ[#, "Mathematica.NB." ~~ ___] || # === 
                     "MathematicaNB" &]; 
                If[StringFreeQ[
                    value = 
                     Null /. 
                      Developer`ReadRegistryKeyValues[
                       "HKEY_CLASSES_ROOT\\" ~~ # ~~ 
                        "\\shell\\open\\command"], " -b -directlaunch "], 
                   Developer`WriteRegistryKeyValues[
                    "HKEY_CLASSES_ROOT\\" ~~ # ~~ 
                     "\\shell\\open\\command", 
                    Null -> 
                     StringReplace[value, 
                      path__ ~~ "\\Mathematica.exe\"" ~~ __ ~~ "\"%1\"" :>
                        path ~~ 
                        "\\Mathematica.exe\" -b -directlaunch \"%1\""]]] \
    & /@ installedVersions)], installedVersions, 
             Appearance -> "Vertical"]}, 
           If[Last@Last@Options[$FrontEnd, "VersionedPreferences"] === 
              False && 
             b == True, {Button[
              Pane[Style[
                "This FrontEnd uses shared preferences file. Press this \
    button to set FrontEnd to use versioned preferences file (all the \
    FrontEnd settings will be reset to defaults).", Red], 300], 
              AbortProtect[
               SetOptions[$FrontEnd, "VersionedPreferences" -> True]; 
               b = False]]}, {}]], Alignment -> Center], 
         Initialization :> 
          If[! Last@Last@Options[$FrontEnd, "VersionedPreferences"], 
           b = True, b = False]]], FrameMargins -> {{0, 0}, {0, 5}}, 
       FrameStyle -> None];
    

    This palette can be installed permanently using "Install Palette..." menu item in "Palette" menu.

    Here is how it looks:

    screenshot1 screenshot2

    Any suggestions and improvements are welcome!


    Since all installed versions of Mathematica share the same $BaseDirectory and $UserBaseDirectory, it is recommended to install this palette in the oldest version installed to avoid standard warning popup:

    This notebook was created in a more recent version of Mathematica, and may not function properly with the older front end you are using. Contact Wolfram Research (www.wolfram.com) for upgrade information.