55)
66$ErrorActionPreference = " Stop"
77
8- # 自动提权 & 切回脚本目录
8+ # -------------------------------------------------
9+ # 1. 自动提权 & 回到脚本目录
10+ # -------------------------------------------------
911if (-not ([Security.Principal.WindowsPrincipal ][Security.Principal.WindowsIdentity ]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole ]::Administrator)) {
10- Write-Host " 当前非管理员权限,正在尝试以管理员身份重新启动..." - ForegroundColor Yellow
12+ Write-Host " 当前非管理员权限,正在尝试以管理员身份重新启动,如果闪退请走代理 ..." - ForegroundColor Yellow
1113 $arguments = " -NoProfile -ExecutionPolicy Bypass -File `" $ ( $MyInvocation.MyCommand.Path ) `" "
1214 if ($UseProxy ) { $arguments += " -UseProxy -ProxyHost `" $ProxyHost `" " }
1315 if ($SkipConfirm ) { $arguments += " -SkipConfirm" }
@@ -16,7 +18,9 @@ if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdenti
1618}
1719Set-Location - LiteralPath $PSScriptRoot
1820
19- # ---------- 代理 ----------
21+ # -------------------------------------------------
22+ # 2. 通用函数
23+ # -------------------------------------------------
2024function Use-ProxyIfNeeded {
2125 param ([scriptblock ]$Script )
2226 if ($UseProxy ) {
@@ -36,111 +40,168 @@ function Invoke-WebRequestWithProxy([string]$Url, [string]$OutFile) {
3640 else { Invoke-WebRequest $Url - OutFile $OutFile }
3741}
3842
39- # ---------- 用户确认 ----------
43+ # -------------------------------------------------
44+ # 3. 按需安装 winget
45+ # -------------------------------------------------
46+ function Install-Winget {
47+ if (Test-Cmd winget) { return }
48+ Write-Host " 未检测到 winget,正在安装 App Installer..." - ForegroundColor Yellow
49+ $url = " https://aka.ms/getwinget"
50+ $out = " $env: TEMP \Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle"
51+ Invoke-WebRequestWithProxy $url $out
52+ Add-AppxPackage - Path $out - ErrorAction SilentlyContinue
53+ Remove-Item $out
54+ # 刷新 PATH
55+ $env: Path = [System.Environment ]::GetEnvironmentVariable(" Path" , " Machine" ) + " ;" + [System.Environment ]::GetEnvironmentVariable(" Path" , " User" )
56+ }
57+
58+ # -------------------------------------------------
59+ # 4. 用户确认
60+ # -------------------------------------------------
4061if (-not $SkipConfirm ) {
4162 Write-Host " 警告:此脚本仅适用于 Windows 10/11 64 位" - ForegroundColor Green
4263 Write-Host " 建议使用 Windows Terminal 终端管理员方式运行" - ForegroundColor Green
4364 Write-Host " 如果 nvm、git、python 安装失败,建议手动安装" - ForegroundColor Green
44- Write-Host " 下载失败可指定旁路由代理:.\drpys-final .ps1 -UseProxy -ProxyHost `" 192.168.1.21:7890`" " - ForegroundColor Green
65+ Write-Host " 下载失败可指定旁路由代理:.\drpys-auto .ps1 -UseProxy -ProxyHost `" 192.168.1.21:7890`" " - ForegroundColor Green
4566 Write-Host " 如果旁路由也下载失败那就换成道长那个白嫖地址" - ForegroundColor Green
4667 $confirm = Read-Host " 您是否理解并同意继续?(y/n) 默认(y)"
4768 if ($confirm -eq " n" ) { exit 1 }
4869}
4970
50- # ---------- 安装 Node / nvm / git / python ----------
51- Use-ProxyIfNeeded - Script {
52- $needNode = $false
53- if (Test-Cmd " node" ) {
54- # 取出三段版本号
55- $nodeVer = (node - v) -replace ' ^v' , ' ' -split ' \.' | ForEach-Object { [int ]$_ }
56- # 构造一个可比较的整数:主*10000 + 次*100 + 修订
57- $current = $nodeVer [0 ]* 10000 + $nodeVer [1 ]* 100 + $nodeVer [2 ]
58- $require = 20 * 10000 + 18 * 100 + 3 # 20.18.3
59- if ($current -ge $require ) {
60- Write-Host " 已检测到 Node v$ ( $nodeVer -join ' .' ) ≥20.18.3,跳过安装" - ForegroundColor Green
61- } else {
62- Write-Host " Node 版本低于 20.18.3,将使用 nvm 安装/切换到 20.18.3" - ForegroundColor Yellow
63- $needNode = $true
64- }
71+ # -------------------------------------------------
72+ # 5. 安装 nvm(不变)
73+ # -------------------------------------------------
74+ if (-not (Test-Cmd " nvm" )) {
75+ Write-Host " 正在安装 nvm-windows..." - ForegroundColor Green
76+ $nvmSetup = " $env: TEMP \nvm-setup.exe"
77+ Invoke-WebRequestWithProxy " https://github.com/coreybutler/nvm-windows/releases/latest/download/nvm-setup.exe" $nvmSetup
78+ Start-Process - Wait - FilePath $nvmSetup - ArgumentList " /silent"
79+ Remove-Item $nvmSetup
80+ Write-Host " "
81+ Write-Host " --------------------------------------------------" - ForegroundColor Yellow
82+ Write-Host " nvm 已安装完毕,但当前 PowerShell 会话尚未识别到它。" - ForegroundColor Yellow
83+ Write-Host " 请执行以下任意一步后再继续:" - ForegroundColor Cyan
84+ Write-Host " 1) 关闭本窗口,重新打开一个『管理员』PowerShell后,再次执行脚本;" - ForegroundColor Cyan
85+ Write-Host " 2) 或者再次右键选PS运行本脚本。" - ForegroundColor Cyan
86+ Write-Host " --------------------------------------------------" - ForegroundColor Yellow
87+ Read-Host " 按 Enter 键退出本窗口"
88+ exit
89+ } else {
90+ Write-Host " 已检测到 nvm,跳过安装" - ForegroundColor Green
91+ }
92+
93+ # -------------------------------------------------
94+ # 6. 安装/切换 Node
95+ # -------------------------------------------------
96+ $needNode = $false
97+ if (Test-Cmd " node" ) {
98+ $nodeVer = (node - v) -replace ' ^v' , ' ' -split ' \.' | ForEach-Object { [int ]$_ }
99+ $current = $nodeVer [0 ]* 10000 + $nodeVer [1 ]* 100 + $nodeVer [2 ]
100+ $require = 20 * 10000 + 18 * 100 + 3 # 20.18.3
101+ if ($current -ge $require ) {
102+ Write-Host " 已检测到 Node v$ ( $nodeVer -join ' .' ) ≥20.18.3,跳过安装" - ForegroundColor Green
65103 } else {
66- Write-Host " 未检测到 Node,准备安装 " - ForegroundColor Yellow
104+ Write-Host " Node 版本低于 20.18.3,将使用 nvm 安装/切换到 20.18.3 " - ForegroundColor Yellow
67105 $needNode = $true
68106 }
107+ } else {
108+ Write-Host " 未检测到 Node,准备安装" - ForegroundColor Yellow
109+ $needNode = $true
110+ }
111+ if ($needNode ) {
112+ nvm install 20.18 .3
113+ nvm use 20.18 .3
114+ }
69115
70- if (-not (Test-Cmd " nvm" )) {
71- Write-Host " 正在安装 nvm-windows..." - ForegroundColor Green
72- $nvmSetup = " $env: TEMP \nvm-setup.exe"
73- Invoke-WebRequestWithProxy " https://github.com/coreybutler/nvm-windows/releases/latest/download/nvm-setup.exe" $nvmSetup
74- Start-Process - Wait - FilePath $nvmSetup - ArgumentList " /silent"
75- Remove-Item $nvmSetup
76- $env: Path = [System.Environment ]::GetEnvironmentVariable(" Path" , " Machine" ) + " ;" + [System.Environment ]::GetEnvironmentVariable(" Path" , " User" )
116+ # -------------------------------------------------
117+ # 7. 安装 Python 3.11(优先 winget)
118+ # -------------------------------------------------
119+ $pyNeed = $false
120+ try {
121+ $ver = (python - V 2> $null ) -replace ' Python ' , ' '
122+ if ($ver -match ' ^3\.11' ) {
123+ Write-Host " 已检测到 Python 3.11 ($ver ),跳过安装" - ForegroundColor Green
77124 } else {
78- Write-Host " 已检测到 nvm,跳过安装" - ForegroundColor Green
79- }
80-
81- if ($needNode ) {
82- nvm install 20.18 .3
83- nvm use 20.18 .3
125+ Write-Host " 检测到非 3.11 版本,准备覆盖安装 3.11" - ForegroundColor Yellow
126+ $pyNeed = $true
84127 }
128+ } catch {
129+ Write-Host " 未检测到 Python,准备安装 3.11" - ForegroundColor Yellow
130+ $pyNeed = $true
131+ }
132+ if ($pyNeed ) {
133+ Install-Winget
134+ Write-Host " 正在通过 winget 安装 Python 3.11..." - ForegroundColor Green
135+ winget install -- id Python.Python.3.11 - e -- accept- source- agreements -- accept- package- agreements
136+ $env: Path = [System.Environment ]::GetEnvironmentVariable(" Path" , " Machine" ) + " ;" + [System.Environment ]::GetEnvironmentVariable(" Path" , " User" )
137+ }
85138
86- # ---------- 安装 Python 3.11 ----------
87- $pyExe = " python-3.11.9-amd64.exe"
88- $pyUrl = " https://www.python.org/ftp/python/3.11.9/$pyExe "
89- $pyDir = " C:\Python311"
90- $needPy = $false
91-
92- if (Test-Cmd " python" ) {
93- $ver = (& python - V 2>&1 ) -replace ' Python ' , ' '
94- if ($ver -match ' ^3\.11' ) {
95- Write-Host " 已检测到 Python 3.11 ($ver ),跳过安装" - ForegroundColor Green
96- } else {
97- Write-Host " 检测到非 3.11 版本,准备覆盖安装 3.11" - ForegroundColor Yellow
98- $needPy = $true
139+ # -------------------------------------------------
140+ # 安装 Git:winget 优先,失败自动离线
141+ # -------------------------------------------------
142+ if (-not (Test-Cmd " git" )) {
143+ # 1) winget 交互式安装
144+ Install-Winget
145+ if (Test-Cmd winget) {
146+ Write-Host " 正在通过 winget 安装 Git(交互模式)..." - ForegroundColor Green
147+ try {
148+ winget install -- id Git.Git - e -- source winget
149+ if (Test-Cmd git) {
150+ Write-Host " Git 安装成功(winget)" - ForegroundColor Green
151+ $env: Path = [System.Environment ]::GetEnvironmentVariable(" Path" , " Machine" ) + " ;" + [System.Environment ]::GetEnvironmentVariable(" Path" , " User" )
152+ continue
153+ }
154+ } catch {
155+ Write-Host " winget 安装失败,将使用离线包..." - ForegroundColor Yellow
99156 }
100- } else {
101- Write-Host " 未检测到 Python,准备安装 3.11" - ForegroundColor Yellow
102- $needPy = $true
103157 }
104158
105- if ($needPy ) {
106- Write-Host " 正在下载并安装 Python 3.11..." - ForegroundColor Green
107- $exePath = " $env: TEMP \$pyExe "
108- Invoke-WebRequestWithProxy $pyUrl $exePath
109- $proc = Start-Process - FilePath $exePath - ArgumentList `
110- " /quiet InstallAllUsers=1 TargetDir=$pyDir PrependPath=1" - PassThru
111- $proc.WaitForExit ()
112- Remove-Item $exePath
113- $env: Path = [System.Environment ]::GetEnvironmentVariable(" Path" , " Machine" ) + " ;" + [System.Environment ]::GetEnvironmentVariable(" Path" , " User" )
114- if (-not (Test-Cmd " python" )) {
115- Write-Error " Python 3.11 安装失败,脚本终止"
116- exit 1
117- }
159+ # 2) winget 失败 → 离线安装
160+ Write-Host " 正在解析 Git 最新版本..." - ForegroundColor Green
161+ try {
162+ $latestUri = (Invoke-WebRequest - Uri " https://github.com/git-for-windows/git/releases/latest" - MaximumRedirection 0 - ErrorAction SilentlyContinue).Headers.Location
163+ $ver = if ($latestUri ) { $latestUri -replace ' .*/tag/v([0-9.]+).*$' , ' $1' } else { " 2.51.0" }
164+ } catch {
165+ $ver = " 2.51.0"
118166 }
119167
120- $tools = @ {
121- yarn = { npm install - g yarn }
122- pm2 = { npm install - g pm2 }
123- git = { winget install -- id Git.Git - e -- source winget }
124- }
125- foreach ($kv in $tools.GetEnumerator ()) {
126- $cmd = $kv.Key
127- if (-not (Test-Cmd $cmd )) {
128- Write-Host " 正在安装 $cmd ..." - ForegroundColor Yellow
129- & $kv.Value
130- } else {
131- Write-Host " 已检测到 $cmd ,跳过安装" - ForegroundColor Green
132- }
133- }
168+ Write-Host " 正在下载 Git $ver ..." - ForegroundColor Green
169+ $gitSetup = " $env: TEMP \Git-$ver -64-bit.exe"
170+ $gitUrl = " https://github.com/git-for-windows/git/releases/download/v$ver .windows.1/Git-$ver -64-bit.exe"
171+ Invoke-WebRequestWithProxy $gitUrl $gitSetup
172+ Start-Process - Wait - FilePath $gitSetup - ArgumentList `
173+ " /VERYSILENT /NORESTART /NOCANCEL /SP- /CLOSEAPPLICATIONS /RESTARTAPPLICATIONS"
174+ Remove-Item $gitSetup - Force
134175 $env: Path = [System.Environment ]::GetEnvironmentVariable(" Path" , " Machine" ) + " ;" + [System.Environment ]::GetEnvironmentVariable(" Path" , " User" )
176+ } else {
177+ Write-Host " 已检测到 Git,跳过安装" - ForegroundColor Green
135178}
136179
137- # ---------- 工作目录 ----------
180+ # -------------------------------------------------
181+ # 9. 安装全局 npm 工具
182+ # -------------------------------------------------
183+ $tools = @ {
184+ yarn = { npm install - g yarn }
185+ pm2 = { npm install - g pm2 }
186+ }
187+ foreach ($kv in $tools.GetEnumerator ()) {
188+ if (-not (Test-Cmd $kv.Key )) {
189+ Write-Host " 正在安装 $ ( $kv.Key ) ..." - ForegroundColor Yellow
190+ & $kv.Value
191+ } else {
192+ Write-Host " 已检测到 $ ( $kv.Key ) ,跳过安装" - ForegroundColor Green
193+ }
194+ }
195+ $env: Path = [System.Environment ]::GetEnvironmentVariable(" Path" , " Machine" ) + " ;" + [System.Environment ]::GetEnvironmentVariable(" Path" , " User" )
196+
197+ # -------------------------------------------------
198+ # 10. 克隆仓库 / 配置 / 依赖 / PM2(保持不变)
199+ # -------------------------------------------------
138200$repoDir = Read-Host " 请输入项目存放目录(留空则使用当前目录)"
139201if ([string ]::IsNullOrWhiteSpace($repoDir )) { $repoDir = (Get-Location ).Path }
140202$projectPath = Join-Path $repoDir " drpy-node"
141203$remoteRepo = " https://github.com/hjdhnx/drpy-node.git"
142204
143- # ---------- 首次克隆 / 配置 ----------
144205Use-ProxyIfNeeded - Script {
145206 if (-not (Test-Path $projectPath )) {
146207 Write-Host " 正在克隆仓库..." - ForegroundColor Yellow
@@ -152,12 +213,10 @@ Use-ProxyIfNeeded -Script {
152213 }
153214 Set-Location $projectPath
154215
155- # ---------- 生成 env.json(目录不存在则创建,UTF-8 无 BOM) ----------
216+ # 生成 env.json
156217 $configDir = Join-Path $projectPath " config"
157218 $configJson = Join-Path $configDir " env.json"
158- if (-not (Test-Path $configDir )) {
159- New-Item - ItemType Directory - Path $configDir - Force | Out-Null
160- }
219+ if (-not (Test-Path $configDir )) { New-Item - ItemType Directory - Path $configDir - Force | Out-Null }
161220 if (-not (Test-Path $configJson )) {
162221 $utf8NoBom = [System.Text.UTF8Encoding ]::new($false )
163222 $jsonText = @ {
@@ -168,18 +227,15 @@ Use-ProxyIfNeeded -Script {
168227 [System.IO.File ]::WriteAllLines($configJson , $jsonText , $utf8NoBom )
169228 }
170229
171- # ---------- 生成 .env(复制后重写为 UTF-8 无 BOM) ----------
230+ # 生成 .env
172231 $envFile = Join-Path $projectPath " .env"
173232 if (-not (Test-Path $envFile )) {
174233 $template = Join-Path $projectPath " .env.development"
175234 Copy-Item $template $envFile
176-
177- # 强制无 BOM 重写
178235 $utf8NoBom = [System.Text.UTF8Encoding ]::new($false )
179236 $content = [System.IO.File ]::ReadAllText($envFile )
180237 [System.IO.File ]::WriteAllText($envFile , $content , $utf8NoBom )
181238
182- # 交互式替换
183239 $cookieAuth = Read-Host " 网盘入库密码(默认 drpys)"
184240 $apiUser = Read-Host " 登录用户名(默认 admin)"
185241 $apiPass = Read-Host " 登录密码(默认 drpys)"
@@ -197,7 +253,7 @@ Use-ProxyIfNeeded -Script {
197253 if (-not (Test-Path " node_modules" )) {
198254 Write-Host " 首次安装 Node 依赖..." - ForegroundColor Yellow
199255 yarn config set registry https:// registry.npmmirror.com /
200- yarn install
256+ yarn
201257 } elseif ((git diff HEAD^ HEAD -- name- only 2> $null ) -match [regex ]::Escape(" yarn.lock" )) {
202258 Write-Host " 检测到 yarn.lock 变动,更新 Node 依赖..." - ForegroundColor Yellow
203259 yarn install -- registry https:// registry.npmmirror.com /
@@ -208,8 +264,7 @@ Use-ProxyIfNeeded -Script {
208264 Write-Host " 首次创建 Python 虚拟环境..." - ForegroundColor Yellow
209265 python - m venv .venv
210266 & .\.venv\Scripts\Activate.ps1
211- Write-Host " 首次安装 Python 依赖..." - ForegroundColor Yellow
212- python.exe - m pip install -- upgrade pip
267+ python - m pip install -- upgrade pip
213268 pip install - r spider\py\base\requirements.txt - i https:// mirrors.cloud.tencent.com / pypi/ simple
214269 } else {
215270 & .\.venv\Scripts\Activate.ps1
@@ -219,6 +274,7 @@ Use-ProxyIfNeeded -Script {
219274 }
220275 }
221276
277+ # PM2
222278 if (-not (pm2 list | Select-String " drpyS.*online" )) {
223279 Write-Host " 首次启动 PM2 进程..." - ForegroundColor Yellow
224280 pm2 start index.js -- name drpyS -- update-env
@@ -228,20 +284,19 @@ Use-ProxyIfNeeded -Script {
228284 }
229285}
230286
231- # ---------- 任务计划 ----------
287+ # -------------------------------------------------
288+ # 11. 计划任务(开机自启 + 6 小时更新)
289+ # -------------------------------------------------
232290$taskStartup = " drpyS_PM2_Startup"
233291$taskUpdate = " drpyS_Update"
234-
235292$pm2 = (Get-Command pm2.cmd - ErrorAction SilentlyContinue).Source
236293$nodeExe = (Get-Command node.exe - ErrorAction SilentlyContinue).Source
237-
238294if ($pm2 -and $nodeExe ) {
239295 $taskStartup , $taskUpdate | ForEach-Object {
240296 if (Get-ScheduledTask - TaskName $_ - ErrorAction SilentlyContinue) {
241297 Unregister-ScheduledTask - TaskName $_ - Confirm:$false
242298 }
243299 }
244-
245300 $commonSettings = New-ScheduledTaskSettingsSet `
246301 - AllowStartIfOnBatteries - DontStopIfGoingOnBatteries - StartWhenAvailable
247302
@@ -257,16 +312,17 @@ if ($pm2 -and $nodeExe) {
257312 # 每 6 小时更新
258313 $action = New-ScheduledTaskAction `
259314 - Execute " powershell.exe" `
260- - Argument " -NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -Command `" & { `$ env:PM2_HOME='C:\$env: USERNAME \.pm2'; Set-Location '$projectPath '; git fetch origin; if (git status -uno | Select-String 'Your branch is behind') { git reset --hard origin/main; yarn install --registry https://registry.npmmirror.com/; pip install -r spider\py\base\requirements.txt -i https://mirrors.cloud.tencent.com/pypi/simple; & '$pm2 ' restart drpyS } }`" " `
315+ - Argument " -NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -Command `" & { `$ env:PM2_HOME='C:\$env: USERNAME \.pm2'; Set-Location '$projectPath '; git fetch origin; if (git status -uno | Select-String 'Your branch is behind') { git reset --hard origin/main; yarn install --registry https://registry.npmmirror.com/ ; pip install -r spider\py\base\requirements.txt -i https://mirrors.cloud.tencent.com/pypi/simple ; & '$pm2 ' restart drpyS } }`" " `
261316 - WorkingDirectory $projectPath
262317 $trigger = New-ScheduledTaskTrigger - Once - At (Get-Date ) - RepetitionInterval (New-TimeSpan - Hours 6 )
263318 Register-ScheduledTask - TaskName $taskUpdate - Action $action - Trigger $trigger - Settings $commonSettings - User " SYSTEM" - RunLevel Highest - Force | Out-Null
264319 Write-Host " 已创建/更新每 6 小时更新任务:$taskUpdate " - ForegroundColor Green
265320}
266321
267- # ------ 退出虚拟环境 ------
322+ # -------------------------------------------------
323+ # 12. 结束提示
324+ # -------------------------------------------------
268325deactivate
269- # ---------- 完成 ----------
270326$ip = (ipconfig | Select-String " IPv4 地址" | Select-Object - First 1 ).ToString().Split(" :" )[-1 ].Trim()
271327$public = (Invoke-RestMethod " https://ipinfo.io/ip" )
272328Write-Host " 内网地址:http://${ip} :5757" - ForegroundColor Green
0 commit comments