fix: windows service installation for py3.13

This commit is contained in:
2026-02-09 11:28:08 +08:00
parent 3ba61b4cbf
commit db13c68161
17 changed files with 22 additions and 2051 deletions

View File

@ -1,15 +0,0 @@
{
"permissions": {
"allow": [
"Bash(poetry init:*)",
"Bash(mkdir:*)",
"Bash(python:*)",
"Bash(poetry run python:*)",
"Bash(del test_upgrade.py)",
"Bash(git add .)",
"Bash(git commit -m \"Initial commit with Python .gitignore\")"
],
"deny": [],
"ask": []
}
}

View File

@ -1,8 +0,0 @@
# Code style
- Use type hinting everywhere
- Use pydantic based models instead of dict
- Adopt Inversion of Control pattern whenever possible, use constructor injection for class, extract pure function if it has to depend on some global variable
# Workflow
- Be sure to typecheck when youre done making a series of code changes
- Be sure to update README.md after making code changes

View File

@ -15,8 +15,9 @@ A Python package for surfing internet scientifically.
```bash ```bash
git clone ssh://git@gitea.epss.net.cn:2223/klesh/ss.git git clone ssh://git@gitea.epss.net.cn:2223/klesh/ss.git
cd ss cd ss
brew install poetry python -m venv .venv
poetry config --local virtualenvs.in-project true ./.venv/Scripts/activate
pip install -r requirements.txt
``` ```
### 2. Add the root directory to system PATH ### 2. Add the root directory to system PATH

View File

@ -1,96 +0,0 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "4dbde0c5",
"metadata": {},
"outputs": [],
"source": [
"import yaml\n",
"\n",
"\n",
"with open(r'C:\\Users\\Klesh\\basicfiles\\cli\\scientific_surfing\\generated_config.yaml', 'r', encoding=\"utf-8\") as f:\n",
" config = yaml.safe_load(f)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "16e45ae8",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'cipher': 'rc4-md5', 'name': 'taiwan06', 'obfs': 'plain', 'obfs-param': '2c9120876.douyin.com', 'password': 'di15PV', 'port': 6506, 'protocol': 'auth_aes128_md5', 'protocol-param': '120876:VCgmuD', 'server': 'cdn02.0821.meituan88.com', 'type': 'ssr', 'udp': True}\n"
]
}
],
"source": [
"server = next(filter(lambda p: \"台湾06\" in p[\"name\"], config[\"proxies\"]))\n",
"server[\"name\"] = \"taiwan06\"\n",
"print(server)\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "cc472edc",
"metadata": {},
"outputs": [],
"source": [
"config2 = config.copy()"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "3db89abe",
"metadata": {},
"outputs": [],
"source": [
"config2[\"proxies\"] = [server]\n",
"config2[\"proxy-groups\"] = {\n",
" \"name\": \"defaultgroup\",\n",
" \"type\": \"select\",\n",
" \"proxies\": [server[\"name\"]],\n",
"}\n",
"config2[\"rules\"] = config[\"rules\"][:17]"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "2630b0fc",
"metadata": {},
"outputs": [],
"source": [
"with open(r'C:\\Users\\Klesh\\basicfiles\\cli\\scientific_surfing\\simple.yaml', 'w', encoding=\"utf-8\") as f:\n",
" yaml.dump(config2, f, default_flow_style=False, allow_unicode=True)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "scientific-surfing-4fYWmyKm-py3.12",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

1780
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,2 +0,0 @@
[virtualenvs]
in-project = true

View File

@ -1,28 +1,3 @@
[tool.poetry]
name = "ss"
version = "0.1.0"
description = "A Python package for surfing the internet scientifically"
authors = ["Scientific Surfing Team <team@scientific-surfing.com>"]
readme = "README.md"
packages = [{include = "ss"}]
[tool.poetry.dependencies]
python = "^3.9"
requests = "^2.25.0"
PyYAML = "^6.0.0"
pydantic = "^2.0.0"
ipykernel = "^6.31.0"
[tool.poetry.group.dev.dependencies]
pytest = "^6.0.0"
pytest-cov = "^2.0.0"
black = "^21.0.0"
flake8 = "^3.8.0"
[build-system]
requires = ["poetry-core>=2.0.0,<3.0.0"]
build-backend = "poetry.core.masonry.api"
[tool.black] [tool.black]
line-length = 88 line-length = 88
target-version = ['py38'] target-version = ['py38']

4
requirements-dev.txt Normal file
View File

@ -0,0 +1,4 @@
pytest>=6.0.0
pytest-cov>=2.0.0
black>=21.0.0
flake8>=3.8.0

1
requirements-win32.txt Normal file
View File

@ -0,0 +1 @@
pywin32

4
requirements.txt Normal file
View File

@ -0,0 +1,4 @@
requests>=2.25.0
PyYAML>=6.0.0
pydantic>=2.0.0
ipykernel>=6.31.0

View File

@ -166,7 +166,7 @@ class WindowsServiceManager(ServiceManagerProtocol):
# Create permanent config file in a stable location # Create permanent config file in a stable location
config_dir = self.config_dir config_dir = self.config_dir
config_dir.mkdir(parents=True, exist_ok=True) config_dir.mkdir(parents=True, exist_ok=True)
config_file = config_dir / f"{config.name}_config.json" config_file = Path.home() / f"{config.name}_config.json"
with open(config_file, 'w') as f: with open(config_file, 'w') as f:
json.dump(asdict(windows_service_config), f, indent=2) json.dump(asdict(windows_service_config), f, indent=2)

View File

@ -27,27 +27,7 @@ class StorageManager:
if config_dir: if config_dir:
return Path(config_dir) return Path(config_dir)
system = platform.system().lower() return Path.home() / "basicfiles" / "cli" / "ss"
if system == "windows":
# Windows: %APPDATA%/scientific_surfing
app_data = os.environ.get("APPDATA")
if app_data:
return Path(app_data) / "scientific_surfing"
else:
return Path.home() / "AppData" / "Roaming" / "scientific_surfing"
elif system == "darwin":
# macOS: ~/Library/Application Support/scientific_surfing
return Path.home() / "Library" / "Application Support" / "scientific_surfing"
else:
# Linux and other Unix-like systems: ~/.config/scientific_surfing
xdg_config_home = os.environ.get("XDG_CONFIG_HOME")
if xdg_config_home:
return Path(xdg_config_home) / "scientific_surfing"
else:
return Path.home() / ".config" / "scientific_surfing"
def _ensure_config_dir(self) -> None: def _ensure_config_dir(self) -> None:
"""Ensure the configuration directory exists.""" """Ensure the configuration directory exists."""

View File

@ -85,7 +85,7 @@ class WindowsServiceFramework(win32serviceutil.ServiceFramework):
except Exception as e: except Exception as e:
# Fallback to servicemanager logging # Fallback to servicemanager logging
servicemanager.LogInfoMsg(f"Failed to setup file logging: {e}") servicemanager.LogInfoMsg(f"Failed to setup file logging: {e}")
self.log = servicemanager #self.log = servicemanager
@classmethod @classmethod
def load_service_config(cls): def load_service_config(cls):

View File

@ -1,10 +0,0 @@
{
"executable_path": "test.exe",
"arguments": "--test",
"working_directory": "",
"restart_on_failure": true,
"max_restarts": 5,
"restart_delay": 10,
"log_level": "INFO",
"environment_variables": {}
}

View File

@ -1,89 +0,0 @@
#!/usr/bin/env python3
"""
Test script for the upgrade method in corecfg_manager.py
"""
import sys
import os
sys.path.insert(0, os.path.dirname(__file__))
from ss.corecfg_manager import CoreConfigManager
def test_upgrade():
"""Test the upgrade method functionality."""
manager = CoreConfigManager()
print("Testing upgrade method...")
print("=" * 50)
# Test 1: Check if upgrade method exists
if hasattr(manager, 'upgrade'):
print("[OK] upgrade method exists")
else:
print("[FAIL] upgrade method not found")
return False
# Test 2: Test OS detection (without actually downloading)
import platform
system = platform.system().lower()
machine = platform.machine().lower()
print(f"Detected OS: {system}")
print(f"Detected Architecture: {machine}")
# Test 3: Test platform mapping
platform_map = {
'windows': {
'amd64': 'mihomo-windows-amd64.exe',
'386': 'mihomo-windows-386.exe',
'arm64': 'mihomo-windows-arm64.exe',
'arm': 'mihomo-windows-arm32v7.exe'
},
'linux': {
'amd64': 'mihomo-linux-amd64',
'386': 'mihomo-linux-386',
'arm64': 'mihomo-linux-arm64',
'arm': 'mihomo-linux-armv7'
},
'darwin': {
'amd64': 'mihomo-darwin-amd64',
'arm64': 'mihomo-darwin-arm64'
}
}
arch_map = {
'x86_64': 'amd64',
'amd64': 'amd64',
'i386': '386',
'i686': '386',
'arm64': 'arm64',
'aarch64': 'arm64',
'armv7l': 'arm',
'arm': 'arm'
}
normalized_arch = arch_map.get(machine, machine)
if system in platform_map and normalized_arch in platform_map[system]:
binary_name = platform_map[system][normalized_arch]
print(f"[OK] Would download: {binary_name}")
else:
print(f"[FAIL] Unsupported platform: {system}/{normalized_arch}")
return False
# Test 4: Test directory creation
from ss.storage import StorageManager
storage = StorageManager()
binary_dir = storage.config_dir / "bin"
print(f"Binary directory: {binary_dir}")
print("\n[OK] All tests passed! The upgrade method is ready to use.")
print("\nUsage examples:")
print(" manager.upgrade() # Download latest version")
print(" manager.upgrade(version='v1.18.5') # Download specific version")
print(" manager.upgrade(force=True) # Force re-download")
return True
if __name__ == "__main__":
test_upgrade()

View File

@ -1 +0,0 @@
# Test package for scientific-surfing

7
windows.md Normal file
View File

@ -0,0 +1,7 @@
管理员
```powershell
pip install -r requirements.txt -r requirements-win32.txt
python -m ss core service install
```