Skip to content

Commit bb698cf

Browse files
committed
add activateMatlab.py script
This is useful for when Matlab can't start due to needing license reactivation need to resolve path before taking parent in case of symlink
1 parent 29daf3e commit bb698cf

File tree

2 files changed

+140
-0
lines changed

2 files changed

+140
-0
lines changed

pyproject.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[tool.black]
2+
line-length = 100

scripts/activateMatlab.py

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
#!/usr/bin/env python3
2+
"""
3+
When institutional network Matlab licenses are renewed,
4+
Matlab might not be startable to reactivate the license.
5+
Hence we have a convenient Python script to find the MathWorksProductAuthorizer
6+
program used to re-activate the Matlab license.
7+
8+
After running the MathWorksProductAuthorizer executable found by this script,
9+
Matlab should be able to start again.
10+
If license error 5201 still occurs upon starting Matlab, try rebooting the computer.
11+
This might be necessary because the Matlab service might be used in the background by other programs
12+
like Visual Studio Code or JupyterLab.
13+
"""
14+
15+
import shutil
16+
import os
17+
import argparse
18+
from pathlib import Path
19+
import logging
20+
import platform
21+
22+
try:
23+
import winreg
24+
except ModuleNotFoundError:
25+
winreg = None # type: ignore[assignment]
26+
27+
28+
def _registry_search(release: str) -> Path | None:
29+
try:
30+
# must use "\" as path separator in Windows registry
31+
matlab_path = winreg.QueryValue(
32+
winreg.HKEY_LOCAL_MACHINE, rf"SOFTWARE\MathWorks\{release}\MATLAB"
33+
)
34+
35+
return Path(matlab_path)
36+
except (AttributeError, OSError) as e:
37+
logging.debug(f"Registry key not found {e}, falling back to ProgramFiles search.")
38+
return None
39+
40+
41+
def _windows_search(release: str) -> Path | None:
42+
"""Look at Windows registry, Program Files, Path for Matlab installation."""
43+
44+
if winreg is not None:
45+
if (p := _registry_search(release)) is not None and p.is_dir():
46+
logging.info(f"Using Matlab from registry: {p}")
47+
return p
48+
49+
if (r := os.environ.get("ProgramFiles")) is not None:
50+
if (p := Path(r) / "MATLAB" / release / "bin/win64").is_dir():
51+
logging.info(f"Using Matlab from ProgramFiles: {p}")
52+
return p
53+
54+
tail = "win64"
55+
56+
if (r := shutil.which("matlab")) is not None:
57+
if (p := Path(r).resolve().parent / tail).is_dir():
58+
logging.info(f"Using Matlab from PATH: {p}")
59+
return p
60+
61+
return None
62+
63+
64+
def _macos_search(release: str) -> Path | None:
65+
"""Search for Matlab in common macOS application directories."""
66+
67+
arch = platform.machine()
68+
match (arch):
69+
case "x86_64":
70+
tail = "maci64"
71+
case "arm64":
72+
tail = "maca64"
73+
case _:
74+
raise SystemExit(f"ERROR: Unsupported architecture for macOS {arch}.")
75+
76+
roots = ["~/Applications", "/Applications"]
77+
for root in roots:
78+
if (p := Path(root).expanduser() / f"MATLAB_{release}.app" / "bin" / tail).is_dir():
79+
return p
80+
81+
if (r := shutil.which("matlab")) is not None:
82+
if (p := Path(r).resolve().parent / tail).is_dir():
83+
logging.info(f"Using Matlab from PATH: {p}")
84+
return p
85+
86+
return None
87+
88+
89+
def _linux_search(release: str) -> Path | None:
90+
91+
tail = "glnxa64"
92+
93+
if (r := shutil.which("matlab")) is not None:
94+
if (p := Path(r).resolve().parent / tail).is_dir():
95+
logging.info(f"Using Matlab from PATH: {p}")
96+
return p
97+
98+
return None
99+
100+
101+
def find_activate_matlab(release: str) -> str | None:
102+
"""
103+
Fallback to PATH if the platform-specific search fails.
104+
Linux doesn't have a platform-specific search.
105+
"""
106+
name = "MathWorksProductAuthorizer"
107+
108+
mr = None
109+
110+
match (os.name):
111+
case "nt":
112+
mr = _windows_search(release)
113+
case "darwin":
114+
mr = _macos_search(release)
115+
case _:
116+
mr = _linux_search(release)
117+
118+
return shutil.which(name, path=mr)
119+
120+
121+
if __name__ == "__main__":
122+
parser = argparse.ArgumentParser(description="Find the MathWorksProductAuthorizer executable.")
123+
parser.add_argument(
124+
"release",
125+
type=str,
126+
help="Specify the MATLAB version to search for (e.g., R2023a)",
127+
default=None,
128+
)
129+
parser.add_argument("-v", "--verbose", action="store_true", help="Enable verbose output")
130+
args = parser.parse_args()
131+
132+
if args.verbose:
133+
logging.basicConfig(level=logging.DEBUG)
134+
135+
exe = find_activate_matlab(args.release)
136+
137+
print("This program can reactivate the Matlab license if authorized:\n")
138+
print(exe)

0 commit comments

Comments
 (0)