Skip to content

Commit c734133

Browse files
author
codefl0w
committed
Get rid of OpenSSL (not a dependency anymore), fix VS issue and overall code cleanup
1 parent 96c3cbc commit c734133

1 file changed

Lines changed: 40 additions & 140 deletions

File tree

mtkclient_installer.py

Lines changed: 40 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
from PyQt6 import QtCore, QtWidgets, QtGui
2121

22-
VERSION = "V1.1.0"
22+
VERSION = "V1.2.0"
2323
LOGFILE = Path(os.getenv("TEMP") or tempfile.gettempdir()) / f"mtkclient_installer_{VERSION}.log"
2424
TIMEOUT_WINGET = 60 * 30
2525
TIMEOUT_VS = 60 * 60
@@ -104,22 +104,6 @@ def resource_path(relative: str) -> str:
104104
return os.path.join(os.path.abspath("."), relative)
105105

106106

107-
def _choose_download_dest_from_headers(url: str, fallback_name: str, timeout_head: float = 8.0) -> str:
108-
try:
109-
req = urllib.request.Request(url, method="HEAD", headers={"User-Agent": "mtkclient-installer/1.0"})
110-
with urllib.request.urlopen(req, timeout=timeout_head) as head:
111-
cd = head.getheader("Content-Disposition")
112-
if cd:
113-
m = re.search(r'filename\*?=(?:UTF-8\'\')?["\']?([^"\';]+)', cd)
114-
if m:
115-
return m.group(1)
116-
except Exception:
117-
pass
118-
119-
parsed = urllib.parse.urlparse(url)
120-
name = Path(parsed.path).name
121-
return name or fallback_name
122-
123107

124108
def get_user_runtime_dir(appname: str = "mtkclient") -> Path:
125109
base = os.getenv("LOCALAPPDATA") or os.getenv("APPDATA") or str(Path.home())
@@ -242,7 +226,6 @@ def _setup_steps(self):
242226
("Install Git & Python 3.1x", self.step_install_git_python),
243227
("Refresh Environment PATH", self.step_refresh_path),
244228
("Install WinFsp and UsbDk", self.step_install_winfsp_usbdk),
245-
("Install OpenSSL 1.1.1", self.step_install_openssl),
246229
("Install Visual Studio Build Tools", self.step_install_build_tools),
247230
("Clone mtkclient Repo", self.step_clone_repo),
248231
("Install Python Requirements", self.step_pip_install_requirements),
@@ -268,25 +251,36 @@ def _run_proc(self, cmd: List[str], cwd: Optional[str] = None,
268251

269252
def reader(pipe, collector, prefix):
270253
try:
254+
buffer = ""
271255
while True:
272-
line = pipe.readline()
273-
if line:
274-
collector.append(line)
275-
self.log_debug.emit(prefix + line)
276-
m = PCT_RE.search(line)
277-
if m:
278-
try:
279-
pct = int(m.group(1))
280-
if 0 <= pct <= 100:
281-
self.current_progress_changed.emit(pct)
282-
except Exception:
283-
pass
284-
else:
256+
char = pipe.read(1)
257+
if not char:
285258
if proc.poll() is not None or self._stop_requested:
286259
break
287260
if stop_time and time.time() > stop_time:
288261
break
289-
time.sleep(0.05)
262+
time.sleep(0.01)
263+
continue
264+
265+
buffer += char
266+
267+
# Process on newline or carriage return
268+
if char in ('\n', '\r'):
269+
if buffer.strip():
270+
line = buffer
271+
collector.append(line)
272+
self.log_debug.emit(prefix + line)
273+
274+
# Extract percentage
275+
m = PCT_RE.search(line)
276+
if m:
277+
try:
278+
pct = int(m.group(1))
279+
if 0 <= pct <= 100:
280+
self.current_progress_changed.emit(pct)
281+
except Exception:
282+
pass
283+
buffer = ""
290284
except Exception:
291285
pass
292286

@@ -705,6 +699,7 @@ def get_ver(cmd_list): # version string helper
705699
return False, "winget not available"
706700

707701
# Refresh sources
702+
708703
self.log_summary.emit("Refreshing winget sources...\n")
709704
self._run_proc(["winget", "source", "update"], None, timeout=120)
710705

@@ -755,7 +750,12 @@ def get_ver(cmd_list): # version string helper
755750
self.log_summary.emit(f"Verified Python: {new_py_ver}\n")
756751
else:
757752
# If winget succeeded but we can't find it, it's a PATH refresh issue
758-
return False, "Python installed but system PATH is not refreshed. Please reboot and try again."
753+
refresh_environment_path()
754+
find_python_executable() # last attempt. Won't change the result but may help with debugging
755+
return False, "Python installed but isn't in PATH, please retry step or reboot."
756+
757+
758+
759759

760760
return True, "Git and Python setup successful"
761761

@@ -789,101 +789,7 @@ def step_install_winfsp_usbdk(self) -> Tuple[bool, str]:
789789
self.log_summary.emit(f"Warning: WinFsp install returned {res.exitcode}\n")
790790
return True, "WinFsp/UsbDk step completed"
791791

792-
def step_install_openssl(self) -> Tuple[bool, str]:
793-
# Install OpenSSL 1.1.1 with multiple fallback methods
794-
# Check if already installed
795-
candidates = [
796-
Path(r"C:\OpenSSL-Win64"),
797-
Path(r"C:\Program Files\OpenSSL-Win64"),
798-
Path(os.environ.get("ProgramFiles", "")) / "OpenSSL-Win64",
799-
]
800-
for c in candidates:
801-
if c.exists():
802-
return True, f"OpenSSL found at {c}"
803792

804-
# Method 1: Try winget with known package IDs
805-
if shutil.which("winget"):
806-
self.log_summary.emit("Installing OpenSSL via winget...\n")
807-
for pkg_id in ["ShiningLight.OpenSSL", "ShiningLight.OpenSSL.Light"]:
808-
res = self._run_proc(
809-
["winget", "install", "--id", pkg_id, "-e",
810-
"--accept-package-agreements", "--accept-source-agreements"],
811-
None, timeout=TIMEOUT_WINGET
812-
)
813-
if res.exitcode in [0, 3010]:
814-
if res.exitcode == 3010:
815-
self._needs_reboot = True
816-
return True, f"OpenSSL installed via winget ({pkg_id})"
817-
818-
# Method 2: Search winget for OpenSSL packages
819-
self.log_debug.emit(timestamped("[OPENSSL] Searching winget catalog...\n"))
820-
search = self._run_proc(["winget", "search", "openssl"], None, timeout=60)
821-
found_ids = set()
822-
for line in (search.stdout or "").splitlines():
823-
for token in line.strip().split()[:3]:
824-
if "." in token and "openssl" in token.lower() and len(token) > 4:
825-
found_ids.add(token)
826-
827-
for pkg_id in found_ids:
828-
self.log_summary.emit(f"Trying: {pkg_id}\n")
829-
res = self._run_proc(
830-
["winget", "install", "--id", pkg_id, "-e",
831-
"--accept-package-agreements", "--accept-source-agreements"],
832-
None, timeout=TIMEOUT_WINGET
833-
)
834-
if res.exitcode in [0, 3010]:
835-
if res.exitcode == 3010:
836-
self._needs_reboot = True
837-
return True, f"OpenSSL installed via winget ({pkg_id})"
838-
839-
# Method 3: Direct download fallback
840-
self.log_summary.emit("Attempting direct download...\n")
841-
urls = [
842-
"https://slproweb.com/download/Win64OpenSSL-1_1_1u.exe",
843-
"https://slproweb.com/download/Win64OpenSSL-1_1_1u-x64.exe",
844-
"https://sourceforge.net/projects/openssl-for-windows/files/latest/download",
845-
]
846-
847-
tempdir = Path(os.getenv("TEMP") or tempfile.gettempdir())
848-
for url in urls:
849-
# Get proper filename from headers and validate
850-
filename = _choose_download_dest_from_headers(url, "Win64OpenSSL-installer.exe")
851-
dest = tempdir / filename
852-
853-
# Retry wrapper for this specific URL
854-
def attempt_download():
855-
return self._download_with_progress(url, dest, timeout=TIMEOUT_DOWNLOAD)
856-
857-
self.log_summary.emit(f"Attempting download from {url} (up to 3 retries)...\n")
858-
success, msg = _download_with_retry(attempt_download, max_attempts=3, base_delay=2.0)
859-
860-
if not success:
861-
self.log_summary.emit(f"All download attempts failed for {url}: {msg}\n")
862-
continue
863-
864-
# ensure we actually downloaded an .exe/.msi
865-
if dest.suffix.lower() not in (".exe", ".msi"):
866-
self.log_debug.emit(f"[OPENSSL] downloaded file {dest} is not an executable; removing and skipping.\n")
867-
try:
868-
dest.unlink()
869-
except Exception:
870-
pass
871-
continue
872-
873-
# Try installation with silent flags
874-
for flags in [["/verysilent", "/sp-", "/norestart"], ["/S"]]:
875-
res = self._run_proc([str(dest)] + flags, None, timeout=TIMEOUT_DOWNLOAD)
876-
try:
877-
dest.unlink()
878-
except:
879-
pass
880-
881-
if res.exitcode in [0, 3010]:
882-
if res.exitcode == 3010:
883-
self._needs_reboot = True
884-
return True, "OpenSSL installed via direct download"
885-
886-
return False, "All OpenSSL installation methods failed. Please install manually from slproweb.com"
887793

888794
def step_install_build_tools(self) -> Tuple[bool, str]:
889795
# check vcvars64.bat presence
@@ -919,7 +825,10 @@ def step_install_build_tools(self) -> Tuple[bool, str]:
919825

920826
if not shutil.which("winget"):
921827
return False, "winget not present"
922-
828+
829+
self.log_summary.emit("Ensuring Winget health...\n")
830+
subprocess.run(["winget", "source", "reset", "--force"], capture_output=True)
831+
subprocess.run(["winget", "source", "update"], capture_output=True)
923832
self.log_summary.emit(
924833
"Installing Visual Studio Build Tools (Desktop C++ workload).\n"
925834
)
@@ -1085,21 +994,12 @@ def step_pip_install_requirements(self) -> Tuple[bool, str]:
1085994
None, timeout=300
1086995
)
1087996

1088-
# Configure OpenSSL environment for compilation
1089-
env = os.environ.copy()
1090-
for openssl_dir in [r"C:\OpenSSL-Win64", r"C:\Program Files\OpenSSL-Win64"]:
1091-
if Path(openssl_dir).exists():
1092-
env["INCLUDE"] = env.get("INCLUDE", "") + ";" + os.path.join(openssl_dir, "include")
1093-
env["LIB"] = env.get("LIB", "") + ";" + os.path.join(openssl_dir, "lib")
1094-
env["PATH"] = env.get("PATH", "") + ";" + os.path.join(openssl_dir, "bin")
1095-
self.log_summary.emit(f"Using OpenSSL from: {openssl_dir}\n")
1096-
break
1097997

1098998
# Install requirements
1099999
self.log_summary.emit("Installing Python packages (this may take several minutes)...\n")
11001000
res = self._run_proc(
11011001
[py_exec, "-m", "pip", "install", "-r", str(reqs)],
1102-
str(reqs.parent), env=env, timeout=PIP_TIMEOUT
1002+
str(reqs.parent), env=None, timeout=PIP_TIMEOUT
11031003
)
11041004

11051005
if res.exitcode == 0:
@@ -1327,7 +1227,7 @@ def show_about(self):
13271227
about_text = f"""
13281228
<h3>MTKClient Windows Installer</h3>
13291229
<p>
1330-
<b>Version:</b> {VERSION} (290120261511)<br>
1230+
<b>Version:</b> {VERSION} (0606220262110)<br>
13311231
<b>Developer:</b>
13321232
<a href="https://github.com/codefl0w">fl0w</a>
13331233
</p>
@@ -1351,7 +1251,7 @@ def show_about(self):
13511251
</li>
13521252
<li style="margin-top: 8px;">
13531253
<b>Other Components:</b><br>
1354-
Git, Python, OpenSSL, Visual Studio Build Tools, WinFsp, and UsbDk
1254+
Git, Python, Visual Studio Build Tools, WinFsp, and UsbDk
13551255
are trademarks and products of their respective owners and are
13561256
distributed under their own licenses.
13571257
</li>

0 commit comments

Comments
 (0)