Following solutions (actually it is only one) doesn't work to me :
How to get a name of default browser using python
How to get name of the default browser in windows using python?
Solution was:
from _winreg import HKEY_CURRENT_USER, OpenKey, QueryValue
# In Py3, this module is called winreg without the underscore
with OpenKey(HKEY_CURRENT_USER,
r"Software\Classes\http\shell\open\command") as key:
cmd = QueryValue(key, None)
But unfortunately, in Windows 10 Pro I don't have targeted registry value. I've tried to find alternative keys in Regedit, but no luck.
Please take a look, what my registry virtually contains:
The following works for me on Windows 10 pro:
from winreg import HKEY_CURRENT_USER, OpenKey, QueryValueEx
reg_path = r'Software\Microsoft\Windows\Shell\Associations\UrlAssociations\https\UserChoice'
with OpenKey(HKEY_CURRENT_USER, reg_path) as key:
print(QueryValueEx(key, 'ProgId'))
Result (first with Chrome set as default, then with IE):
$ python test.py
('ChromeHTML', 1)
$ python test.py
('IE.HTTPS', 1)
Please check for the key in windows 10
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\Shell\Associations\URLAssociations(http|https)\UserChoice
def get_windows_default_browser_launch():
""" On windows, return the default browser for 'https' urls
returns: example '"C:\Program Files\Mozilla Firefox\firefox.exe" -osint -url "%1"'
"""
import winreg
key = winreg.OpenKey(winreg.ConnectRegistry(None, winreg.HKEY_CURRENT_USER), r"Software\Microsoft\Windows\Shell\Associations\UrlAssociations\https\UserChoice")
prog_id, _ = winreg.QueryValueEx(key, "ProgId")
key = winreg.OpenKey(winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE), r"SOFTWARE\Classes\{}\shell\open\command".format(prog_id))
launch_string, _ = winreg.QueryValueEx(key, "") # read the default value
return launch_string
Windows 10 Python3 , may want to change the key for 'http' not https, but this is my code verbatim as my context is of a secured server. I wanted the browser binary name and path, which is just one more line.
Related
I am writing a python program that needs to store a value in a persistent user environment variable. I believe these values are stored in the registry. I have tried something like this using the winreg python module.
key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, 'Environment', access=winreg.KEY_WRITE)
winreg.SetValueEx(key, envVarName, 0, winreg.REG_SZ, envVarValue)
winreg.Close(key)
I can see from using Registry Editor that this value is successfully set. But if I try and read the value from another python script or from a new powershell instance, I don't see the new value until the machine is rebooted.
What else do I need to do to make this value available to other processes without rebooting?
Looking at this answer gives a possible answer:
https://stackoverflow.com/a/61757725/18300067
os.system("SETX {0} {1} /M".format("start", "test"))
This is how we do it in production on one of Windows servers (code is simplified):
import winreg
regdir = "Environment-test"
keyname = "Name-test"
keyvalue = "Value-test"
def setRegistry(regdir, keyname, keyvalue):
with winreg.CreateKey(winreg.HKEY_CURRENT_USER, regdir) as _:
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, regdir, 0, winreg.KEY_WRITE) as writeRegistryDir:
winreg.SetValueEx(writeRegistryDir, keyname, 0, winreg.REG_SZ, keyvalue)
def getRegistry(regdir, keyname):
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, regdir) as accessRegistryDir:
value, _ = winreg.QueryValueEx(accessRegistryDir, keyname)
return(value)
If I firstly set the value using:
setRegistry(regdir, keyname, keyvalue)
Then check if it's created:
Now I use the getRegistry and open a PS in admin mode to run it:
print(getRegistry(regdir, keyname))
I have coded a python skript using a 32bit geckodriver.exe.
I package this script with the geckodriver included as an Pyinstalled .exe file.
I recognized, this .exe doesn't run when somebody uses Firefox 64bit.
And obviously it doesn't either work when somebody doesnt use Firefox at all, but Chrome instead.
So theoretically, yes I can package 2 geckodriver versions (32/64) and 2 chromedriver versions (32/64) into the .exe, but HOW can I find out which browser and which version (32/64) is installed on the system of the user?
It's only windows-system... so is there a way by reading the users registry or so?
Any ideas appreciated.
Thanks!
I think you can do it with the registry as this:
from winreg import HKEY_LOCAL_MACHINE
import winreg
try:
winreg.OpenKey(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\chrome.exe', 0, KEY_ALL_ACCESS).Close()
except FileNotFoundError:
print('Chrome not installed')
And same for firefox
here is a good way to use it in function:
import os
import win32file
from winreg import *
import winreg
CHROME_KEY = 'SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\chrome.exe'
def is_chrome_installed():
try:
key = winreg.OpenKey(HKEY_LOCAL_MACHINE, CHROME_KEY, 0, KEY_ALL_ACCESS)
path_dir = QueryValueEx(key, "PATH")[0]
file_arc = win32file.GetBinaryType(os.path.join(path_dir, 'chrome.exe'))
if file_arc == 0:
print('its a 32bit')
elif file_arc == 6:
print('its a 64bit')
return True
except FileNotFoundError:
print('Chrome not installed')
return False
notice that you need to be run as administartor for this to work
I'm trying to run a example from http://codespeak.net/execnet/example/hybridpython.html but python freezes on line:
gw = execnet.makegateway("popen//python=jython")
Example:
import execnet
gw = execnet.makegateway("popen//python=jython")
channel = gw.remote_exec("""
from java.util import Vector
v = Vector()
v.add('aaa')
v.add('bbb')
for val in v:
channel.send(val)
""")
for item in channel:
print (item)
I'm on Debian Jessie
If you read the documentation, the following is defined
def makegateway(self, spec=None):
"""create and configure a gateway to a Python interpreter.
The ``spec`` string encodes the target gateway type
and configuration information. The general format is::
key1=value1//key2=value2//...
If you leave out the ``=value`` part a True value is assumed.
Valid types: ``popen``, ``ssh=hostname``, ``socket=host:port``.
Valid configuration::
id=<string> specifies the gateway id
***python=<path> specifies which python interpreter to execute***
execmodel=model 'thread', 'eventlet', 'gevent' model for execution
chdir=<path> specifies to which directory to change
nice=<path> specifies process priority of new process
env:NAME=value specifies a remote environment variable setting.
If no spec is given, self.defaultspec is used.
"""
meaning you should write:
gw = execnet.makegateway("popen//python=C:\\..\\jython2.7.0\\bin\\jython")
I am trying to get all installed programs of my windows computer, therefore I read out the registry.
But somehow python reads the 32bit programs out twice (even though I give him another registry entry)
Here is the code snipped:
def get_programs(registry):
reg = ConnectRegistry(None, HKEY_LOCAL_MACHINE)
programList = []
key = OpenKey(reg, registry)
print(QueryInfoKey(key))
for i in range(0, QueryInfoKey(key)[0]):
programList.append(EnumKey(key, i))
CloseKey(key)
CloseKey(reg)
return programList
I call this function like this:
registry32bit = "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
registry64bit = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
programs32bit = get_programs(registry32bit)
programs64bit = get_programs(registry64bit)
Why does python open and read out the same registry (for 32 bit) twice and return the exactly same list?
This appears to work and uses #eryksun suggestion in a comment below about just letting the redirection happen and not explicitly referencing the Wow6432Node registry key. The central idea is to just specify either the KEY_WOW64_32KEY or KEY_WOW64_64KEY flag when opening the uninstall subkey and let the magic happen.
Note: I also Pythonized the code in the get_programs() function some. This made it shorter and more readable in my opinion.
import sys
from _winreg import *
# Assure registry handle objects with context manager protocol implemented.
if sys.version_info.major*10 + sys.version_info.minor < 26:
raise AssertionError('At least Python 2.6 is required.')
def get_programs(subkey, regBitView):
with ConnectRegistry(None, HKEY_LOCAL_MACHINE) as hive:
with OpenKey(hive, subkey, 0, regBitView | KEY_READ) as key:
return [EnumKey(key, i) for i in range(QueryInfoKey(key)[0])]
UNINSTALL_REG_KEY = r'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
programs32bit = get_programs(UNINSTALL_REG_KEY, KEY_WOW64_32KEY)
programs64bit = get_programs(UNINSTALL_REG_KEY, KEY_WOW64_64KEY)
print('32-bit programs:\n{}'.format(programs32bit))
print('')
print('64-bit programs:\n{}'.format(programs64bit))
Many thanks to #eryksun for the clues and many implementation strategy suggestions.
what I am trying to do is change the desktop wallpaper in windows.
To do that, I use the following code:
import ctypes
import Image
pathToBmp = "PATH TO BMP FILE"
SPI_SETDESKWALLPAPER = 20
ctypes.windll.user32.SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, pathToBmp , 0)
this works when I run the .py file, this works when I convert it using py2exe and run the exe under the current user, but when I run the exe as SYSTEM, the current user background does not change.
This ofcourse was to be expected. But I don't know how to solve it.
By the way, it does not matter if any of your solutions changes the current user background or all the users' backgrounds.
Thank you for your time.
How about creating a value key in the registry at:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
This will change the background when ever the user login.
To try it, write this script, name it for example SetDesktopBackground.py, any where you like:
#!python
from ctypes import *
from os import path
SPI_SETDESKWALLPAPER = 0x14
SPIF_UPDATEINIFILE = 0x1
lpszImage = path.join(path.dirname(path.realpath(__file__)), 'your_image.jpg')
SystemParametersInfo = windll.user32.SystemParametersInfoA
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, lpszImage, SPIF_UPDATEINIFILE)
Dont forgot to put some image, your_image.jpg, in the same directory. Then open the registery editor:
Start > Search > type regedit.exe
Then go to the path:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
Right click and choose New > String Value and type any name you like for this value.
Right click on this new value and choose Modify, in the Data Value field write:
"C:\Python26\pythonw.exe" "C:\Path\To\SetDesktopBackground.py"
To test it, logout and login again. The background should change when ever this user login.
That was the manual way to do it, you can use _winreg in your application to create the value during the installation:
#!python
from _winreg import *
from sys import executable
from os import path
subkey = 'Software\\Microsoft\\Windows\\CurrentVersion\\Run'
script = 'C:\\Path\\To\\SetDesktopBackground.py'
pythonw = path.join(path.dirname(executable), 'pythonw.exe')
hKey = OpenKey(HKEY_CURRENT_USER, subkey, 0, KEY_SET_VALUE)
SetValueEx(hKey, 'MyApp', 0, REG_SZ, '"{0}" "{1}"'.format(pythonw, script))
CloseKey(hKey)