Closed stevieb9 closed 4 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:
berrybrew switch
berrybrew off
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.
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
.
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.
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.
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:
berrybrew exec
:
loop over versions: { build path, including c, perl, and perl\site bin directories; call putenv() to update local and spawned environment; execute the given command }
berrybrew use
:
one time: { build path; call putenv() to update local and spawned environment; system(START "version name" cmd /K [optional initial command]); } remind user that this window hasn't updated path, but the spawned window has
berrybrew switch
: myberry.c doesn't have this one, but it would be:
one time: { build path; save permanent path to registry call putenv() to update local and spawned environments system(START "version name" cmd /K [optional initial command]); } remind user that this window hasn't updated path, but the spawned window has
(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)
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...
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).
This work is now done, in the v1.30 branch.
when we set, we create a new handler called berrybrewPerl
, which uses env.exe
to use the first perl in PATH
we then point .pl assoc at the new handler
we do not remove the original handler, if one existed
when we unset, we simply revert the .pl association to point back at the original handler that was being used previously, or none if there wasn't one available at time of setting
FileAssoc()
and berrybrew associate [option]
added
http://stackoverflow.com/questions/1387769/create-registry-entry-to-associate-file-extension-with-application-in-c