如何实现本地PDF与远程Web文件同步及认证站点访问?
解决方案:触发式PDF同步与认证站点访问
一、公共PDF的智能同步与灵活打开
改进版PowerShell脚本(同步+指定阅读器)
该脚本会先检查远程PDF是否比本地新,仅在需要时下载,然后用你指定的阅读器打开:
# 配置参数 $remotePdfUrl = "https://lorempdf.com/140/85/1" $localPdfPath = "C:\Users\你的用户名\source\test.pdf" $pdfViewerPath = "C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe" # 替换为你的阅读器路径 # 同步PDF函数(仅远程更新时下载) function Sync-Pdf { try { # 获取远程文件的最后修改时间 $headerResponse = Invoke-WebRequest -Uri $remotePdfUrl -Method Head -ErrorAction Stop $remoteLastModified = $headerResponse.Headers['Last-Modified'] | Get-Date # 检查本地文件状态 if (Test-Path $localPdfPath) { $localLastModified = (Get-Item $localPdfPath).LastWriteTime # 允许1分钟时差,避免因时间同步问题误触发下载 if ($remoteLastModified -le $localLastModified.AddMinutes(1)) { Write-Host "本地PDF已是最新版本" return } } # 下载更新 Write-Host "正在下载最新PDF..." Invoke-WebRequest -Uri $remotePdfUrl -OutFile $localPdfPath -ErrorAction Stop Write-Host "PDF更新完成" } catch { Write-Warning "同步失败:$_" } } # 执行同步并打开文件 Sync-Pdf if (Test-Path $localPdfPath) { Start-Process -FilePath $pdfViewerPath -ArgumentList "`"$localPdfPath`"" } else { Write-Warning "本地PDF不存在,无法打开" }
触发式同步设置
打开PDF时自动同步
右键桌面→新建快捷方式,输入以下内容(替换脚本路径):powershell.exe -ExecutionPolicy Bypass -File "C:\你的脚本路径\sync-and-open-pdf.ps1"之后双击该快捷方式即可自动同步并打开PDF。
定期自动同步
打开「任务计划程序」→创建基本任务:- 触发器选择「每天」/「每周」,设置执行时间
- 操作选择「启动程序」,程序填
powershell.exe,参数填:-ExecutionPolicy Bypass -File "C:\你的脚本路径\sync-only-pdf.ps1"
(注:需创建仅包含
Sync-Pdf函数的精简脚本)联网时自动同步
在任务计划程序中创建任务,触发器选择「事件」:- 日志选「系统」,来源选「Microsoft-Windows-NetworkProfile」,事件ID填
10000(代表网络连接成功) - 操作同定期同步,执行精简版同步脚本
- 日志选「系统」,来源选「Microsoft-Windows-NetworkProfile」,事件ID填
二、Shibboleth认证站点的PDF获取
Shibboleth基于SAML协议,无法通过-Credential参数直接认证,需借助浏览器会话或自动化工具:
方案1:复用浏览器已登录的Cookie
Windows下Chrome的Cookie存储在加密文件中,可通过以下PowerShell脚本解密并复用(需以当前登录用户运行):
# 需先安装CredentialManager模块:Install-Module CredentialManager -Scope CurrentUser $cookiePath = "$env:LOCALAPPDATA\Google\Chrome\User Data\Default\Cookies" $dbConnection = "Data Source=$cookiePath;Version=3;New=False;ReadOnly=True;" # 解密Cookie(依赖DPAPI,仅当前用户可解密) function Decrypt-Cookie { param([byte[]]$encryptedData) if ($encryptedData.Length -le 0) { return $null } $decrypted = [System.Security.Cryptography.ProtectedData]::Unprotect( $encryptedData, $null, [System.Security.Cryptography.DataProtectionScope]::CurrentUser ) return [System.Text.Encoding]::UTF8.GetString($decrypted) } # 从Chrome数据库读取目标站点Cookie $conn = New-Object System.Data.SQLite.SQLiteConnection($dbConnection) $conn.Open() $cmd = $conn.CreateCommand() $cmd.CommandText = "SELECT name, encrypted_value FROM cookies WHERE host_key LIKE '%你的shibboleth站点域名%'" $reader = $cmd.ExecuteReader() $cookies = @() while ($reader.Read()) { $name = $reader["name"] $value = Decrypt-Cookie $reader["encrypted_value"] $cookies += [PSCustomObject]@{Name=$name;Value=$value} } $conn.Close() # 使用Cookie请求PDF $session = New-Object Microsoft.PowerShell.Commands.WebRequestSession foreach ($cookie in $cookies) { $session.Cookies.Add((New-Object System.Net.Cookie($cookie.Name, $cookie.Value, "/", "你的站点域名"))) } Invoke-WebRequest -Uri "你的受保护PDF链接" -WebSession $session -OutFile "C:\本地保存路径\protected.pdf"
方案2:无头浏览器自动化(Puppeteer)
- 安装Node.js后,执行
npm install puppeteer - 创建Node.js脚本处理登录并下载PDF:
const puppeteer = require('puppeteer'); const fs = require('fs'); (async () => { // 首次运行显示浏览器窗口手动登录,后续复用Cookie const browser = await puppeteer.launch({ headless: false, defaultViewport: null }); const page = await browser.newPage(); const cookieFile = './shibboleth-cookies.json'; const targetPdfUrl = '你的受保护PDF链接'; const localSavePath = 'C:\\Users\\你的用户名\\source\\protected.pdf'; // 加载已保存的Cookie if (fs.existsSync(cookieFile)) { const cookies = JSON.parse(fs.readFileSync(cookieFile)); await page.setCookie(...cookies); } await page.goto(targetPdfUrl); // 检测是否需要登录(替换为你的登录页面元素选择器) const usernameField = await page.$('#username'); if (usernameField) { console.log('请在弹出的浏览器中完成登录...'); // 等待登录完成并跳转至PDF页面 await page.waitForNavigation({ waitUntil: 'networkidle2' }); // 保存Cookie供下次使用 const cookies = await page.cookies(); fs.writeFileSync(cookieFile, JSON.stringify(cookies)); console.log('登录成功,已保存Cookie'); } // 下载PDF const response = await page.goto(targetPdfUrl); const pdfBuffer = await response.buffer(); fs.writeFileSync(localSavePath, pdfBuffer); console.log('PDF下载完成'); await browser.close(); })();
- 在PowerShell中运行该脚本:
node .\shibboleth-pdf-download.js,之后即可用之前的脚本打开本地PDF。
内容的提问来源于stack exchange,提问作者Seth Buesing
相关产品推荐
相关产品推荐

