$ErrorActionPreference = "Stop" $Root = "C:\UniDesk\personal-wechat" $WechatRoot = Join-Path $Root "wechat-3.9.12.51" $WcfRoot = Join-Path $Root "wcf\v39.5.2" $StateRoot = Join-Path $Root "wcf-state" $DownloadRoot = Join-Path $Root "downloads" $PrepareResult = Join-Path $StateRoot "prepare-result.json" $ProgressLog = Join-Path $StateRoot "prepare-progress.log" $Python = "C:\ProgramData\miniconda3\python.exe" $PipIndex = "http://mirrors.aliyun.com/pypi/simple/" $ReleaseBase = "https://github.com/lich0821/WeChatFerry/releases/download/v39.5.2" New-Item -ItemType Directory -Force $WechatRoot,$WcfRoot,$StateRoot,$DownloadRoot | Out-Null $StartedAt = (Get-Date).ToUniversalTime().ToString("o") function Write-PrepareProgress { param([string]$Message) Add-Content -Encoding utf8 -Path $ProgressLog -Value "$((Get-Date).ToUniversalTime().ToString("o")) $Message" } trap { $message = $_.Exception.Message Write-PrepareProgress "error $message" $failed = [ordered]@{ ok = $false startedAt = $StartedAt finishedAt = (Get-Date).ToUniversalTime().ToString("o") root = $Root stateRoot = $StateRoot python = $Python error = $message valuesPrinted = $false } $failed | ConvertTo-Json -Depth 6 | Set-Content -Encoding utf8 $PrepareResult exit 1 } function Download-IfMissing { param([string]$Url, [string]$Path) if (Test-Path $Path) { return } Write-PrepareProgress "download-start $Url" $tmp = "$Path.part" Invoke-WebRequest -Uri $Url -OutFile $tmp -UseBasicParsing Move-Item -Force $tmp $Path Write-PrepareProgress "download-done $Path" } function Find-WeChatExe { $candidates = @( (Join-Path $WechatRoot "WeChat.exe"), "C:\Program Files (x86)\Tencent\WeChat\WeChat.exe", "C:\Program Files\Tencent\WeChat\WeChat.exe" ) foreach ($candidate in $candidates) { if (Test-Path $candidate) { return $candidate } } return $null } Write-PrepareProgress "prepare-start" $installer = Join-Path $DownloadRoot "WeChatSetup-3.9.12.51.exe" Download-IfMissing "$ReleaseBase/WeChatSetup-3.9.12.51.exe" $installer Download-IfMissing "$ReleaseBase/sdk.dll" (Join-Path $WcfRoot "sdk.dll") Download-IfMissing "$ReleaseBase/spy.dll" (Join-Path $WcfRoot "spy.dll") Download-IfMissing "$ReleaseBase/spy_debug.dll" (Join-Path $WcfRoot "spy_debug.dll") if (!(Test-Path $Python)) { throw "Expected Python not found: $Python" } $pipOut = Join-Path $StateRoot "prepare-pip.stdout.log" $pipErr = Join-Path $StateRoot "prepare-pip.stderr.log" Write-PrepareProgress "pip-install-start" & $Python -m pip install --trusted-host mirrors.aliyun.com --index-url $PipIndex "wcferry==39.5.2.0" > $pipOut 2> $pipErr if ($LASTEXITCODE -ne 0) { throw "pip install wcferry failed" } Write-PrepareProgress "pip-install-done" Copy-Item -Force "$PSScriptRoot\wcf_host.py" (Join-Path $WcfRoot "wcf_host.py") if (-not (Get-NetFirewallRule -DisplayName "UniDesk Personal WeChat WCF 10086" -ErrorAction SilentlyContinue)) { New-NetFirewallRule ` -DisplayName "UniDesk Personal WeChat WCF 10086" ` -Direction Inbound ` -Action Allow ` -Protocol TCP ` -LocalPort 10086,10087 ` -RemoteAddress 172.26.0.0/16,10.42.0.0/16,127.0.0.1 ` -Profile Any ` -ErrorAction SilentlyContinue | Out-Null } $wechatExe = Find-WeChatExe $installAttempted = $false $installExitCode = $null $installStdout = Join-Path $StateRoot "prepare-wechat-installer.stdout.log" $installStderr = Join-Path $StateRoot "prepare-wechat-installer.stderr.log" if (-not $wechatExe) { $installAttempted = $true $args = @("/S", "/D=$WechatRoot") Write-PrepareProgress "wechat-install-start $installer" $proc = Start-Process -FilePath $installer -ArgumentList $args -Wait -PassThru -RedirectStandardOutput $installStdout -RedirectStandardError $installStderr -WindowStyle Hidden $installExitCode = $proc.ExitCode Write-PrepareProgress "wechat-install-exit $installExitCode" Start-Sleep -Seconds 5 $wechatExe = Find-WeChatExe } $probePy = Join-Path $StateRoot "prepare-probe.py" @' import importlib.metadata import json payload = {"ok": True} try: payload["wcferryVersion"] = importlib.metadata.version("wcferry") except Exception as exc: payload = {"ok": False, "error": f"{type(exc).__name__}: {exc}"} print(json.dumps(payload, ensure_ascii=False)) '@ | Set-Content -Encoding utf8 $probePy $pyProbeJson = & $Python $probePy $pyProbe = $pyProbeJson | ConvertFrom-Json $summary = [ordered]@{ ok = [bool]($pyProbe.ok -and $wechatExe) startedAt = $StartedAt finishedAt = (Get-Date).ToUniversalTime().ToString("o") root = $Root wechatInstaller = $installer wechatRoot = $WechatRoot wechatExe = $wechatExe installAttempted = $installAttempted installExitCode = $installExitCode installLogs = [ordered]@{ stdout = $installStdout stderr = $installStderr } wcfRoot = $WcfRoot stateRoot = $StateRoot python = $Python wcferryVersion = $pyProbe.wcferryVersion next = if ($wechatExe) { "Run start.ps1 and scan the WeChat login QR." } else { "WeChat silent install did not produce WeChat.exe; run the installer UI from the interactive Windows session, then re-run prepare.ps1." } } Write-PrepareProgress "prepare-done ok=$($summary.ok)" $summary | ConvertTo-Json -Depth 6 | Set-Content -Encoding utf8 $PrepareResult $summary | ConvertTo-Json -Depth 6