stevieb9 / berrybrew

Perlbrew for Windows!
Other
63 stars 9 forks source link

give user option to re-associate .pl files with switched perl ver #15

Closed stevieb9 closed 4 years ago

stevieb9 commented 8 years ago

http://stackoverflow.com/questions/1387769/create-registry-entry-to-associate-file-extension-with-application-in-c

pryrt commented 8 years ago

I started using your berrybrew for the first time today (after recent mentions on perlmonks). This was one of the issues I saw, too.

My thoughts:

  1. look for existing .pl => PL_FILE or .pl => PerlScript association
    • if doesn't exist, create it
    • if does exist, use the existing association (I get annoyed by programs that create a new association rather than just adding actions to the existing association)
  2. Create new action (never overwrite existing action) for ...\shell\RunWithSelectedBerrybrew "Run with berrybrew selected perl"
    • make sure action's key-name does not conflict with existing action
    • optionally make it the default action ( ...\shell\@ = RunWithSelectedBerrybrew )
      • might need to "archive" the old default: for example, to ...\shell\default.orig
    • make sure it gets updated on berrybrew switch
    • make sure it unsets as default on berrybrew off
      • if ...\shell\default.orig exists, re-set the @DEFAULT to .orig value
  3. Create second new action: ...\shell\RunWithBerrybrewExec "Run with berrybrew exec"
cmfrolick commented 8 years ago

I have notes relating to fixing file association for a standard strawberry perl installation that typically works. From an admin command prompt:

assoc .pl=PerlScript
ftype PerlScript=c:\strawberry\perl\bin\perl.exe %1 %*

You may have to delete the HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.pl\UserChoice key to clear up how it is called.

pryrt commented 8 years ago

I was doing some experimenting, and came up with an alternate idea: playing with associations without explicit user intervention might be too dangerous. But as a step toward enabling dynamic associations, set an environment variable of the same type as the PATH (USER if you're setting USER PATH; SYSTEM if you're setting SYSTEM PATH) -- I call it %BerryRoot%.

Change this variable on every berrybrew switch (and possibly clear it -- or point it to a previous system Perl on berrybrew off). You can then advertise this variable in README, and explain that if users set their association to "%BerryRoot%\perl\bin\perl.exe" "%1" %*, the association will follow as berrybrew switches (they might have to open a new explorer window before doing a double-click; not sure if the SendMessageTimeout(...WM_SETTINGCHANGE, ..."Environment", ...) will get sent to existing explorer windows or not).

This has the side benefit that, instead of changing the PATH a bunch, you could just set the PATH to %BerryRoot%\c\bin;%BerryRoot%\perl\bin;%BerryRoot%\perl\site\bin;..., and just need to edit the variable instead of the PATH on every switch.

But if you'd rather leave the PATH part of the code as-is, I think just automating the switch => %BerryRoot% would be quite helpful for those who want file associations to change with the switch.

stevieb9 commented 8 years ago

That's a tremendously good idea, and quite flexible.

Unfortunately, from my testing, SendMessageTimeout() won't update the current/parent shell that I can tell, however, it would limit the hacking of the PATH to just the initial switch and an off.

I'll create a new branch and start playing around. I really want to find a way around having to close the current shell and re-open a new one on every switch, but I'm not holding my breath anymore.

stevieb9 commented 8 years ago

Note that I've implemented a unconfig command (doesn't show up in help) for testing purposes (removes berrybrew bin from PATH), and an upgrade command that ensures that modified config files don't get trampled.

The upgrade simply backs-up the config files, does a git pull, then copies the config files back to data dir.

If you haven't made any config file changes from the default, a git pull will work fine. Also, upgrading in any fashion does not manage the perls_custom.json file (which is the registry for cloned perls), so it'll never get removed/overwritten.

pryrt commented 7 years ago

As I've used my %BerryPath% over the last half year, I've liked it less and less. I just switched back to my main PATH hardcoding the path to my "system" strawberry installation. (The variable expansion doesn't always happen when I expect it to, so sometimes it stays stale)

But I've played with ideas for the equivalents of perlbrew use and perlbrew exec in plain myberry.c (I haven't done enough C# to do a proof of concept there), I found I could use the snippet:

char    *origPath, *selectedPerlVersion, *selectedBerrybrewPerlPath, *cmd; ...
strncpy(origPath, getenv("PATH"), 4096);
snprintf(putPath, 4096, "PATH=%s\\c\\bin;%s\\perl\\bin;%s\\perl\\site\\bin;%s", selectedBerrybrewPerlPath, selectedBerrybrewPerlPath, selectedBerrybrewPerlPath, origPath);
putenv(putPath);
system(cmd);

And it would update the environment of the spawned process. For mybrew exec, I just run that through a for loop to iterate over all the desired selectedBerrybrewPath's; for mybrew use, I spawn a new window by using

sprintf(cmd, "START \"%s\" cmd /K where perl", selectedPerlVersion)

... so the title of the new window indicates the chosen version of perl, and I emphasize the by starting the cmd shell by running the windows builtin where perl to show the path to perl (technically, all ways to get to an executable perl or perl.bat or perl.exe or... that can be found in PATH)

Regarding issue #9, if you used the C# equivalent of putenv() for the new PATH before spawning your new shell window, it should inherit the updated path in the new window. If you did the same before your sub-processes for berrybrew exec, it should allow you to run other commands (not just excecutables that happen to be in version\perl\bin -- I've had some of the scripts that I want to use be installed in version\perl\site\bin, so berrybrew exec won't let me execute those directly.)

Summary:

(If the snippets of C aren't enough, let me know, and I'll see if I can share my subversion for myberry.c: it's not in github because myberry.c was a proof-of-concept, never intended for public consumption)

pryrt commented 7 years ago

Oh, right, and regarding the re-association of .pl (which is technically what this issue is about): I've changed HKCR\PerlScript\shell\run\command from %BerryBrew%\perl\bin\perl.exe "%1" %* to c:\usr\bin\env.exe perl "%1" %*, and I get env.exe from http://gnuwin32.sourceforge.net/packages/coreutils.htm

Given that gnuwin32 are ports of GPL'd software, you could probably re-distribute env.exe in the same directory as berrybrew.exe, and ask the user if they want the HKCR\.pl = PerlScript and HKCR\PerlScript... pointing to c:\berrybrew\bin\env.pl in their registry or not...

stevieb9 commented 4 years ago

I'm going to implement this in correlation with updates to the installer. It'll be an option (unchecked by default) at install time, and will be added as a new configuration file parameter so that it can be changed after installation (and by users who didn't use the installer to install).

stevieb9 commented 4 years ago

This work is now done, in the v1.30 branch.