@@ -9,12 +9,11 @@ $ErrorActionPreference = "Stop"
99if (-not ([Security.Principal.WindowsPrincipal ][Security.Principal.WindowsIdentity ]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole ]::Administrator)) {
1010 Write-Host " 当前非管理员权限,正在尝试以管理员身份重新启动..." - ForegroundColor Yellow
1111 $arguments = " -NoProfile -ExecutionPolicy Bypass -File `" $ ( $MyInvocation.MyCommand.Path ) `" "
12- $params = $MyInvocation .UnboundArguments
13- foreach ($p in $params ) { $arguments += " `" $p `" " }
12+ if ( $UseProxy ) { $arguments += " -UseProxy -ProxyHost `" $ProxyHost `" " }
13+ if ($SkipConfirm ) { $arguments += " -SkipConfirm " }
1414 Start-Process powershell - ArgumentList $arguments - Verb RunAs
1515 exit
1616}
17-
1817Set-Location - LiteralPath $PSScriptRoot
1918
2019# ---------- 代理 ----------
@@ -52,11 +51,15 @@ if (-not $SkipConfirm) {
5251Use-ProxyIfNeeded - Script {
5352 $needNode = $false
5453 if (Test-Cmd " node" ) {
54+ # 取出三段版本号
5555 $nodeVer = (node - v) -replace ' ^v' , ' ' -split ' \.' | ForEach-Object { [int ]$_ }
56- if ($nodeVer [0 ] -ge 20 ) {
57- Write-Host " 已检测到 Node v$ ( $nodeVer -join ' .' ) ≥20,跳过安装" - ForegroundColor Green
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
5861 } else {
59- Write-Host " Node 版本低于 20,将使用 nvm 安装/切换到 20" - ForegroundColor Yellow
62+ Write-Host " Node 版本低于 20.18.3 ,将使用 nvm 安装/切换到 20.18.3 " - ForegroundColor Yellow
6063 $needNode = $true
6164 }
6265 } else {
@@ -76,15 +79,48 @@ Use-ProxyIfNeeded -Script {
7679 }
7780
7881 if ($needNode ) {
79- nvm install 20
80- nvm use 20
82+ nvm install 20.18 .3
83+ nvm use 20.18 .3
84+ }
85+
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
99+ }
100+ } else {
101+ Write-Host " 未检测到 Python,准备安装 3.11" - ForegroundColor Yellow
102+ $needPy = $true
103+ }
104+
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+ }
81118 }
82119
83120 $tools = @ {
84121 yarn = { npm install - g yarn }
85122 pm2 = { npm install - g pm2 }
86123 git = { winget install -- id Git.Git - e -- source winget }
87- python = { winget install -- id Python.Python.3 - e -- source winget }
88124 }
89125 foreach ($kv in $tools.GetEnumerator ()) {
90126 $cmd = $kv.Key
@@ -116,43 +152,71 @@ Use-ProxyIfNeeded -Script {
116152 }
117153 Set-Location $projectPath
118154
119- $configJson = " config\env.json"
155+ # ---------- 生成 env.json(目录不存在则创建,UTF-8 无 BOM) ----------
156+ $configDir = Join-Path $projectPath " config"
157+ $configJson = Join-Path $configDir " env.json"
158+ if (-not (Test-Path $configDir )) {
159+ New-Item - ItemType Directory - Path $configDir - Force | Out-Null
160+ }
120161 if (-not (Test-Path $configJson )) {
121- @ {
162+ $utf8NoBom = [System.Text.UTF8Encoding ]::new($false )
163+ $jsonText = @ {
122164 ali_token = " " ; ali_refresh_token = " " ; quark_cookie = " "
123165 uc_cookie = " " ; bili_cookie = " " ; thread = " 10"
124166 enable_dr2 = " 1" ; enable_py = " 2"
125- } | ConvertTo-Json | Set-Content $configJson - Encoding UTF8
167+ } | ConvertTo-Json
168+ [System.IO.File ]::WriteAllLines($configJson , $jsonText , $utf8NoBom )
126169 }
127170
128- $envFile = " .env"
171+ # ---------- 生成 .env(复制后重写为 UTF-8 无 BOM) ----------
172+ $envFile = Join-Path $projectPath " .env"
129173 if (-not (Test-Path $envFile )) {
130- Copy-Item " .env.development" $envFile
174+ $template = Join-Path $projectPath " .env.development"
175+ Copy-Item $template $envFile
176+
177+ # 强制无 BOM 重写
178+ $utf8NoBom = [System.Text.UTF8Encoding ]::new($false )
179+ $content = [System.IO.File ]::ReadAllText($envFile )
180+ [System.IO.File ]::WriteAllText($envFile , $content , $utf8NoBom )
181+
182+ # 交互式替换
131183 $cookieAuth = Read-Host " 网盘入库密码(默认 drpys)"
132184 $apiUser = Read-Host " 登录用户名(默认 admin)"
133185 $apiPass = Read-Host " 登录密码(默认 drpys)"
134186 $apiPwd = Read-Host " 订阅PWD值(默认 dzyyds)"
135- (Get-Content $envFile ) `
136- -replace ' COOKIE_AUTH_CODE = .*' , " COOKIE_AUTH_CODE = $ ( if ([string ]::IsNullOrWhiteSpace($cookieAuth )){' drpys' }else {$cookieAuth }) " `
137- -replace ' API_AUTH_NAME = .*' , " API_AUTH_NAME = $ ( if ([string ]::IsNullOrWhiteSpace($apiUser )){' admin' }else {$apiUser }) " `
138- -replace ' API_AUTH_CODE = .*' , " API_AUTH_CODE = $ ( if ([string ]::IsNullOrWhiteSpace($apiPass )){' drpys' }else {$apiPass }) " `
139- -replace ' API_PWD = .*' , " API_PWD = $ ( if ([string ]::IsNullOrWhiteSpace($apiPwd )){' dzyyds' }else {$apiPwd }) " |
140- Set-Content $envFile - Encoding UTF8
187+
188+ $newContent = [System.IO.File ]::ReadAllText($envFile ) `
189+ -replace ' (?<=^COOKIE_AUTH_CODE\s*=\s*).*$' , $ (if ([string ]::IsNullOrWhiteSpace($cookieAuth )){' drpys' }else {$cookieAuth }) `
190+ -replace ' (?<=^API_AUTH_NAME\s*=\s*).*$' , $ (if ([string ]::IsNullOrWhiteSpace($apiUser )){' admin' }else {$apiUser }) `
191+ -replace ' (?<=^API_AUTH_CODE\s*=\s*).*$' , $ (if ([string ]::IsNullOrWhiteSpace($apiPass )){' drpys' }else {$apiPass }) `
192+ -replace ' (?<=^API_PWD\s*=\s*).*$' , $ (if ([string ]::IsNullOrWhiteSpace($apiPwd )){' dzyyds' }else {$apiPwd })
193+ [System.IO.File ]::WriteAllText($envFile , $newContent , $utf8NoBom )
141194 }
142195
196+ # Node 依赖
143197 if (-not (Test-Path " node_modules" )) {
144198 Write-Host " 首次安装 Node 依赖..." - ForegroundColor Yellow
145199 yarn config set registry https:// registry.npmmirror.com /
146- yarn
200+ yarn install
201+ } elseif ((git diff HEAD^ HEAD -- name- only 2> $null ) -match [regex ]::Escape(" yarn.lock" )) {
202+ Write-Host " 检测到 yarn.lock 变动,更新 Node 依赖..." - ForegroundColor Yellow
203+ yarn install -- registry https:// registry.npmmirror.com /
147204 }
205+
206+ # Python 依赖
148207 if (-not (Test-Path " .venv\pyvenv.cfg" )) {
149208 Write-Host " 首次创建 Python 虚拟环境..." - ForegroundColor Yellow
150209 python - m venv .venv
151- }
152- & .\.venv\Scripts\Activate.ps1
153- if ((git diff HEAD^ HEAD -- name- only 2> $null ) -match " requirements.txt" ) {
154- Write-Host " 检测到 requirements.txt 变动,更新 Python 依赖..." - ForegroundColor Yellow
210+ & .\.venv\Scripts\Activate.ps1
211+ Write-Host " 首次安装 Python 依赖..." - ForegroundColor Yellow
212+ python.exe - m pip install -- upgrade pip
155213 pip install - r spider\py\base\requirements.txt - i https:// mirrors.cloud.tencent.com / pypi/ simple
214+ } else {
215+ & .\.venv\Scripts\Activate.ps1
216+ if ((git diff HEAD^ HEAD -- name- only 2> $null ) -match [regex ]::Escape(" spider\py\base\requirements.txt" )) {
217+ Write-Host " 检测到 requirements.txt 变动,更新 Python 依赖..." - ForegroundColor Yellow
218+ pip install - r spider\py\base\requirements.txt - i https:// mirrors.cloud.tencent.com / pypi/ simple
219+ }
156220 }
157221
158222 if (-not (pm2 list | Select-String " drpyS.*online" )) {
@@ -168,14 +232,10 @@ Use-ProxyIfNeeded -Script {
168232$taskStartup = " drpyS_PM2_Startup"
169233$taskUpdate = " drpyS_Update"
170234
171- # 获取绝对路径
172235$pm2 = (Get-Command pm2.cmd - ErrorAction SilentlyContinue).Source
173236$nodeExe = (Get-Command node.exe - ErrorAction SilentlyContinue).Source
174237
175- if (-not $pm2 -or -not $nodeExe ) {
176- Write-Warning " 找不到 pm2.cmd 或 node.exe,跳过计划任务注册"
177- } else {
178- # 删除旧任务
238+ if ($pm2 -and $nodeExe ) {
179239 $taskStartup , $taskUpdate | ForEach-Object {
180240 if (Get-ScheduledTask - TaskName $_ - ErrorAction SilentlyContinue) {
181241 Unregister-ScheduledTask - TaskName $_ - Confirm:$false
@@ -185,35 +245,30 @@ if (-not $pm2 -or -not $nodeExe) {
185245 $commonSettings = New-ScheduledTaskSettingsSet `
186246 - AllowStartIfOnBatteries - DontStopIfGoingOnBatteries - StartWhenAvailable
187247
188- # 1) 开机自启(直接启动 drpyS,不依赖 dump)
248+ # 开机自启
189249 $action = New-ScheduledTaskAction `
190250 - Execute " powershell.exe" `
191- - Argument " -NoProfile -ExecutionPolicy Bypass -Command `" & { Set-Location ' $projectPath '; & '$nodeExe ' ' $ projectPath\index.js' | & '$pm2 ' start '$projectPath \index.js' --name drpyS --update-env }`" " `
251+ - Argument " -NoProfile -ExecutionPolicy Bypass -Command `" & { `$ env:PM2_HOME='C:\ $ env: USERNAME \.pm2 '; Set-Location '$projectPath '; & '$pm2 ' start '$projectPath \index.js' --name drpyS --update-env }`" " `
192252 - WorkingDirectory $projectPath
193253 $trigger = New-ScheduledTaskTrigger - AtStartup - RandomDelay (New-TimeSpan - Seconds 30 )
194- Register-ScheduledTask - TaskName $taskStartup `
195- - Action $action - Trigger $trigger - Settings $commonSettings `
196- - User " SYSTEM" - RunLevel Highest - Force | Out-Null
197- Write-Host " 已创建/更新开机自启任务:$taskStartup " - ForegroundColor Yellow
254+ Register-ScheduledTask - TaskName $taskStartup - Action $action - Trigger $trigger - Settings $commonSettings - User " SYSTEM" - RunLevel Highest - Force | Out-Null
255+ Write-Host " 已创建/更新开机自启任务:$taskStartup " - ForegroundColor Green
198256
199- # 2) 每 24 h 更新
257+ # 每 6 小时更新
200258 $action = New-ScheduledTaskAction `
201259 - Execute " powershell.exe" `
202- - Argument " -NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -Command `" & { Set-Location '$projectPath '; git fetch origin; if (git status -uno | Select-String 'Your branch is behind') { git reset --hard origin/main; yarn --prod --silent; if (git diff HEAD^ HEAD --name-only | Select-String 'spider/py/base/requirements.txt') { python -m venv .venv; & .\.venv\Scripts\Activate.ps1; pip install -r spider\py\base\requirements.txt -q } & '$pm2 ' restart drpyS } }`" " `
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 } }`" " `
203261 - WorkingDirectory $projectPath
204- $trigger = New-ScheduledTaskTrigger - Once - At (Get-Date ) - RepetitionInterval (New-TimeSpan - Hours 24 )
205- Register-ScheduledTask - TaskName $taskUpdate `
206- - Action $action - Trigger $trigger - Settings $commonSettings `
207- - User " SYSTEM" - RunLevel Highest - Force | Out-Null
208- Write-Host " 已创建/更新每 24 小时更新任务:$taskUpdate " - ForegroundColor Yellow
262+ $trigger = New-ScheduledTaskTrigger - Once - At (Get-Date ) - RepetitionInterval (New-TimeSpan - Hours 6 )
263+ Register-ScheduledTask - TaskName $taskUpdate - Action $action - Trigger $trigger - Settings $commonSettings - User " SYSTEM" - RunLevel Highest - Force | Out-Null
264+ Write-Host " 已创建/更新每 6 小时更新任务:$taskUpdate " - ForegroundColor Green
209265}
210266
211267# ---------- 完成 ----------
212- $ip = (ipconfig | Select-String " IPv4 地址" | Select-Object - First 1 ).ToString().Split(" :" )[-1 ].Trim()
268+ $ip = (ipconfig | Select-String " IPv4 地址" | Select-Object - First 1 ).ToString().Split(" :" )[-1 ].Trim()
213269$public = (Invoke-RestMethod " https://ipinfo.io/ip" )
214- Write-Host " 内网地址:http://${ip} :5757" - ForegroundColor Yellow
215- Write-Host " 公网地址:http://${public} :5757" - ForegroundColor Yellow
216- Write-Host " 脚本执行完成!重启后 drpyS 自动启动并每 24 小时检查更新。" - ForegroundColor Yellow
217- Write-Host " 脚本只需要执行一次,无需重复执行。" - ForegroundColor Yellow
218- Write-Host " 按任意键退出!!!" - ForegroundColor Yellow
270+ Write-Host " 内网地址:http://${ip} :5757" - ForegroundColor Green
271+ Write-Host " 公网地址:http://${public} :5757" - ForegroundColor Green
272+ Write-Host " 脚本执行完成!重启后 drpyS 自动启动并每 6 小时检查更新。" - ForegroundColor Green
273+ Write-Host " 按任意键退出!!!" - ForegroundColor Green
219274Read-Host
0 commit comments