You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

在Ubuntu/Orange Pi 5环境下通过终端获取Kiosk模式Chromium的已打开标签页(PowerShell脚本开发场景)

在Ubuntu/Orange Pi 5环境下通过终端获取Kiosk模式Chromium的已打开标签页(PowerShell脚本开发场景)

看起来你现在卡在了通过终端准确获取Kiosk模式下Chromium当前打开的标签页这一步,而且想优化现有的PowerShell脚本,让它更像保活工具而非粗暴重启。我结合你的场景给你分点梳理解决方案和优化建议:


一、核心问题:获取Chromium当前打开的标签页(替代BroTab和Session文件方案)

你的核心需求是判断当前标签页是否符合配置,避免不必要的重启。之前尝试的Session文件读取存在更新不及时的问题,这里给你两个更可靠的方案:

1. 推荐:利用Chromium远程调试接口(DevTools Protocol)

Chromium支持通过远程调试端口暴露实时标签页信息,这是最准确的方式,无论Chromium是手动还是终端启动都能正常工作:

  • 步骤1:修改Chromium启动命令,添加远程调试端口参数:
$chrome = "DISPLAY=:0 chromium-browser $link_string --kiosk --disable-session-crashed-bubble --disable-infobars --remote-debugging-port=9222 &> /dev/null &"
  • 步骤2:在PowerShell中调用接口获取标签页
function Get-ChromiumActiveTabs {
    param([string]$Ip)
    try {
        # 调用远程调试接口获取所有标签页JSON数据
        $tabData = Invoke-RestMethod -Uri "http://$Ip:9222/json" -ErrorAction Stop
        # 提取所有页面类型标签页的URL
        return $tabData | Where-Object { $_.type -eq "page" } | Select-Object -ExpandProperty url
    }
    catch {
        Write-Error "无法获取$Ip的Chromium标签页:$_"
        return @()
    }
}

# 在主循环中使用该函数
$currentTabs = Get-ChromiumActiveTabs -Ip $ip
$expectedTabs = $link_string -split "\s+" | ForEach-Object { $_.Trim() }

# 检查所有预期URL是否都在当前标签页中
$needsRestart = $false
foreach ($url in $expectedTabs) {
    if ($currentTabs -notcontains $url) {
        $needsRestart = $true
        break
    }
}

if ($needsRestart) {
    Write-Host "$ip的标签页不匹配,执行重启..."
    Invoke-PiCommand -Ip $ip -Command $exitchrome -SuppressOutput
    Start-Sleep -Seconds 5
    Invoke-PiCommand -Ip $ip -Command $chrome -SuppressOutput
} else {
    Write-Host "$ip的标签页符合要求,跳过重启"
}

2. 备选方案:通过进程命令行参数判断(仅适用于固定标签页场景)

如果你的场景是脚本启动固定标签页,没有手动添加标签的需求,可以直接检查Chromium进程的命令行参数:

$chromiumCmd = Invoke-PiCommand -Ip $ip -Command "ps aux | grep chromium-browser | grep -v grep"
$needsRestart = -not ($chromiumCmd -match [regex]::Escape($link_string))

这个方案更轻量,但不支持动态标签页的检测。


二、脚本整体优化建议(针对你的需求:函数、错误日志、邮件通知)

1. 重构重复代码为函数,提升可维护性

你提到函数使用有困难,这里给你封装几个核心函数,统一处理SSH执行、错误捕获:

# 通用SSH执行函数,带错误处理
function Invoke-PiCommand {
    param(
        [Parameter(Mandatory=$true)][string]$Ip,
        [Parameter(Mandatory=$true)][string]$Command,
        [switch]$SuppressOutput
    )
    try {
        # 捕获标准输出和错误输出
        $output = ssh orangepi@$Ip -X $Command 2>&1
        if (-not $SuppressOutput) {
            return $output -join "`n"
        }
    }
    catch {
        $errorMsg = "在$Ip执行命令失败:`n命令:$Command`n错误:$_"
        Write-Error $errorMsg
        # 这里可以调用错误日志/邮件通知函数
        Log-Error -Message $errorMsg
        Send-FailureAlert -Ip $Ip -Message $errorMsg
        throw $errorMsg # 可选:终止脚本或继续执行
    }
}

# 获取分辨率的函数(用正则替代字符串索引,更可靠)
function Get-PiResolution {
    param([string]$Ip)
    $xrandrOutput = Invoke-PiCommand -Ip $Ip -Command "xrandr -display :0.0"
    $resMatch = [regex]::Match($xrandrOutput, '(\d{3,4} x \d{3,4})').Value
    return $resMatch
}

2. 添加错误日志与邮件通知

# 错误日志函数
function Log-Error {
    param([string]$Message)
    $logPath = "C:\temp\display_management_errors.log"
    $logEntry = "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] $Message"
    Add-Content -Path $logPath -Value $logEntry -Encoding UTF8
}

# 邮件通知函数
function Send-FailureAlert {
    param(
        [string]$Ip,
        [string]$Message
    )
    $smtpParams = @{
        SmtpServer = "你的SMTP服务器地址"
        From = "display-monitor@yourdomain.com"
        To = "admin@yourdomain.com"
        Subject = "显示终端$Ip异常告警"
        Body = "异常详情:`n$Message"
        Port = 587 # 或你的SMTP端口
        UseSsl = $true
        Credential = (Get-Credential -Message "输入SMTP凭据") # 或存储在安全字符串中
    }
    Send-MailMessage @smtpParams -ErrorAction SilentlyContinue
}

3. 优化保活与重启逻辑

  • 把“每30分钟强制重启”改成“定时检查(比如每5分钟),仅在异常时重启”
  • 替换粗暴的killall -9为温和的终止,避免Session文件损坏:
# 先尝试正常关闭,失败再强制杀死
$exitchrome = "killall chromium-browser &>/dev/null; sleep 3; killall -9 chromium-browser &>/dev/null; exit;"

4. 时间处理优化(支持所有月份的月末更新)

你原来的$Calendar.Day -eq '28'不够通用,改成自动判断当月最后一天:

$isLastDayOfMonth = $Calendar.Day -eq [DateTime]::DaysInMonth($Calendar.Year, $Calendar.Month)
if ($isLastDayOfMonth -and $Calendar -gt $updatestart -and $Calendar -lt $updatecutoff) {
    Write-Host "$ip执行月末系统更新..."
    Invoke-PiCommand -Ip $ip -Command "sudo apt-get update; sudo apt-get upgrade -y; sudo reboot;"
    Start-Sleep -Seconds 60
}

三、你提供的原始脚本格式化版本

## SCRIPT TO RERESH AND MANAGE PI BOXES FOR DISPLAYS ##

$getr=$null;

## SET VARIABLES TO GET DATES AND FOR SPECIFIC TIMES IN REGARDS TO UPDATES
$Calendar = Get-Date
$updatestart = Get-Date -Hour 11 -Minute 55
$updatecutoff = Get-Date -Hour 12 -Minute 01

## SET VARIABLES FOR PI INSTRUCTIONS
$exitchrome = "killall -9 chromium-browser &>/dev/null; exit;" ## QUITS BROWSER AND EXITS SCRIPT

Get-Content -Path "C:\temp\ip.txt" | Foreach-Object { ## LOOP THROUGH CONTENTS OF TEXT FILE - IP.TXT
    $textfile = $_;
    $pos = $textfile.IndexOf("|") ## LOOK FOR PIPE CHARECTER IN TEXT FILE
    $link_string = $textfile.Substring($pos+1) ## CONTENTS AFTER PIPE CHARECTER
    $ip = $textfile.Substring(0, $pos) ## CONTENTS BEFORE PIPE CHARECTER

    echo $ip

    $chrome = "DISPLAY=:0 chromium-browser " + $link_string + " --kiosk --disable-session-crashed-bubble --disable-infobars &> /dev/null &" ## STARTS BROWSER IN KIOSK MODE

    ## PLAY CODE##
    $i = 0
    $c = 0
    $w = 1
    $wb_chk = "cat -e ~/.config/chromium/Default/Sessions/Tabs_* | sed -e 's/\^@/\n/g' -e '/_\/chrome/d' | grep -Po '(http|https)://\K.*' | sort -u" ## CHECK BROWSER FOR OPEN TABS
    $wb_chk_res = ssh orangepi@"$ip" -X "$wb_chk" | Out-String

    foreach($url_array in -split $link_string)
    {
        $url_array_pos = $url_array.IndexOf("/") ## LOOK FOR SLASH IN VARIABLE
        $url_array = $url_array.Substring($url_array_pos+2) ## REMOVE CONTENTS AFTER SLASH
        $i++
        foreach($wbl_chk in -split $wb_chk_res)
        {
            $w++
            if ($wbl_chk -eq $url_array) {
                $c++
            }
        }
    }

    echo "$w websites were checked"
    echo "There are $c live on the display"
    echo "$c websites match the $i URLS in the config file"
    ## PLAY CODE##

    If ($Calendar.Day -eq '28' -AND $Calendar.TimeOfDay -gt $updatestart.TimeOfDay -AND $Calendar.TimeOfDay -lt $updatecutoff.TimeOfDay) { ## IF END OF THE MONTH, RUN UPDATES
        ssh -p 222 pi@"$ip" -X "sudo apt-get update; sudo apt-get upgrade -y; sudo reboot;"
        Start-Sleep -s 60
    }

    ## CHECK DISPLAY RES ##
    $getr = ssh orangepi@"$ip" -X "xrandr -display :0.0;" | Out-String

    $res_pos = $getr.IndexOf(",") ## LOOK FOR COMMA IN VARIABLE
    $getr = $getr.Substring($res_pos+2) ## REMOVE CONTENTS AFTER COMMA
    $res_pos = $getr.IndexOf(",") ## LOOK FOR COMMA IN VARIABLE
    $getr = $getr.Substring(0, $res_pos) ## REMOVE CONTENTS BEFORE COMMA
    $res_pos = $getr.IndexOf(" ") ## LOOK FOR SPACE IN VARIABLE
    $getr = $getr.Substring($res_pos+1) ## REMOVE CONTENTS BEFORE SPACE

    $uptime = ssh orangepi@"$ip" -X "awk '{print $1}' /proc/uptime" | Out-String
    $up_pos = $uptime.IndexOf(" ") ## LOOK FOR SPACE IN VARIABLE
    $uptime = $uptime.Substring(0,$up_pos) ## CONTENTS BEFORE SPACE

    echo $uptime
    echo $getr

    if ($uptime -lt "1800.00" -Or $getr -ne "1920 x 1080") {
        echo "Forcing Display Resolution";
        ssh orangepi@"$ip" -X "sudo service lightdm restart;"
        Start-Sleep -s 10;
        ssh orangepi@"$ip" -X "$chrome";
        Start-Sleep -s 10;
        ssh orangepi@"$ip" -X "$exitchrome";
        Start-Sleep -s 10;
        $getr=$null;
    }

    $MATICS = select-string -pattern "xxx.my.leadermes.com" -InputObject $link_string ## LOOK FOR MATICS URL

    if ($MATICS -ne $null)
    {
        $getr = ssh orangepi@"$ip" -X "xrandr -display :0.0;" | Out-String

        $res_pos = $getr.IndexOf(",") ## LOOK FOR COMMA IN VARIABLE
        $getr = $getr.Substring($res_pos+2) ## CONTENTS AFTER COMMA
        $res_pos = $getr.IndexOf(",") ## LOOK FOR COMMA IN VARIABLE
        $getr = $getr.Substring(0, $res_pos) ## CONTENTS BEFORE COMMA
        $res_pos = $getr.IndexOf(" ") ## LOOK FOR SPACE IN VARIABLE
        $getr = $getr.Substring($res_pos+1) ## CONTENTS AFTER SPACE

        echo "MATICS ON DISPLAY";
        ssh orangepi@"$ip" -X "$exitchrome";
        ssh orangepi@"$ip" -X "$chrome";

        if ($getr -eq "1920 x 1080") {
            echo "$getr live";
            Start-Sleep -s 15
            ssh orangepi@"$ip" -X "DISPLAY=:0 xdotool key Return; exit;"
            Start-Sleep -s 20
            ssh orangepi@"$ip" -X "DISPLAY=:0 xdotool key Tab Tab space mousemove 220 60 click 1; exit;"
            Start-Sleep -s 20
            ssh orangepi@"$ip" -X "DISPLAY=:0 xdotool mousemove 1860 180 click 1 mousemove 1920 1080; exit;"
            $getr=$null;
        }
    }
    else
    {
        echo "MATICS IS NOT ON THIS DISPLAY";
        ssh orangepi@"$ip" -X "$exitchrome";
        ssh orangepi@"$ip" -X "$chrome";
    }
}

备注:内容来源于stack exchange,提问作者M.Atkinson

火山引擎 最新活动