Updated logic for reading InstallPath and PythonPath registry variables. Added support for both system-wide and per-user python installation. Activate and Deactivate functions now backup/restore PYTHONHOME environment variable
May be we should use RegistryKey.OpenBaseKey along with RegistryView.Registry32. But this would add a dependency for .NET 4. Do you think it's OK to take the dependency? Another alternative is to use P/Invokes to the native win32 registry api; this will be a bit complicated.
Or would it be a good idea to replace registry based mechanism and rely on PYTHONHOME, PYTHONPATH variables? Not sure if there could be issues when someone wants to modify these variables in Pre/Post hooks.
This could also solve one problem with registry based mechanism - while I'm in a virtualenv, I cannot use the system-installed python in a separate console or run any other python app outside virtualenv.
I'm starting to lose my patience with Bitbucket issues... It's a mess to try to follow a conversation.
I think I've lost the overview of this patch, so allow me to summarize the situation and please correct me if I am wrong:
At any give point, only one Python install can be "active" on the user's machine. This install can be either a per-user install or a system-wide install.
Everything works fine without the patch with the current code, right? (This is not true, because some installers don't create the referenced keys in the registry, at least in my experience, but this is a different problem.)
HKLM/Software and children thereof are redirected keys, so Wow6432Node comes into play. We shouldn't access that key directly, because it might break compatibility down the road.
Now, what can we do about system-wide installs? If we attempted to access the HKLM hive, we'd need admin rights, wouldn't we?
Assuming a system-wide install, what's the benefit of modifying the HKLM registtry? A few observations:
1) The user needs elevation
How can we achieve this? Opening a new instance of PS as admin? Restoring the registry after that would be difficult; if the user simply closed the console, we'd have to keep some state to remember to change the registry the next time. It looks complicated.
2) Can we limit ourselves to the HKCU hive?
Even if are facing a system-wide install, wouldn't it work to just change the HKLU hive entries instead? Maybe Python checks HKCU and HKLM in order. It doesn't really have any other information to determine what kind of install it is, right? In such a case, the check to change venvs would go like this:
a) Change HKCU
To restore the entries, we'd do this:
a) Is there any Python-releated entry in HKLM?
a.YES and we're restoring, not changing venvs) Delete HKCU entries
a.NO) Change HKCU only
If it proved to work, this would be my preferred approach.
3) If the above fails, we could resort to calling reg.exe with elevation from the same VirtualenvWrapper instance, without having to start a new one.
I did a small experiment. Removed the python related HKCU and HKLU registry keys. In a non-virtualenv shell, ran python.exe from c:\python27 and \.virtualenvs\venv\scripts\. In both cases, python picked up the correct sys.path: for venv case it picked up the Lib & DLLs from \.virtualenvs\venv.
It means python.exe doesn't read the registry keys, it's only the installers who read it. All we need to ensure is that the correct python.exe runs for an user.
However the other installers (like pywin32 or pyside, for instance) read the registry to know where python is. They also provide user an option to choose python install directory in the installation wizard. So our modification of registry is just providing a value-add for additional installers that user may use.
I believe most of us who use virtualenv, use pip for package management. In that case, can we just inform the user (for a non-admin shell and system-wide install) that installation of other software functionality will not be available for virtualenv?