Module libwine.wine
Expand source code
import glob
import re
from .utils.command import Command
from .wineprocess import WineProcess
class Wine:
'''
Create a new object of type Wine with all the methods for its management.
Parameters
----------
winepath : str
full path to Wine
wineprefix: str
full path to your wineprefix
verbose: int, optional
verbosity status of wine logs (default is 0):
0 (silent): -all
1 (quite): -warn+all
2 (no fixme): fixme-all
3 (debug): +all
Raises
------
ValueError
If the given winepath doesn't contains all the essential paths.
'''
_winepath = str
_wineprefix = str
_verbose = int
_terminals = {
'xterm': 'xterm -e %s',
'konsole': 'konsole -e %s',
'gnome-terminal': 'gnome-terminal -- %s',
'xfce4-terminal': 'xfce4-terminal --command %s',
'mate-terminal': 'mate-terminal --command %s'
}
_verbose_levels = {
0: "-all",
1: "-warn+all",
2: "fixme-all",
3: "+all"
}
_windows_versions = {
"win10": {
"ProductName": "Microsoft Windows 10",
"CSDVersion": "",
"CurrentBuild": "17763",
"CurrentBuildNumber": "17763",
"CurrentVersion": "10.0",
},
"win81": {
"ProductName": "Microsoft Windows 8.1",
"CSDVersion": "",
"CurrentBuild": "9600",
"CurrentBuildNumber": "9600",
"CurrentVersion": "6.3",
},
"win8": {
"ProductName": "Microsoft Windows 8",
"CSDVersion": "",
"CurrentBuild": "9200",
"CurrentBuildNumber": "9200",
"CurrentVersion": "6.2",
},
"win7": {
"ProductName": "Microsoft Windows 7",
"CSDVersion": "Service Pack 1",
"CurrentBuild": "7601",
"CurrentBuildNumber": "7601",
"CurrentVersion": "6.1",
},
"win2008r2": {
"ProductName": "Microsoft Windows 2008 R2",
"CSDVersion": "Service Pack 1",
"CurrentBuild": "7601",
"CurrentBuildNumber": "7601",
"CurrentVersion": "6.1",
},
"win2008": {
"ProductName": "Microsoft Windows 2008",
"CSDVersion": "Service Pack 2",
"CurrentBuild": "6002",
"CurrentBuildNumber": "6002",
"CurrentVersion": "6.0",
},
"winxp": {
"ProductName": "Microsoft Windows XP",
"CSDVersion": "Service Pack 2",
"CurrentBuild": "3790",
"CurrentBuildNumber": "3790",
"CurrentVersion": "5.2",
},
}
_dll_overrides = {
0: "builtin",
1: "native",
2: "builtin,native",
3: "native,builtin"
}
_reg_types = {
0: "REG_SZ",
1: "REG_DWORD",
2: "REG_MULTI_SZ",
3: "REG_BINARY",
4: "REG_EXPAND_SZ",
5: "REG_NONE",
}
def __init__(self, winepath: str, wineprefix: str, verbose: int = 0):
self._winepath = winepath
self._wineprefix = wineprefix
if verbose in self._verbose_levels:
self._verbose = verbose
if not self.__validate_winepath():
raise ValueError("Given winepath doesn't seem a valid Wine path.")
'''
Wine checks
'''
def __validate_winepath(self):
'''
Check if essential paths exist in winepath.
'''
promise = ["share", "bin", "lib"]
dirs = glob.glob(f"{self._winepath}/*")
dirs = [d.replace(f"{self._winepath}/", "") for d in dirs]
for p in promise:
if p not in dirs:
return False
return True
def check_arch_compatibility(self):
'''
Check if the given wine arch is compatible with the running system
TODO: this method should check for ARM wine compatibility on ARM devices
'''
return
def execute(self, command: str, comunicate: bool = False, envs: dict = {}, terminal: str = None):
'''
Execute command inside wineprefix using the wine in winepath
Parameters
----------
command : str
command to be executed inside the wineprefix
comunicate : bool, optional
to get the output of the command (default is False)
envs: dict, optional
dict of environment variables to pass on the execution
terminal : str, optional
command to an external terminal (default is None)
'''
envs["WINEPREFIX"] = self._wineprefix
envs["WINEDEBUG"] = self._verbose_levels[self._verbose]
command = f"{self._winepath}/bin/wine64 {command}"
if terminal in self._terminals:
command = self._terminals[terminal] % command
cmd = Command(
command=command,
cwd=self._wineprefix,
envs=envs
)
if comunicate:
return cmd.comunicate()
return cmd.execute()
'''
Setters
'''
def set_verbose(self, level: int):
if level not in self._verbose_levels:
raise ValueError(f"{level} is not a valid verbose level.")
else:
self._verbose = self._verbose_levels[level]
'''
Wine Tools
'''
def winecfg(self):
'''
Launch the winecfg tool on the active display.
'''
self.execute(command="winecfg")
def debug(self, terminal: str = None):
'''
Launch the winedbg tool.
Parameters
----------
terminal : str, optional
command to an external terminal (default is None)
'''
self.execute(
command="winedbg",
terminal=terminal
)
def cmd(self, terminal: str = None):
'''
Launch the cmd tool.
Parameters
----------
terminal : str, optional
command to an external terminal (default is None)
'''
self.execute(
command="cmd",
terminal=terminal
)
def taskmanager(self):
'''
Launch the taskmgr tool on the active display.
'''
self.execute(command="taskmgr")
def controlpanel(self):
'''
Launch the control tool on the active display.
'''
self.execute(command="control")
def uninstaller(self):
'''
Launch the uninstaller tool on the active display.
'''
self.execute(command="uninstaller")
def regedit(self):
'''
Launch the regedit tool on the active display.
'''
self.execute(command="regedit")
'''
Wine commandd execution
'''
def command(self, command: str):
'''
Execute custom wine commands inside the wineprefix.
Parameters
----------
command : str
the command to be executed
'''
self.execute(command=command)
def run_exe(self, executable_path: str, envs: dict = {}):
'''
Execute exe files inside the wineprefix.
executable_path : str
full path to the .exe file
envs: dict, optional
dict of environment variables to pass on the execution
'''
command = executable_path
self.execute(command=command, envs=envs)
def run_msi(self, msi_path: str, envs: dict = {}):
'''
Execute msi files inside the wineprefix.
msi_path : str
full path to the .msi file
envs: dict, optional
dict of environment variables to pass on the execution
'''
command = f"msiexec /i {msi_path}"
self.execute(command=command, envs=envs)
def run_bat(self, bat_path: str, envs: dict = {}):
'''
Execute bat files inside the wineprefix.
bat_path : str
full path to the .bat file
envs: dict, optional
dict of environment variables to pass on the execution
'''
command = f"wineconsole cmd /c '{bat_path}'"
self.execute(command=command, envs=envs)
'''
Wine uptime management
'''
def __wineboot(self, status: int, silent: bool = True):
'''
Manage Wine server uptime using wineboot
Parameters
----------
status : int
the state ID to set in wineboot:
0 (kill): Kill running processes without any cleanup
1 (restart): Restart only, don't do normal startup operations
2 (shutdown): Shutdown only, don't reboot
3 (update): Update the wineprefix directory
silent: bool, optional
if the command should not display on display (default True)
Raises
------
Exception
If the given state is invalid.
'''
states = {
0: "-k",
1: "-r",
2: "-s",
3: "-u"
}
envs = {}
if silent:
envs["DISPLAY"] = ":0.0"
if status in states:
status = states[status]
self.execute(command=f"wineboot {status}", envs=envs)
else:
raise ValueError(f"[{status}] is not a valid status for wineboot!")
def kill(self):
'''
Kill all processes running inside the wineprefix.
'''
self.__wineboot(status=0)
def restart(self):
'''
Simulate system restart for the wineprefix,
don't do normal startup operations.
'''
self.__wineboot(status=1)
def shutdown(self):
'''
Simulate system shutdown for the wineprefix, don't reboot.
'''
self.__wineboot(status=2)
def update(self):
'''
Update the wineprefix directory.
'''
self.__wineboot(status=3, silent=True)
'''
Wine process management
'''
def processes(self):
'''
Get processes running on the wineprefix.
Return
------
list:
A list of WineProcess.
'''
processes = []
parent = None
winedbg = self.execute(
command='winedbg --command "info proc"',
comunicate=True).split("\n")
# remove the first line from the output (the header)
del winedbg[0]
for w in winedbg:
w = re.sub("\s{2,}", " ", w)[1:].replace("'", "")
if "\_" in w:
w = w.replace("\_ ", "")
w += " child"
w = w.split(" ")
w_parent = None
if len(w) >= 3 and w[1].isdigit():
w_pid = w[0]
w_threads = w[1]
w_name = w[2]
if len(w) == 3:
parent = w_pid
else:
w_parent = parent
w = WineProcess(
pid=w_pid,
name=w_name,
parent_pid=w_parent,
wine=self
)
processes.append(w)
return processes
'''
Wine register management
'''
def reg_list(self, key: str):
'''
List all keys values from the wineprefix register.
Parameters
----------
key : str
the key name
Return
------
list:
A list of key values.
'''
values = []
command = f'reg query "{key}" /f'
output = self.execute(
command=command,
comunicate=True).split("\n")
for o in output:
if o.startswith(" "):
o = re.sub(' +', '|', o[4:].replace("\r", ""))
values.append(o.split("|"))
return values
def reg_add(self, key: str, value: str, data: str, data_type: int = 0):
'''
Add (or edit) key to the wineprefix register.
Parameters
----------
key : str
the key name
value : str
the key value
data : str
the data to store in the key value
data_type : int
the type of data (default 0:REG_SZ):
0 (REG_SZ): standard string
1 (REG_DWORD): data by a four byte number
2 (REG_MULTI_SZ): multiple string
3 (REG_BINARY): data as raw binary data
4 (REG_EXPAND_SZ): expandable data string
5 (REG_NONE): no defined value type
'''
if data_type not in self._reg_types:
raise ValueError("Given key type is not supported.")
data_type = self._reg_types.get(data_type)
command = f'reg add "{key}" /v "{value}" /d "{data}" /t "{data_type}" /f'
self.execute(command=command)
def reg_delete(self, key: str, value: str):
'''
Delete key from the wineprefix register.
Parameters
----------
key : str
the key name
value : str
the key value to be removed
'''
command = f'reg delete "{key}" /v "{value}" /f'
self.execute(command=command)
'''
Simplified Wine register keys
'''
def set_windows(self, version: str):
'''
Change Windows version of the wineprefix.
Parameters
----------
version : str
the Windows version to be setted:
win10 (Microsoft Windows 10)
win81 (Microsoft Windows 8.1)
win8 (Microsoft Windows 8)
win7 (Microsoft Windows 7)
win2008r2 (Microsoft Windows 2008 R1)
win2008 (Microsoft Windows 2008)
winxp (Microsoft Windows XP)
Raises
------
ValueError
If the given version is invalid.
'''
if version not in self._windows_versions:
raise ValueError("Given version is not supported.")
self.reg_add(
key="HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion",
value="ProductName",
data=self._windows_versions.get(version)["ProductName"]
)
self.reg_add(
key="HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion",
value="CSDVersion",
data=self._windows_versions.get(version)["CSDVersion"]
)
self.reg_add(
key="HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion",
value="CurrentBuild",
data=self._windows_versions.get(version)["CurrentBuild"]
)
self.reg_add(
key="HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion",
value="CurrentBuildNumber",
data=self._windows_versions.get(version)["CurrentBuildNumber"]
)
self.reg_add(
key="HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion",
value="CurrentVersion",
data=self._windows_versions.get(version)["CurrentVersion"]
)
def set_virtual_desktop(self, status: bool, res: str = None):
'''
Enable or disable the Wine Virtual Desktop.
Parameters
----------
status : bool
the Virtual Desktop status
res : str (optional)
the resolution to be used (e.g. 800x600) only if status is True
'''
if status:
self.reg_add(
key="HKEY_CURRENT_USER\\Software\\Wine\\Explorer",
value="Desktop",
data="Default"
)
self.reg_add(
key="HKEY_CURRENT_USER\\Software\\Wine\\Explorer\\Desktops",
value="Default",
data=res
)
else:
self.reg_delete(
key="HKEY_CURRENT_USER\\Software\\Wine\\Explorer",
value="Desktop"
)
def set_decorations(self, status: bool):
'''
Enable or disable the windows manager decorations.
Parameters
----------
status : bool
the decorations status
'''
if status:
status = "Y"
else:
status = "N"
self.reg_add(
key="HKEY_CURRENT_USER\\Software\\Wine\\X11 Driver",
value="Decorated",
data=status
)
def set_window_managed(self, status: bool):
'''
Enable or disable the windows manager control.
Parameters
----------
status : bool
the control status
'''
if status:
status = "Y"
else:
status = "N"
self.reg_add(
key="HKEY_CURRENT_USER\\Software\\Wine\\X11 Driver",
value="Managed",
data=status
)
def set_fullscreen_mouse_capture(self, status: bool):
'''
Enable or disable auto mouse capture in fullscreen.
Parameters
----------
status : bool
the capture status
'''
if status:
status = "Y"
else:
status = "N"
self.reg_add(
key="HKEY_CURRENT_USER\\Software\\Wine\\X11 Driver",
value="GrabbFullscreen",
data=status
)
def set_dpi(self, dpi: int):
'''
Set custom DPI value.
Parameters
----------
dpi : int
the new density value
'''
self.reg_add(
key="HKEY_CURRENT_USER\\Control Panel\\Desktop",
value="LogPixels",
data=dpi,
data_type=1
)
'''
Wine DLL overrides management
'''
def override_dll_list(self):
'''
List all DLL overrides in the wineprefix
Return
------
list:
A list of dll overrides.
'''
overrides = []
values = self.reg_list(
"HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides")
for v in values:
override = [v[0]]
if v[2] == "native,builtin":
override.append(3)
elif v[2] == "builtin,native":
override.append(2)
elif v[2] == "native":
override.append(1)
elif v[2] == "builtin":
override.append(0)
overrides.append(override)
return overrides
def override_dll(self, name: str, override: int = 0, restore: bool = False):
'''
Overriding a DLL in the wineprefix.
Parameters
----------
name : str
the name of the DLL
override : int
the type of override (default 0:builtin):
0 (builtin): provided by Wine
1 (native): provided by Windows
2 (builtin/native): builtin then native
3 (native/builtin): native then builtin
restore : bool (optional)
restore the override to the initiale state (default False)
'''
if override not in self._dll_overrides:
raise ValueError("Given override type is not supported.")
if not restore:
self.reg_add(
key="HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides",
value=name,
data=self._dll_overrides.get(override)
)
else:
self.reg_delete(
key="HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides",
value=name
)
Classes
class Wine (winepath: str, wineprefix: str, verbose: int = 0)
-
Create a new object of type Wine with all the methods for its management.
Parameters
winepath
:str
- full path to Wine
wineprefix
:str
- full path to your wineprefix
verbose
:int
, optional- verbosity status of wine logs (default is 0): 0 (silent): -all 1 (quite): -warn+all 2 (no fixme): fixme-all 3 (debug): +all
Raises
ValueError
- If the given winepath doesn't contains all the essential paths.
Expand source code
class Wine: ''' Create a new object of type Wine with all the methods for its management. Parameters ---------- winepath : str full path to Wine wineprefix: str full path to your wineprefix verbose: int, optional verbosity status of wine logs (default is 0): 0 (silent): -all 1 (quite): -warn+all 2 (no fixme): fixme-all 3 (debug): +all Raises ------ ValueError If the given winepath doesn't contains all the essential paths. ''' _winepath = str _wineprefix = str _verbose = int _terminals = { 'xterm': 'xterm -e %s', 'konsole': 'konsole -e %s', 'gnome-terminal': 'gnome-terminal -- %s', 'xfce4-terminal': 'xfce4-terminal --command %s', 'mate-terminal': 'mate-terminal --command %s' } _verbose_levels = { 0: "-all", 1: "-warn+all", 2: "fixme-all", 3: "+all" } _windows_versions = { "win10": { "ProductName": "Microsoft Windows 10", "CSDVersion": "", "CurrentBuild": "17763", "CurrentBuildNumber": "17763", "CurrentVersion": "10.0", }, "win81": { "ProductName": "Microsoft Windows 8.1", "CSDVersion": "", "CurrentBuild": "9600", "CurrentBuildNumber": "9600", "CurrentVersion": "6.3", }, "win8": { "ProductName": "Microsoft Windows 8", "CSDVersion": "", "CurrentBuild": "9200", "CurrentBuildNumber": "9200", "CurrentVersion": "6.2", }, "win7": { "ProductName": "Microsoft Windows 7", "CSDVersion": "Service Pack 1", "CurrentBuild": "7601", "CurrentBuildNumber": "7601", "CurrentVersion": "6.1", }, "win2008r2": { "ProductName": "Microsoft Windows 2008 R2", "CSDVersion": "Service Pack 1", "CurrentBuild": "7601", "CurrentBuildNumber": "7601", "CurrentVersion": "6.1", }, "win2008": { "ProductName": "Microsoft Windows 2008", "CSDVersion": "Service Pack 2", "CurrentBuild": "6002", "CurrentBuildNumber": "6002", "CurrentVersion": "6.0", }, "winxp": { "ProductName": "Microsoft Windows XP", "CSDVersion": "Service Pack 2", "CurrentBuild": "3790", "CurrentBuildNumber": "3790", "CurrentVersion": "5.2", }, } _dll_overrides = { 0: "builtin", 1: "native", 2: "builtin,native", 3: "native,builtin" } _reg_types = { 0: "REG_SZ", 1: "REG_DWORD", 2: "REG_MULTI_SZ", 3: "REG_BINARY", 4: "REG_EXPAND_SZ", 5: "REG_NONE", } def __init__(self, winepath: str, wineprefix: str, verbose: int = 0): self._winepath = winepath self._wineprefix = wineprefix if verbose in self._verbose_levels: self._verbose = verbose if not self.__validate_winepath(): raise ValueError("Given winepath doesn't seem a valid Wine path.") ''' Wine checks ''' def __validate_winepath(self): ''' Check if essential paths exist in winepath. ''' promise = ["share", "bin", "lib"] dirs = glob.glob(f"{self._winepath}/*") dirs = [d.replace(f"{self._winepath}/", "") for d in dirs] for p in promise: if p not in dirs: return False return True def check_arch_compatibility(self): ''' Check if the given wine arch is compatible with the running system TODO: this method should check for ARM wine compatibility on ARM devices ''' return def execute(self, command: str, comunicate: bool = False, envs: dict = {}, terminal: str = None): ''' Execute command inside wineprefix using the wine in winepath Parameters ---------- command : str command to be executed inside the wineprefix comunicate : bool, optional to get the output of the command (default is False) envs: dict, optional dict of environment variables to pass on the execution terminal : str, optional command to an external terminal (default is None) ''' envs["WINEPREFIX"] = self._wineprefix envs["WINEDEBUG"] = self._verbose_levels[self._verbose] command = f"{self._winepath}/bin/wine64 {command}" if terminal in self._terminals: command = self._terminals[terminal] % command cmd = Command( command=command, cwd=self._wineprefix, envs=envs ) if comunicate: return cmd.comunicate() return cmd.execute() ''' Setters ''' def set_verbose(self, level: int): if level not in self._verbose_levels: raise ValueError(f"{level} is not a valid verbose level.") else: self._verbose = self._verbose_levels[level] ''' Wine Tools ''' def winecfg(self): ''' Launch the winecfg tool on the active display. ''' self.execute(command="winecfg") def debug(self, terminal: str = None): ''' Launch the winedbg tool. Parameters ---------- terminal : str, optional command to an external terminal (default is None) ''' self.execute( command="winedbg", terminal=terminal ) def cmd(self, terminal: str = None): ''' Launch the cmd tool. Parameters ---------- terminal : str, optional command to an external terminal (default is None) ''' self.execute( command="cmd", terminal=terminal ) def taskmanager(self): ''' Launch the taskmgr tool on the active display. ''' self.execute(command="taskmgr") def controlpanel(self): ''' Launch the control tool on the active display. ''' self.execute(command="control") def uninstaller(self): ''' Launch the uninstaller tool on the active display. ''' self.execute(command="uninstaller") def regedit(self): ''' Launch the regedit tool on the active display. ''' self.execute(command="regedit") ''' Wine commandd execution ''' def command(self, command: str): ''' Execute custom wine commands inside the wineprefix. Parameters ---------- command : str the command to be executed ''' self.execute(command=command) def run_exe(self, executable_path: str, envs: dict = {}): ''' Execute exe files inside the wineprefix. executable_path : str full path to the .exe file envs: dict, optional dict of environment variables to pass on the execution ''' command = executable_path self.execute(command=command, envs=envs) def run_msi(self, msi_path: str, envs: dict = {}): ''' Execute msi files inside the wineprefix. msi_path : str full path to the .msi file envs: dict, optional dict of environment variables to pass on the execution ''' command = f"msiexec /i {msi_path}" self.execute(command=command, envs=envs) def run_bat(self, bat_path: str, envs: dict = {}): ''' Execute bat files inside the wineprefix. bat_path : str full path to the .bat file envs: dict, optional dict of environment variables to pass on the execution ''' command = f"wineconsole cmd /c '{bat_path}'" self.execute(command=command, envs=envs) ''' Wine uptime management ''' def __wineboot(self, status: int, silent: bool = True): ''' Manage Wine server uptime using wineboot Parameters ---------- status : int the state ID to set in wineboot: 0 (kill): Kill running processes without any cleanup 1 (restart): Restart only, don't do normal startup operations 2 (shutdown): Shutdown only, don't reboot 3 (update): Update the wineprefix directory silent: bool, optional if the command should not display on display (default True) Raises ------ Exception If the given state is invalid. ''' states = { 0: "-k", 1: "-r", 2: "-s", 3: "-u" } envs = {} if silent: envs["DISPLAY"] = ":0.0" if status in states: status = states[status] self.execute(command=f"wineboot {status}", envs=envs) else: raise ValueError(f"[{status}] is not a valid status for wineboot!") def kill(self): ''' Kill all processes running inside the wineprefix. ''' self.__wineboot(status=0) def restart(self): ''' Simulate system restart for the wineprefix, don't do normal startup operations. ''' self.__wineboot(status=1) def shutdown(self): ''' Simulate system shutdown for the wineprefix, don't reboot. ''' self.__wineboot(status=2) def update(self): ''' Update the wineprefix directory. ''' self.__wineboot(status=3, silent=True) ''' Wine process management ''' def processes(self): ''' Get processes running on the wineprefix. Return ------ list: A list of WineProcess. ''' processes = [] parent = None winedbg = self.execute( command='winedbg --command "info proc"', comunicate=True).split("\n") # remove the first line from the output (the header) del winedbg[0] for w in winedbg: w = re.sub("\s{2,}", " ", w)[1:].replace("'", "") if "\_" in w: w = w.replace("\_ ", "") w += " child" w = w.split(" ") w_parent = None if len(w) >= 3 and w[1].isdigit(): w_pid = w[0] w_threads = w[1] w_name = w[2] if len(w) == 3: parent = w_pid else: w_parent = parent w = WineProcess( pid=w_pid, name=w_name, parent_pid=w_parent, wine=self ) processes.append(w) return processes ''' Wine register management ''' def reg_list(self, key: str): ''' List all keys values from the wineprefix register. Parameters ---------- key : str the key name Return ------ list: A list of key values. ''' values = [] command = f'reg query "{key}" /f' output = self.execute( command=command, comunicate=True).split("\n") for o in output: if o.startswith(" "): o = re.sub(' +', '|', o[4:].replace("\r", "")) values.append(o.split("|")) return values def reg_add(self, key: str, value: str, data: str, data_type: int = 0): ''' Add (or edit) key to the wineprefix register. Parameters ---------- key : str the key name value : str the key value data : str the data to store in the key value data_type : int the type of data (default 0:REG_SZ): 0 (REG_SZ): standard string 1 (REG_DWORD): data by a four byte number 2 (REG_MULTI_SZ): multiple string 3 (REG_BINARY): data as raw binary data 4 (REG_EXPAND_SZ): expandable data string 5 (REG_NONE): no defined value type ''' if data_type not in self._reg_types: raise ValueError("Given key type is not supported.") data_type = self._reg_types.get(data_type) command = f'reg add "{key}" /v "{value}" /d "{data}" /t "{data_type}" /f' self.execute(command=command) def reg_delete(self, key: str, value: str): ''' Delete key from the wineprefix register. Parameters ---------- key : str the key name value : str the key value to be removed ''' command = f'reg delete "{key}" /v "{value}" /f' self.execute(command=command) ''' Simplified Wine register keys ''' def set_windows(self, version: str): ''' Change Windows version of the wineprefix. Parameters ---------- version : str the Windows version to be setted: win10 (Microsoft Windows 10) win81 (Microsoft Windows 8.1) win8 (Microsoft Windows 8) win7 (Microsoft Windows 7) win2008r2 (Microsoft Windows 2008 R1) win2008 (Microsoft Windows 2008) winxp (Microsoft Windows XP) Raises ------ ValueError If the given version is invalid. ''' if version not in self._windows_versions: raise ValueError("Given version is not supported.") self.reg_add( key="HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion", value="ProductName", data=self._windows_versions.get(version)["ProductName"] ) self.reg_add( key="HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion", value="CSDVersion", data=self._windows_versions.get(version)["CSDVersion"] ) self.reg_add( key="HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion", value="CurrentBuild", data=self._windows_versions.get(version)["CurrentBuild"] ) self.reg_add( key="HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion", value="CurrentBuildNumber", data=self._windows_versions.get(version)["CurrentBuildNumber"] ) self.reg_add( key="HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion", value="CurrentVersion", data=self._windows_versions.get(version)["CurrentVersion"] ) def set_virtual_desktop(self, status: bool, res: str = None): ''' Enable or disable the Wine Virtual Desktop. Parameters ---------- status : bool the Virtual Desktop status res : str (optional) the resolution to be used (e.g. 800x600) only if status is True ''' if status: self.reg_add( key="HKEY_CURRENT_USER\\Software\\Wine\\Explorer", value="Desktop", data="Default" ) self.reg_add( key="HKEY_CURRENT_USER\\Software\\Wine\\Explorer\\Desktops", value="Default", data=res ) else: self.reg_delete( key="HKEY_CURRENT_USER\\Software\\Wine\\Explorer", value="Desktop" ) def set_decorations(self, status: bool): ''' Enable or disable the windows manager decorations. Parameters ---------- status : bool the decorations status ''' if status: status = "Y" else: status = "N" self.reg_add( key="HKEY_CURRENT_USER\\Software\\Wine\\X11 Driver", value="Decorated", data=status ) def set_window_managed(self, status: bool): ''' Enable or disable the windows manager control. Parameters ---------- status : bool the control status ''' if status: status = "Y" else: status = "N" self.reg_add( key="HKEY_CURRENT_USER\\Software\\Wine\\X11 Driver", value="Managed", data=status ) def set_fullscreen_mouse_capture(self, status: bool): ''' Enable or disable auto mouse capture in fullscreen. Parameters ---------- status : bool the capture status ''' if status: status = "Y" else: status = "N" self.reg_add( key="HKEY_CURRENT_USER\\Software\\Wine\\X11 Driver", value="GrabbFullscreen", data=status ) def set_dpi(self, dpi: int): ''' Set custom DPI value. Parameters ---------- dpi : int the new density value ''' self.reg_add( key="HKEY_CURRENT_USER\\Control Panel\\Desktop", value="LogPixels", data=dpi, data_type=1 ) ''' Wine DLL overrides management ''' def override_dll_list(self): ''' List all DLL overrides in the wineprefix Return ------ list: A list of dll overrides. ''' overrides = [] values = self.reg_list( "HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides") for v in values: override = [v[0]] if v[2] == "native,builtin": override.append(3) elif v[2] == "builtin,native": override.append(2) elif v[2] == "native": override.append(1) elif v[2] == "builtin": override.append(0) overrides.append(override) return overrides def override_dll(self, name: str, override: int = 0, restore: bool = False): ''' Overriding a DLL in the wineprefix. Parameters ---------- name : str the name of the DLL override : int the type of override (default 0:builtin): 0 (builtin): provided by Wine 1 (native): provided by Windows 2 (builtin/native): builtin then native 3 (native/builtin): native then builtin restore : bool (optional) restore the override to the initiale state (default False) ''' if override not in self._dll_overrides: raise ValueError("Given override type is not supported.") if not restore: self.reg_add( key="HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides", value=name, data=self._dll_overrides.get(override) ) else: self.reg_delete( key="HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides", value=name )
Subclasses
Methods
def check_arch_compatibility(self)
-
Check if the given wine arch is compatible with the running system TODO: this method should check for ARM wine compatibility on ARM devices
Expand source code
def check_arch_compatibility(self): ''' Check if the given wine arch is compatible with the running system TODO: this method should check for ARM wine compatibility on ARM devices ''' return
def cmd(self, terminal: str = None)
-
Launch the cmd tool.
Parameters
terminal
:str
, optional- command to an external terminal (default is None)
Expand source code
def cmd(self, terminal: str = None): ''' Launch the cmd tool. Parameters ---------- terminal : str, optional command to an external terminal (default is None) ''' self.execute( command="cmd", terminal=terminal )
def command(self, command: str)
-
Execute custom wine commands inside the wineprefix.
Parameters
command
:str
- the command to be executed
Expand source code
def command(self, command: str): ''' Execute custom wine commands inside the wineprefix. Parameters ---------- command : str the command to be executed ''' self.execute(command=command)
def controlpanel(self)
-
Launch the control tool on the active display.
Expand source code
def controlpanel(self): ''' Launch the control tool on the active display. ''' self.execute(command="control")
def debug(self, terminal: str = None)
-
Launch the winedbg tool.
Parameters
terminal
:str
, optional- command to an external terminal (default is None)
Expand source code
def debug(self, terminal: str = None): ''' Launch the winedbg tool. Parameters ---------- terminal : str, optional command to an external terminal (default is None) ''' self.execute( command="winedbg", terminal=terminal )
def execute(self, command: str, comunicate: bool = False, envs: dict = {}, terminal: str = None)
-
Execute command inside wineprefix using the wine in winepath
Parameters
command
:str
- command to be executed inside the wineprefix
comunicate
:bool
, optional- to get the output of the command (default is False)
envs
:dict
, optional- dict of environment variables to pass on the execution
terminal
:str
, optional- command to an external terminal (default is None)
Expand source code
def execute(self, command: str, comunicate: bool = False, envs: dict = {}, terminal: str = None): ''' Execute command inside wineprefix using the wine in winepath Parameters ---------- command : str command to be executed inside the wineprefix comunicate : bool, optional to get the output of the command (default is False) envs: dict, optional dict of environment variables to pass on the execution terminal : str, optional command to an external terminal (default is None) ''' envs["WINEPREFIX"] = self._wineprefix envs["WINEDEBUG"] = self._verbose_levels[self._verbose] command = f"{self._winepath}/bin/wine64 {command}" if terminal in self._terminals: command = self._terminals[terminal] % command cmd = Command( command=command, cwd=self._wineprefix, envs=envs ) if comunicate: return cmd.comunicate() return cmd.execute()
def kill(self)
-
Kill all processes running inside the wineprefix.
Expand source code
def kill(self): ''' Kill all processes running inside the wineprefix. ''' self.__wineboot(status=0)
def override_dll(self, name: str, override: int = 0, restore: bool = False)
-
Overriding a DLL in the wineprefix.
Parameters
name
:str
- the name of the DLL
override
:int
- the type of override (default 0:builtin): 0 (builtin): provided by Wine 1 (native): provided by Windows 2 (builtin/native): builtin then native 3 (native/builtin): native then builtin
restore
:bool (optional)
- restore the override to the initiale state (default False)
Expand source code
def override_dll(self, name: str, override: int = 0, restore: bool = False): ''' Overriding a DLL in the wineprefix. Parameters ---------- name : str the name of the DLL override : int the type of override (default 0:builtin): 0 (builtin): provided by Wine 1 (native): provided by Windows 2 (builtin/native): builtin then native 3 (native/builtin): native then builtin restore : bool (optional) restore the override to the initiale state (default False) ''' if override not in self._dll_overrides: raise ValueError("Given override type is not supported.") if not restore: self.reg_add( key="HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides", value=name, data=self._dll_overrides.get(override) ) else: self.reg_delete( key="HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides", value=name )
def override_dll_list(self)
-
List all DLL overrides in the wineprefix
Return
list: A list of dll overrides.
Expand source code
def override_dll_list(self): ''' List all DLL overrides in the wineprefix Return ------ list: A list of dll overrides. ''' overrides = [] values = self.reg_list( "HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides") for v in values: override = [v[0]] if v[2] == "native,builtin": override.append(3) elif v[2] == "builtin,native": override.append(2) elif v[2] == "native": override.append(1) elif v[2] == "builtin": override.append(0) overrides.append(override) return overrides
def processes(self)
-
Get processes running on the wineprefix.
Return
list: A list of WineProcess.
Expand source code
def processes(self): ''' Get processes running on the wineprefix. Return ------ list: A list of WineProcess. ''' processes = [] parent = None winedbg = self.execute( command='winedbg --command "info proc"', comunicate=True).split("\n") # remove the first line from the output (the header) del winedbg[0] for w in winedbg: w = re.sub("\s{2,}", " ", w)[1:].replace("'", "") if "\_" in w: w = w.replace("\_ ", "") w += " child" w = w.split(" ") w_parent = None if len(w) >= 3 and w[1].isdigit(): w_pid = w[0] w_threads = w[1] w_name = w[2] if len(w) == 3: parent = w_pid else: w_parent = parent w = WineProcess( pid=w_pid, name=w_name, parent_pid=w_parent, wine=self ) processes.append(w) return processes
def reg_add(self, key: str, value: str, data: str, data_type: int = 0)
-
Add (or edit) key to the wineprefix register.
Parameters
key
:str
- the key name
value
:str
- the key value
data
:str
- the data to store in the key value
data_type
:int
- the type of data (default 0:REG_SZ): 0 (REG_SZ): standard string 1 (REG_DWORD): data by a four byte number 2 (REG_MULTI_SZ): multiple string 3 (REG_BINARY): data as raw binary data 4 (REG_EXPAND_SZ): expandable data string 5 (REG_NONE): no defined value type
Expand source code
def reg_add(self, key: str, value: str, data: str, data_type: int = 0): ''' Add (or edit) key to the wineprefix register. Parameters ---------- key : str the key name value : str the key value data : str the data to store in the key value data_type : int the type of data (default 0:REG_SZ): 0 (REG_SZ): standard string 1 (REG_DWORD): data by a four byte number 2 (REG_MULTI_SZ): multiple string 3 (REG_BINARY): data as raw binary data 4 (REG_EXPAND_SZ): expandable data string 5 (REG_NONE): no defined value type ''' if data_type not in self._reg_types: raise ValueError("Given key type is not supported.") data_type = self._reg_types.get(data_type) command = f'reg add "{key}" /v "{value}" /d "{data}" /t "{data_type}" /f' self.execute(command=command)
def reg_delete(self, key: str, value: str)
-
Delete key from the wineprefix register.
Parameters
key
:str
- the key name
value
:str
- the key value to be removed
Expand source code
def reg_delete(self, key: str, value: str): ''' Delete key from the wineprefix register. Parameters ---------- key : str the key name value : str the key value to be removed ''' command = f'reg delete "{key}" /v "{value}" /f' self.execute(command=command)
def reg_list(self, key: str)
-
List all keys values from the wineprefix register.
Parameters
key
:str
- the key name
Return
list: A list of key values.
Expand source code
def reg_list(self, key: str): ''' List all keys values from the wineprefix register. Parameters ---------- key : str the key name Return ------ list: A list of key values. ''' values = [] command = f'reg query "{key}" /f' output = self.execute( command=command, comunicate=True).split("\n") for o in output: if o.startswith(" "): o = re.sub(' +', '|', o[4:].replace("\r", "")) values.append(o.split("|")) return values
def regedit(self)
-
Launch the regedit tool on the active display.
Expand source code
def regedit(self): ''' Launch the regedit tool on the active display. ''' self.execute(command="regedit")
def restart(self)
-
Simulate system restart for the wineprefix, don't do normal startup operations.
Expand source code
def restart(self): ''' Simulate system restart for the wineprefix, don't do normal startup operations. ''' self.__wineboot(status=1)
def run_bat(self, bat_path: str, envs: dict = {})
-
Execute bat files inside the wineprefix. bat_path : str full path to the .bat file envs: dict, optional dict of environment variables to pass on the execution
Expand source code
def run_bat(self, bat_path: str, envs: dict = {}): ''' Execute bat files inside the wineprefix. bat_path : str full path to the .bat file envs: dict, optional dict of environment variables to pass on the execution ''' command = f"wineconsole cmd /c '{bat_path}'" self.execute(command=command, envs=envs)
def run_exe(self, executable_path: str, envs: dict = {})
-
Execute exe files inside the wineprefix. executable_path : str full path to the .exe file envs: dict, optional dict of environment variables to pass on the execution
Expand source code
def run_exe(self, executable_path: str, envs: dict = {}): ''' Execute exe files inside the wineprefix. executable_path : str full path to the .exe file envs: dict, optional dict of environment variables to pass on the execution ''' command = executable_path self.execute(command=command, envs=envs)
def run_msi(self, msi_path: str, envs: dict = {})
-
Execute msi files inside the wineprefix. msi_path : str full path to the .msi file envs: dict, optional dict of environment variables to pass on the execution
Expand source code
def run_msi(self, msi_path: str, envs: dict = {}): ''' Execute msi files inside the wineprefix. msi_path : str full path to the .msi file envs: dict, optional dict of environment variables to pass on the execution ''' command = f"msiexec /i {msi_path}" self.execute(command=command, envs=envs)
def set_decorations(self, status: bool)
-
Enable or disable the windows manager decorations.
Parameters
status
:bool
- the decorations status
Expand source code
def set_decorations(self, status: bool): ''' Enable or disable the windows manager decorations. Parameters ---------- status : bool the decorations status ''' if status: status = "Y" else: status = "N" self.reg_add( key="HKEY_CURRENT_USER\\Software\\Wine\\X11 Driver", value="Decorated", data=status )
def set_dpi(self, dpi: int)
-
Set custom DPI value.
Parameters
dpi
:int
- the new density value
Expand source code
def set_dpi(self, dpi: int): ''' Set custom DPI value. Parameters ---------- dpi : int the new density value ''' self.reg_add( key="HKEY_CURRENT_USER\\Control Panel\\Desktop", value="LogPixels", data=dpi, data_type=1 )
def set_fullscreen_mouse_capture(self, status: bool)
-
Enable or disable auto mouse capture in fullscreen.
Parameters
status
:bool
- the capture status
Expand source code
def set_fullscreen_mouse_capture(self, status: bool): ''' Enable or disable auto mouse capture in fullscreen. Parameters ---------- status : bool the capture status ''' if status: status = "Y" else: status = "N" self.reg_add( key="HKEY_CURRENT_USER\\Software\\Wine\\X11 Driver", value="GrabbFullscreen", data=status )
def set_verbose(self, level: int)
-
Expand source code
def set_verbose(self, level: int): if level not in self._verbose_levels: raise ValueError(f"{level} is not a valid verbose level.") else: self._verbose = self._verbose_levels[level]
def set_virtual_desktop(self, status: bool, res: str = None)
-
Enable or disable the Wine Virtual Desktop.
Parameters
status
:bool
- the Virtual Desktop status
res
:str (optional)
- the resolution to be used (e.g. 800x600) only if status is True
Expand source code
def set_virtual_desktop(self, status: bool, res: str = None): ''' Enable or disable the Wine Virtual Desktop. Parameters ---------- status : bool the Virtual Desktop status res : str (optional) the resolution to be used (e.g. 800x600) only if status is True ''' if status: self.reg_add( key="HKEY_CURRENT_USER\\Software\\Wine\\Explorer", value="Desktop", data="Default" ) self.reg_add( key="HKEY_CURRENT_USER\\Software\\Wine\\Explorer\\Desktops", value="Default", data=res ) else: self.reg_delete( key="HKEY_CURRENT_USER\\Software\\Wine\\Explorer", value="Desktop" )
def set_window_managed(self, status: bool)
-
Enable or disable the windows manager control.
Parameters
status
:bool
- the control status
Expand source code
def set_window_managed(self, status: bool): ''' Enable or disable the windows manager control. Parameters ---------- status : bool the control status ''' if status: status = "Y" else: status = "N" self.reg_add( key="HKEY_CURRENT_USER\\Software\\Wine\\X11 Driver", value="Managed", data=status )
def set_windows(self, version: str)
-
Change Windows version of the wineprefix.
Parameters
version
:str
- the Windows version to be setted: win10 (Microsoft Windows 10) win81 (Microsoft Windows 8.1) win8 (Microsoft Windows 8) win7 (Microsoft Windows 7) win2008r2 (Microsoft Windows 2008 R1) win2008 (Microsoft Windows 2008) winxp (Microsoft Windows XP)
Raises
ValueError
- If the given version is invalid.
Expand source code
def set_windows(self, version: str): ''' Change Windows version of the wineprefix. Parameters ---------- version : str the Windows version to be setted: win10 (Microsoft Windows 10) win81 (Microsoft Windows 8.1) win8 (Microsoft Windows 8) win7 (Microsoft Windows 7) win2008r2 (Microsoft Windows 2008 R1) win2008 (Microsoft Windows 2008) winxp (Microsoft Windows XP) Raises ------ ValueError If the given version is invalid. ''' if version not in self._windows_versions: raise ValueError("Given version is not supported.") self.reg_add( key="HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion", value="ProductName", data=self._windows_versions.get(version)["ProductName"] ) self.reg_add( key="HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion", value="CSDVersion", data=self._windows_versions.get(version)["CSDVersion"] ) self.reg_add( key="HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion", value="CurrentBuild", data=self._windows_versions.get(version)["CurrentBuild"] ) self.reg_add( key="HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion", value="CurrentBuildNumber", data=self._windows_versions.get(version)["CurrentBuildNumber"] ) self.reg_add( key="HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion", value="CurrentVersion", data=self._windows_versions.get(version)["CurrentVersion"] )
def shutdown(self)
-
Simulate system shutdown for the wineprefix, don't reboot.
Expand source code
def shutdown(self): ''' Simulate system shutdown for the wineprefix, don't reboot. ''' self.__wineboot(status=2)
def taskmanager(self)
-
Launch the taskmgr tool on the active display.
Expand source code
def taskmanager(self): ''' Launch the taskmgr tool on the active display. ''' self.execute(command="taskmgr")
def uninstaller(self)
-
Launch the uninstaller tool on the active display.
Expand source code
def uninstaller(self): ''' Launch the uninstaller tool on the active display. ''' self.execute(command="uninstaller")
def update(self)
-
Update the wineprefix directory.
Expand source code
def update(self): ''' Update the wineprefix directory. ''' self.__wineboot(status=3, silent=True)
def winecfg(self)
-
Launch the winecfg tool on the active display.
Expand source code
def winecfg(self): ''' Launch the winecfg tool on the active display. ''' self.execute(command="winecfg")