chore(release): v1.1.0 — 版本号 1.0.0 → 1.1.0,README 双语化,构建脚本编码自检
版本号 1.1.0(Windows 支持是新功能) - core/protocol.py APP_VERSION、installer/version_info.txt、installer/iosloc.iss MyAppVersion、Location.spec(mac BUNDLE)、tools/make_dmg.py VERSION 全部同步到 1.1.0 - 产物命名规范:Windows 用 _win、macOS 用 _mac 后缀,Release 页面一眼分清平台 · iOSLocationTrack-1.1.0_win-setup.exe · iOSLocationTrack-1.1.0_win-portable.zip · iOSLocationTrack-1.1.0_mac.dmg README 双语化(默认中文) - docs/README-WINDOWS.en.md 新增(Windows 文档全文英文版) - docs/README-WINDOWS.md 顶部加 [中文] | [English] 语言切换 - README.md / README.en.md 的下载章节改成平台表格,说明 _win / _mac 命名 构建脚本编码自检 - scripts/build.ps1 新增第 0.5 步:检查 scripts/*.ps1 是否为 UTF-8 with BOM, 缺失则自动补回。Windows PowerShell 5.1 没有 BOM 时会按 ANSI(GBK) 解析, 中文乱码且直接语法报错(改个注释就构建不了,本项目实际踩过两次) - 本次修复:build.ps1 的 BOM 在编辑后被工具静默丢弃,已补回 验收(Windows 11 x64 / iPhone 11 iOS 26.6.1) - selftest 83/83、drift_sim 40/40、offline_tiles 13/13 - 打包版 exe 清单含 requireAdministrator,FileVersion 1.1.0.0
This commit is contained in:
1 parent
4d55e2415f
commit
c60e4b5cd4
10 files changed
+380
-25
No files matched your search
+3
-3
@@ -207,12 +207,12 @@ else:
|
||||
name="虚拟定位轨迹.app",
|
||||
icon=str(ROOT / "resources" / "AppIcon.icns"),
|
||||
bundle_identifier="com.local.ios-location-track",
|
||||
version="1.0.0",
|
||||
version="1.1.0",
|
||||
info_plist={
|
||||
"CFBundleName": "虚拟定位轨迹",
|
||||
"CFBundleDisplayName": "虚拟定位轨迹",
|
||||
"CFBundleShortVersionString": "1.0.0",
|
||||
"CFBundleVersion": "1.0.0",
|
||||
"CFBundleShortVersionString": "1.1.0",
|
||||
"CFBundleVersion": "1.1.0",
|
||||
"CFBundlePackageType": "APPL",
|
||||
"CFBundleIconFile": "AppIcon",
|
||||
"CFBundleIconName": "AppIcon",
|
||||
|
||||
+13
-4
@@ -13,7 +13,7 @@ The UI is a local web app opened in a Chrome / Edge app window (no address bar
|
||||
> userspace stack — no Wintun driver needed), detects and auto-installs Apple Mobile Device
|
||||
> Support on first launch, and shows an environment self-check window.
|
||||
> Build outputs: `dist\iOSLocationTrack\iOSLocationTrack.exe` and
|
||||
> `dist\installer\iOSLocationTrack-1.0.0-setup.exe`.
|
||||
> `dist\installer\iOSLocationTrack-1.1.0_win-setup.exe`.
|
||||
|
||||
---
|
||||
|
||||
@@ -21,10 +21,19 @@ The UI is a local web app opened in a Chrome / Edge app window (no address bar
|
||||
|
||||
### Option A — Download the installer (recommended)
|
||||
|
||||
Grab `iOSLocationTrack-1.0.0.dmg` from [Releases](https://github.com/jbjf6666/ios-location-track/releases):
|
||||
Grab the build for your platform from [Releases](https://github.com/jbjf6666/ios-location-track/releases):
|
||||
|
||||
1. Open the DMG and drag `虚拟定位轨迹.app` into `Applications`
|
||||
2. If macOS says *"unidentified developer"* on first launch → **right-click → Open → Open**
|
||||
| Platform | Filename | Notes |
|
||||
| --- | --- | --- |
|
||||
| **Windows** | `iOSLocationTrack-<version>_win-setup.exe` | Installer. A portable ZIP is also provided — just unzip and run |
|
||||
| **macOS** | `iOSLocationTrack-<version>_mac.dmg` | Open the DMG and drag the app into `Applications` |
|
||||
|
||||
On Windows the first launch asks for administrator rights and shows an environment
|
||||
self-check window that installs anything missing — see
|
||||
[docs/README-WINDOWS.md](docs/README-WINDOWS.md).
|
||||
|
||||
macOS: open the DMG and drag `虚拟定位轨迹.app` into `Applications`. If macOS says
|
||||
*"unidentified developer"* on first launch → **right-click → Open → Open**.
|
||||
|
||||
**No Python, no dependencies** — the Python runtime and every dependency are bundled inside the app (~80 MB).
|
||||
Config and tile cache are written to `~/Library/Application Support/iOSLocationTrack/`.
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
> Windows 版:免管理员建立隧道(纯 Python 用户态协议栈,不需要 Wintun 驱动)、
|
||||
> 启动时自动检测并安装 Apple Mobile Device Support、带「环境准备」自检窗口。
|
||||
> 构建产物:`dist\iOSLocationTrack\iOSLocationTrack.exe` 与
|
||||
> `dist\installer\iOSLocationTrack-1.0.0-setup.exe`。
|
||||
> `dist\installer\iOSLocationTrack-1.1.0_win-setup.exe`。
|
||||
|
||||
---
|
||||
|
||||
@@ -20,10 +20,18 @@
|
||||
|
||||
### 方式一:直接下载安装包(推荐)
|
||||
|
||||
从 [Releases](https://github.com/jbjf6666/ios-location-track/releases) 下载 `iOSLocationTrack-1.0.0.dmg`:
|
||||
从 [Releases](https://github.com/jbjf6666/ios-location-track/releases) 下载对应平台的安装包:
|
||||
|
||||
1. 打开 DMG,把 `虚拟定位轨迹.app` 拖进 `Applications`
|
||||
2. 首次打开若提示「来自身份不明的开发者」→ 右键 → 打开 → 再点「打开」
|
||||
| 平台 | 文件名 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| **Windows** | `iOSLocationTrack-<版本>_win-setup.exe` | 安装包。也可用绿色版压缩包,解压即用 |
|
||||
| **macOS** | `iOSLocationTrack-<版本>_mac.dmg` | 打开 DMG,把 App 拖进 `Applications` |
|
||||
|
||||
Windows 版首次启动会请求管理员权限并弹出「环境准备」窗口自动补齐依赖,
|
||||
详见 [docs/README-WINDOWS.md](docs/README-WINDOWS.md)。
|
||||
|
||||
macOS 版:打开 DMG,把 `虚拟定位轨迹.app` 拖进 `Applications`;首次打开若提示
|
||||
「来自身份不明的开发者」→ 右键 → 打开 → 再点「打开」。
|
||||
|
||||
**不需要安装 Python、不需要任何依赖**,Python 运行时与全部依赖都已打包在应用内(约 80 MB)。
|
||||
数据(配置、瓦片缓存)写到 `~/Library/Application Support/iOSLocationTrack/`。
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ import uuid
|
||||
from typing import Any
|
||||
|
||||
APP_NAME = "iOS 虚拟定位轨迹工具"
|
||||
APP_VERSION = "1.0.0"
|
||||
APP_VERSION = "1.1.0"
|
||||
PROTOCOL_VERSION = "v1"
|
||||
|
||||
DEFAULT_HOST = "127.0.0.1"
|
||||
|
||||
@@ -0,0 +1,313 @@
|
||||
# Windows Guide — iOS Virtual Location & Route Simulator
|
||||
|
||||
[**中文**](README-WINDOWS.md) | [English](README-WINDOWS.en.md)
|
||||
|
||||
> This document is for Windows users and maintainers.
|
||||
> macOS instructions live in [README.md](../README.md); the porting rationale and
|
||||
> lessons learned are in [WINDOWS_PORT.md](WINDOWS_PORT.md).
|
||||
|
||||
---
|
||||
|
||||
## 1. Quick start (3 minutes)
|
||||
|
||||
1. Run `iOSLocationTrack-1.1.0_win-setup.exe`, or unzip the portable build and
|
||||
double-click `iOSLocationTrack.exe`.
|
||||
2. **The app requests administrator rights** — click *Yes* on the UAC prompt.
|
||||
This is only needed so it can auto-install the Apple driver on first run.
|
||||
3. An **Environment Check** window appears, listing every required component:
|
||||
- Ready items show a green ✓ and their button reads *已就绪* (disabled)
|
||||
- Missing items show a red ✗ with a clickable **Install / Download** button
|
||||
- **The "进入程序" (Enter) button only becomes clickable once every required item is ready**
|
||||
4. Click **进入程序** — the UI opens in a Chrome/Edge app window (no address bar).
|
||||
5. Connect your iPhone by cable → unlock it → tap *Trust* → click **连接设备** in the UI.
|
||||
|
||||
> Running from source: `.\scripts\run.ps1` (creates the venv, installs dependencies
|
||||
> and fetches the disk-image assets automatically).
|
||||
|
||||
---
|
||||
|
||||
## 2. What the Environment Check verifies
|
||||
|
||||
| Item | Required | How it is checked | What "Install" does |
|
||||
| --- | --- | --- | --- |
|
||||
| Python runtime | ✅ | version string | — (bundled in the exe) |
|
||||
| pymobiledevice3 | ✅ | import + version | — (bundled) |
|
||||
| **Apple Mobile Device Support** | ✅ | service state + a protocol round-trip on port 27015 | downloads and installs it (~40–200 MB) |
|
||||
| RSD tunnel deps | ✅ | imports `pytun_pmd3` / `pmd_pytcp` etc. | — (bundled) |
|
||||
| Developer disk image | ✅ | three files under `resources/ddi/personalized/` | downloads the personalized image (~15 MB) |
|
||||
| Administrator rights | ✅ | `IsUserAnAdmin` | right-click → *Run as administrator* |
|
||||
| iPhone connection | ➖ optional | usbmuxd `ListDevices` | — (just plug the phone in) |
|
||||
| Network reachability | ➖ optional | TCP to `gs.apple.com:443` | — (Apple signs the image online) |
|
||||
|
||||
**The only authoritative signal that usbmuxd actually works is a protocol round-trip
|
||||
on `127.0.0.1:27015`** — not merely that the port accepts a connection.
|
||||
`ReadBUID` needs no device attached, so the service can be validated with no phone present.
|
||||
|
||||
### Text-mode self check
|
||||
|
||||
```powershell
|
||||
# portable build
|
||||
.\dist\iOSLocationTrack\iOSLocationTrack.exe --check-driver
|
||||
# from source
|
||||
.venv\Scripts\python.exe main.py --check-driver
|
||||
```
|
||||
|
||||
Sample output:
|
||||
|
||||
```
|
||||
平台:Windows(管理员:是)
|
||||
服务:RUNNING(Apple Mobile Device Service)
|
||||
版本:Apple Mobile Device Support 20.0.0.35
|
||||
usbmuxd(127.0.0.1:27015):可通信
|
||||
设备:1 台
|
||||
· 00008030-001551840A02402E(USB)
|
||||
结论:Apple Mobile Device Service 正在运行,usbmuxd 可通信
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Automatic Apple Mobile Device Support installation
|
||||
|
||||
Click **Install** on the Apple row in the Environment Check window, or run:
|
||||
|
||||
```powershell
|
||||
main.py --install-driver # from source
|
||||
iOSLocationTrack.exe --install-driver # portable build
|
||||
```
|
||||
|
||||
Strategies are tried in order and fall through automatically (`core/apple_driver.py`):
|
||||
|
||||
| # | Strategy | Notes |
|
||||
| --- | --- | --- |
|
||||
| 0 | Start the existing service | If it is installed but stopped, `sc start` is all that is needed (cheapest, most common fix) |
|
||||
| 1 | Standalone AMDS MSI | `AppleMobileDeviceSupport64.msi` from Apple's CDN (~38 MB) |
|
||||
| 2 | Full iTunes bundle | `https://www.apple.com/itunes/download/win64` (~193 MB) |
|
||||
| 3 | winget | `Apple.AppleMobileDeviceSupport` / `Apple.iTunes` |
|
||||
|
||||
Success exit codes: `0`, `3010`, `1641`, `1638` (MSI semantics; 3010/1641 mean a reboot is needed).
|
||||
|
||||
### Traps you must know about (all verified on real hardware)
|
||||
|
||||
1. **The service name contains spaces: `Apple Mobile Device Service`.**
|
||||
`AppleMobileDeviceService` is only the exe basename — `sc query AppleMobileDeviceService`
|
||||
fails with error 1060.
|
||||
2. **There is no `\\.\pipe\usbmuxd` on Windows.** usbmuxd is exposed purely as TCP
|
||||
`127.0.0.1:27015`.
|
||||
3. **Do not detect the driver by looking for `usbaapl64`.** The AMDS MSI contains
|
||||
**zero `.inf`/`.sys`/`.cat` files** — it does **not** ship the USB driver. On a modern
|
||||
machine the iPhone actually binds to `appleusb.inf` (service `WINUSB` / `usbccgp`).
|
||||
A `usbaapl64` check produces false "missing driver" reports on perfectly healthy systems.
|
||||
4. **The AMDS ProductCode changes with every version.** The stable identifier is the
|
||||
UpgradeCode `{5CF0656E-F3B8-11DB-BA81-804E56D89593}` (shared by x86 and x64).
|
||||
5. **Apple publishes no stable "latest" direct link** — the `iTunes64Setup.exe` URL embeds
|
||||
a build number. This project therefore pins a SHA256 where one is available and fails
|
||||
loudly rather than installing something unverifiable.
|
||||
6. **Microsoft Store iTunes and the classic installer are mutually exclusive**: the classic
|
||||
installer's `LaunchCondition` hard-codes `NOT ITUNES_STORE_APP_INSTALLED`. Separately,
|
||||
the Store daemon **cannot discover devices over Wi-Fi**. pymobiledevice3's own docs
|
||||
recommend the classic installer for exactly this reason.
|
||||
|
||||
---
|
||||
|
||||
## 4. How Windows differs from macOS (**important**)
|
||||
|
||||
The single biggest porting trap: **the two platforms build the RSD tunnel in fundamentally
|
||||
different ways**, so `core/tunnel.py` has two entirely separate code paths.
|
||||
|
||||
| | macOS | Windows |
|
||||
| --- | --- | --- |
|
||||
| Tunnel | `remote start-tunnel --native` (piggybacks Apple's `remoted`) | `UserspaceRsdTunnel` (pure-Python PyTCP userspace stack) |
|
||||
| Needs root/admin | No | **No** |
|
||||
| Needs a third-party driver | No | **No** (Wintun not required) |
|
||||
| RSD address reachable from | any process (kernel-routable) | **this process only** (userspace stack) |
|
||||
| Implementation | subprocess + parse `HOST PORT` from stdout | build and hold the RSD object on the app's event loop |
|
||||
| Measured time | — | **~0.3 s** |
|
||||
|
||||
### Why Windows cannot use the "tunnel helper subprocess" design
|
||||
|
||||
On macOS the tunnel runs in a child process that prints `HOST PORT`, and the main process
|
||||
connects over ordinary TCP. That does not work on Windows:
|
||||
|
||||
- The userspace tunnel's device address **only exists inside the protocol stack of the
|
||||
process that created it**;
|
||||
- pymobiledevice3 injects a relay dialer into the `RemoteServiceDiscoveryService` object it
|
||||
returns (`open_connection=dial_plane.dial`);
|
||||
- Building a *new* RSD from `(host, port)` falls back to the stdlib dialer, which goes to the
|
||||
OS network stack and fails with `OSError [WinError 1231] The network location cannot be
|
||||
reached` (reproduced during this port).
|
||||
|
||||
**The correct approach**: inject the **rsd object itself** into the DVT layer.
|
||||
`RealLocationProvider` already had an `rsd=` injection seam (`core/location_provider.py`),
|
||||
and `core/server.py:provider_for()` now uses it on Windows.
|
||||
|
||||
### About Wintun
|
||||
|
||||
`docs/WINDOWS_PORT.md` originally said to install Wintun first. **Measurement says it is not
|
||||
needed:**
|
||||
|
||||
- The userspace tunnel runs a pure-Python PyTCP stack and creates no kernel adapter;
|
||||
- Moreover the `pytun_pmd3` dependency **already bundles** `wintun.dll` for every
|
||||
architecture (`pytun_pmd3/wintun/bin/amd64/wintun.dll`), so there was never anything to
|
||||
download.
|
||||
|
||||
### Verified environment
|
||||
|
||||
| Item | Value |
|
||||
| --- | --- |
|
||||
| OS | Windows 11 Home (Chinese), 10.0.26200, x64 |
|
||||
| Python | 3.12.14 |
|
||||
| pymobiledevice3 | 11.31.0 |
|
||||
| Device | iPhone 11 (`iPhone12,1`), **iOS 26.6.1** |
|
||||
| Apple Mobile Device Support | 20.0.0.35 |
|
||||
| iTunes | 12.13.11.1 (classic) |
|
||||
|
||||
Measured connect time: **0.8 s** (0.3 s tunnel + image/DVT session).
|
||||
|
||||
---
|
||||
|
||||
## 5. Where data and logs live
|
||||
|
||||
| Content | Path |
|
||||
| --- | --- |
|
||||
| Config / tile cache / logs | `%LOCALAPPDATA%\iOSLocationTrack\` |
|
||||
| Application log | `%LOCALAPPDATA%\iOSLocationTrack\logs\app.log` |
|
||||
| MSI install logs | `%LOCALAPPDATA%\iOSLocationTrack\logs\msi-*.log` |
|
||||
| Downloaded installers | `%LOCALAPPDATA%\iOSLocationTrack\installers\` |
|
||||
| Developer image cache | `%USERPROFILE%\.pymobiledevice3\Xcode_iOS_DDI_Personalized\` |
|
||||
|
||||
`app.log` is UTF-8, tab-separated: `timestamp \t level \t message`.
|
||||
Open it in Notepad or use `Get-Content -Encoding UTF8` (Windows PowerShell 5.1 defaults to
|
||||
ANSI and will show mojibake).
|
||||
|
||||
---
|
||||
|
||||
## 6. Building
|
||||
|
||||
```powershell
|
||||
# One shot: icon → image assets → tests → PyInstaller → Inno Setup
|
||||
.\scripts\build.ps1
|
||||
|
||||
# exe only
|
||||
.\scripts\build.ps1 -NoInstaller
|
||||
|
||||
# Fast rebuild, skip tests
|
||||
.\scripts\build.ps1 -SkipTests -SkipIcon -SkipDdi
|
||||
```
|
||||
|
||||
Outputs:
|
||||
|
||||
| File | Notes |
|
||||
| --- | --- |
|
||||
| `dist\iOSLocationTrack\iOSLocationTrack.exe` | Portable onedir build — copy the whole folder |
|
||||
| `dist\installer\iOSLocationTrack-1.1.0_win-setup.exe` | Installer (Inno Setup 6) |
|
||||
|
||||
**Prerequisites:**
|
||||
|
||||
```powershell
|
||||
python -m venv .venv
|
||||
.venv\Scripts\python.exe -m pip install -i https://mirrors.aliyun.com/pypi/simple/ pymobiledevice3 pillow pyinstaller
|
||||
winget install -e --id JRSoftware.InnoSetup # optional, installer only
|
||||
```
|
||||
|
||||
### Packaging traps (all fixed — do not reintroduce them)
|
||||
|
||||
1. **Do not exclude `distutils` / `setuptools` / `wheel` / `pip`.** PyInstaller and
|
||||
setuptools hooks force-import or alias them, and the build dies immediately:
|
||||
```
|
||||
ValueError: Target module "distutils" already imported as ExcludedModule('distutils',)
|
||||
ValueError: Target module "wheel" already imported as ExcludedModule('wheel',)
|
||||
```
|
||||
2. **Do not exclude `tkinter`** — the Environment Check window is built with it.
|
||||
3. **`copy_metadata` must include** `apple_compress` and friends, otherwise mounting fails
|
||||
with `No package metadata was found for apple_compress`.
|
||||
4. **Do not exclude `questionary` / `prompt_toolkit` / `pygments`** — pymobiledevice3 imports
|
||||
them at runtime; excluding them silently breaks real-device support (device discovery
|
||||
degrades to the libimobiledevice fallback).
|
||||
5. **With `--windowed`, `sys.stdout` is `None`** — check before printing.
|
||||
6. **`.ps1` files must be UTF-8 *with BOM*.** Windows PowerShell 5.1 only parses a script as
|
||||
UTF-8 when it sees a BOM; otherwise it uses the system ANSI code page (GBK on Chinese
|
||||
Windows), which turns every Chinese character into mojibake and **breaks the script with a
|
||||
syntax error** (`The string is missing the terminator`).
|
||||
Both `scripts\run.ps1` and `scripts\build.ps1` are stored as UTF-8 with BOM, and
|
||||
`build.ps1` re-adds a missing BOM automatically as step 0.5.
|
||||
|
||||
### Requesting administrator rights at launch
|
||||
|
||||
The Windows branch of `Location.spec` sets `uac_admin=True`, which makes PyInstaller write
|
||||
`requestedExecutionLevel level="requireAdministrator"` into the exe manifest.
|
||||
You can verify it by searching the exe for `requireAdministrator`.
|
||||
|
||||
> Note: the userspace tunnel itself does **not** need administrator rights. Elevation exists
|
||||
> purely so the first run can auto-install Apple Mobile Device Support without asking the user
|
||||
> to right-click and elevate manually.
|
||||
|
||||
---
|
||||
|
||||
## 7. Acceptance tests
|
||||
|
||||
```powershell
|
||||
# No device needed (136 checks)
|
||||
.venv\Scripts\python.exe tests\selftest.py # 83: protocol/geometry/playback/config/tiles/e2e
|
||||
.venv\Scripts\python.exe tests\drift_sim.py # 40: realism model
|
||||
.venv\Scripts\python.exe tests\offline_tiles.py # 13: offline tile cache
|
||||
|
||||
# Platform feasibility (real device, 7 checks)
|
||||
.venv\Scripts\python.exe tests\win_e2e.py --confirm
|
||||
|
||||
# Application layer (real device, 9 checks; uses App's real wiring)
|
||||
.venv\Scripts\python.exe tests\win_app_e2e.py --confirm
|
||||
|
||||
# UI without a device
|
||||
.venv\Scripts\python.exe main.py --mock
|
||||
```
|
||||
|
||||
Real-device acceptance, the 6 steps from §7 of `WINDOWS_PORT.md`:
|
||||
|
||||
1. `pymobiledevice3 usbmux list` sees the device ✅
|
||||
2. Developer disk image mounts ✅
|
||||
3. "Connect device" → tunnel up → DVT session ready ✅
|
||||
4. Play a route → the phone's location actually moves ✅
|
||||
5. "Stop" → the phone returns to its real location ✅
|
||||
6. App layer 9/9 and platform layer 7/7 ✅
|
||||
|
||||
---
|
||||
|
||||
## 8. Known limitations
|
||||
|
||||
| Limitation | Detail |
|
||||
| --- | --- |
|
||||
| **One userspace tunnel per process** | PyTCP's stack is a process-global singleton. Do not run two instances. |
|
||||
| **Only one tool may hold the RSD connection** | 爱思助手 / i4Tools / Xcode will evict each other. Close them first. |
|
||||
| **iOS 16 and earlier unsupported** | Classic images must be signed by Apple per build; third-party images are rejected by the device. This project targets iOS 17+. |
|
||||
| **DVT can only change latitude/longitude** | `simulateLocationWithLatitude:longitude:` takes only two arguments; altitude, accuracy and sensor data are synthesized by iOS and cannot be injected. |
|
||||
| **Mounting the image needs network access** | The personalized image is signed online by Apple TSS per device. |
|
||||
| **The tunnel can drop silently** | The Windows userspace stack occasionally disconnects, after which the device quietly reverts to its real location while the UI still looks fine. A **keepalive** re-sends the last point every 15 s when a location is set but playback is stopped (`core/location_provider.py:KEEPALIVE_INTERVAL`). |
|
||||
| **DDI mounting may disturb DVT on iOS 26.4.x** | One peer project reports that uploading the image on 26.4.1 kills the tunnel, poisoning later DVT calls with `InvalidService`. Verified fine on 26.6.1 here. If you hit it, mount the image in another tool first. |
|
||||
| **Unsigned exe triggers SmartScreen** | There is no code-signing certificate. Click *More info → Run anyway*. |
|
||||
| **Windows 10 1809 or later** | The installer sets `MinVersion=10.0`. |
|
||||
|
||||
---
|
||||
|
||||
## 9. File map (Windows-related changes)
|
||||
|
||||
| File | Notes |
|
||||
| --- | --- |
|
||||
| `core/platform.py` | **New.** Platform abstraction: data dir, browser probing, process management, elevation, signals |
|
||||
| `core/apple_driver.py` | **New.** Apple Mobile Device Support detection/install + developer image download |
|
||||
| `core/setup_window.py` | **New.** The Environment Check window (tkinter) |
|
||||
| `core/tunnel.py` | **Rewritten.** Windows uses an in-process userspace tunnel; macOS keeps the native subprocess tunnel |
|
||||
| `core/server.py` | Injects the runner into TunnelManager; `provider_for()` injects the rsd object; file logging; resources dir split from data dir |
|
||||
| `core/location_provider.py` | Platform-aware error messages; **keepalive added** (`_keepalive_loop`) |
|
||||
| `main.py` | Environment Check window, background Apple driver check, `--check-driver` / `--install-driver`, cross-platform browser and signals |
|
||||
| `Location.spec` | Platform branches; Windows uses `.ico` + `uac_admin=True` + `version_info.txt`; **one spec, no fork** |
|
||||
| `tools/make_ico.py` | **New.** Builds a multi-size `.ico` from the existing PNG iconset |
|
||||
| `tools/probe_tunnel_win.py` | **New.** Tunnel feasibility diagnostic |
|
||||
| `scripts/run.ps1` / `build.ps1` | **New.** Windows run/build scripts |
|
||||
| `installer/iosloc.iss` | **New.** Inno Setup installer script |
|
||||
| `installer/version_info.txt` | **New.** exe version resource |
|
||||
| `installer/languages/ChineseSimplified.isl` | **New.** Inno Setup 6.7 no longer bundles Chinese, so it ships with the repo |
|
||||
| `tests/win_e2e.py` / `win_app_e2e.py` | **New.** Real-device acceptance (platform layer / application layer) |
|
||||
|
||||
The macOS build chain (`tools/make_dmg.py`, `scripts/run.sh`, `build_app.sh`, and the
|
||||
`BUNDLE` branch of `Location.spec`) is **fully retained** — a single codebase builds on both
|
||||
platforms.
|
||||
@@ -1,5 +1,7 @@
|
||||
# Windows 版说明(iOS 虚拟定位轨迹工具)
|
||||
|
||||
[**中文**](README-WINDOWS.md) | [English](README-WINDOWS.en.md)
|
||||
|
||||
> 本文档面向 Windows 用户与维护者。
|
||||
> macOS 侧说明见 [README.md](../README.md);移植决策与背景见 [WINDOWS_PORT.md](WINDOWS_PORT.md)。
|
||||
|
||||
@@ -7,7 +9,7 @@
|
||||
|
||||
## 1. 三分钟上手
|
||||
|
||||
1. 运行 `iOSLocationTrack-1.0.0-setup.exe` 安装,或直接双击绿色版
|
||||
1. 运行 `iOSLocationTrack-1.1.0_win-setup.exe` 安装,或直接双击绿色版
|
||||
`dist\iOSLocationTrack\iOSLocationTrack.exe`。
|
||||
2. **程序会请求管理员权限**(UAC 弹窗点「是」)—— 用于首次自动安装 Apple 驱动。
|
||||
3. 弹出**「环境准备」**窗口,逐项列出所需组件:
|
||||
@@ -183,7 +185,7 @@ Windows 上这样行不通:
|
||||
| 文件 | 说明 |
|
||||
| --- | --- |
|
||||
| `dist\iOSLocationTrack\iOSLocationTrack.exe` | 绿色版 onedir,整个目录一起拷走 |
|
||||
| `dist\installer\iOSLocationTrack-1.0.0-setup.exe` | 安装包(Inno Setup 6) |
|
||||
| `dist\installer\iOSLocationTrack-1.1.0_win-setup.exe` | 安装包(Inno Setup 6) |
|
||||
|
||||
**前置条件:**
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
; 1) .venv\Scripts\python.exe -m PyInstaller --clean --noconfirm Location.spec
|
||||
; 2) "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" installer\iosloc.iss
|
||||
;
|
||||
; 产物:dist\installer\iOSLocationTrack-1.0.0-setup.exe
|
||||
; 产物:dist\installer\iOSLocationTrack-1.1.0_win-setup.exe
|
||||
;
|
||||
; 说明:
|
||||
; - 安装包**不包含** Apple 的驱动。程序首次启动时会自动检测 Apple Mobile Device
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
#define MyAppName "iOS 虚拟定位轨迹工具"
|
||||
#define MyAppNameEn "iOSLocationTrack"
|
||||
#define MyAppVersion "1.0.0"
|
||||
#define MyAppVersion "1.1.0"
|
||||
#define MyAppPublisher "本地工具"
|
||||
#define MyAppExeName "iOSLocationTrack.exe"
|
||||
#define DistDir "..\dist\iOSLocationTrack"
|
||||
@@ -32,7 +32,8 @@ DisableProgramGroupPage=yes
|
||||
PrivilegesRequired=lowest
|
||||
PrivilegesRequiredOverridesAllowed=dialog
|
||||
OutputDir=..\dist\installer
|
||||
OutputBaseFilename={#MyAppNameEn}-{#MyAppVersion}-setup
|
||||
; 产物名带 _win 后缀,与 macOS 的 _mac 对应,Release 页面上一眼能分清平台。
|
||||
OutputBaseFilename={#MyAppNameEn}-{#MyAppVersion}_win-setup
|
||||
SetupIconFile=..\resources\AppIcon.ico
|
||||
UninstallDisplayIcon={app}\{#MyAppExeName}
|
||||
Compression=lzma2/max
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
# 语法见 https://learn.microsoft.com/windows/win32/menurc/versioninfo-resource
|
||||
VSVersionInfo(
|
||||
ffi=FixedFileInfo(
|
||||
filevers=(1, 0, 0, 0),
|
||||
prodvers=(1, 0, 0, 0),
|
||||
filevers=(1, 1, 0, 0),
|
||||
prodvers=(1, 1, 0, 0),
|
||||
mask=0x3f,
|
||||
flags=0x0,
|
||||
OS=0x40004,
|
||||
@@ -18,12 +18,12 @@ VSVersionInfo(
|
||||
[
|
||||
StringStruct('CompanyName', '本地工具'),
|
||||
StringStruct('FileDescription', 'iOS 虚拟定位轨迹工具'),
|
||||
StringStruct('FileVersion', '1.0.0.0'),
|
||||
StringStruct('FileVersion', '1.1.0.0'),
|
||||
StringStruct('InternalName', 'iOSLocationTrack'),
|
||||
StringStruct('LegalCopyright', '本地工具,用于自有 App 的定位功能测试'),
|
||||
StringStruct('OriginalFilename', 'iOSLocationTrack.exe'),
|
||||
StringStruct('ProductName', 'iOS 虚拟定位轨迹工具'),
|
||||
StringStruct('ProductVersion', '1.0.0.0'),
|
||||
StringStruct('ProductVersion', '1.1.0.0'),
|
||||
],
|
||||
)
|
||||
]),
|
||||
|
||||
+21
-1
@@ -2,7 +2,7 @@
|
||||
#
|
||||
# 产出:
|
||||
# dist\iOSLocationTrack\iOSLocationTrack.exe 绿色版(直接双击运行)
|
||||
# dist\installer\iOSLocationTrack-1.0.0-setup.exe 安装包(需要 Inno Setup 6)
|
||||
# dist\installer\iOSLocationTrack-1.1.0_win-setup.exe 安装包(需要 Inno Setup 6)
|
||||
#
|
||||
# 用法(在项目根目录):
|
||||
# .\scripts\build.ps1 # 打包 exe + 安装包(若装了 Inno Setup)
|
||||
@@ -49,6 +49,26 @@ if ($LASTEXITCODE -ne 0) {
|
||||
}
|
||||
Write-Ok "PyInstaller / Pillow 就绪"
|
||||
|
||||
# ---------- 0.5 脚本编码自检(.ps1 必须 UTF-8 with BOM)----------
|
||||
# Windows PowerShell 5.1 只有看到 BOM 才按 UTF-8 解析 .ps1;否则按系统 ANSI 代码页读,
|
||||
# 结果是中文全部乱码并**直接语法报错**(The string is missing the terminator),脚本根本跑不起来。
|
||||
# 不少编辑器/工具保存时会静默丢掉 BOM,所以这里自动补回,避免"改个注释就构建不了"。
|
||||
$bomFixed = @()
|
||||
foreach ($script in Get-ChildItem (Join-Path $PSScriptRoot '*.ps1')) {
|
||||
$bytes = [System.IO.File]::ReadAllBytes($script.FullName)
|
||||
$hasBom = $bytes.Length -ge 3 -and $bytes[0] -eq 0xEF -and $bytes[1] -eq 0xBB -and $bytes[2] -eq 0xBF
|
||||
if (-not $hasBom) {
|
||||
$text = [System.IO.File]::ReadAllText($script.FullName, [System.Text.UTF8Encoding]::new($false))
|
||||
[System.IO.File]::WriteAllText($script.FullName, $text, [System.Text.UTF8Encoding]::new($true))
|
||||
$bomFixed += $script.Name
|
||||
}
|
||||
}
|
||||
if ($bomFixed.Count -gt 0) {
|
||||
Write-Warn "已为下列脚本补回 UTF-8 BOM:$($bomFixed -join '、')(下次编辑请保留 BOM)"
|
||||
} else {
|
||||
Write-Ok ".ps1 编码正常(UTF-8 with BOM)"
|
||||
}
|
||||
|
||||
# ---------- 1. 图标 ----------
|
||||
if (-not $SkipIcon) {
|
||||
Write-Bold "1. Windows 图标(.ico)"
|
||||
|
||||
+5
-3
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
"""把打包好的 .app 制作成可分发的 DMG 安装包。
|
||||
|
||||
产物:dist/虚拟定位轨迹-1.0.0.dmg
|
||||
产物:dist/iOSLocationTrack-1.1.0_mac.dmg
|
||||
内容:应用本身 + Applications 快捷方式(拖进去即安装)+ 中文安装说明
|
||||
|
||||
特点:
|
||||
@@ -25,9 +25,11 @@ from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
APP_NAME = "虚拟定位轨迹"
|
||||
VERSION = "1.0.0"
|
||||
VERSION = "1.1.0"
|
||||
APP = ROOT / "dist" / f"{APP_NAME}.app"
|
||||
DMG = ROOT / "dist" / f"{APP_NAME}-{VERSION}.dmg"
|
||||
# 产物名带 _mac 后缀,与 Windows 的 _win 对应,Release 页面上一眼能分清平台。
|
||||
# 用 ASCII 文件名:GitHub Release 会把非 ASCII 字符剥掉(v1.0.0 首次上传时踩过)。
|
||||
DMG = ROOT / "dist" / f"iOSLocationTrack-{VERSION}_mac.dmg"
|
||||
VOLUME = APP_NAME
|
||||
BG_WIDTH, BG_HEIGHT = 600, 400
|
||||
|
||||
|
||||
Reference in new issue
Block a user