博客 (157)

以下是 Spectre.Console 的核心功能示例,涵盖最常用的输出和交互场景:


1. 基础富文本输出

image.png

using Spectre.Console;

// 使用 Markup 语法(类似 BBCode)
AnsiConsole.Markup("[bold green]成功![/] 文件已保存。\n");
AnsiConsole.Markup("[red]错误:[/] 无法连接到服务器。\n");

// 混合样式
AnsiConsole.Markup("[underline blue]https://example.com[/]\n");

// 自动换行写
AnsiConsole.Write(new Panel("[yellow]警告[/] 磁盘空间不足")
    .Header("系统通知")
    .Border(BoxBorder.Rounded));


2. 表格

image.png

var table = new Table();
table.AddColumn("[u]ID[/]");
table.AddColumn(new TableColumn("[u]名称[/]").Centered());
table.AddColumn("[u]状态[/]");

table.AddRow("1", "订单服务", "[green]运行中[/]");
table.AddRow("2", "支付网关", "[red]离线[/]");
table.AddRow("3", "消息队列", "[yellow]警告[/]");

AnsiConsole.Write(table);


3. 进度条 / 状态指示

image.pngimage.png

// 带进度条的循环任务
await AnsiConsole.Progress()
    .StartAsync(async ctx =>
    {
        var task1 = ctx.AddTask("[green]下载文件[/]", maxValue: 100);
        var task2 = ctx.AddTask("[green]处理数据[/]", maxValue: 100);

        while (!ctx.IsFinished)
        {
            task1.Increment(1.5);
            task2.Increment(0.8);
            await Task.Delay(50);
        }
    });

// 不确定时长的旋转状态
await AnsiConsole.Status()
    .StartAsync("正在连接...", async ctx =>
    {
        await Task.Delay(3000); // 模拟工作
        AnsiConsole.MarkupLine("[green]连接成功![/]");
    });


4. 交互式提示

image.png

// 确认
if (AnsiConsole.Confirm("是否继续安装?"))
{
    // 执行安装
}

// 文本输入(带验证)
var name = AnsiConsole.Prompt(
    new TextPrompt<string>("请输入用户名:")
        .ValidationErrorMessage("[red]用户名不能为空[/]")
        .Validate(input => !string.IsNullOrWhiteSpace(input)));

// 选择列表
var fruit = AnsiConsole.Prompt(
    new SelectionPrompt<string>()
        .Title("请选择最喜欢的水果")
        .AddChoices(new[] { "苹果", "香蕉", "橙子", "葡萄" }));

AnsiConsole.MarkupLine($"你选择了:[green]{fruit}[/]");

// 多选
var colors = AnsiConsole.Prompt(
    new MultiSelectionPrompt<string>()
        .Title("请选择颜色")
        .AddChoices(new[] { "红色", "绿色", "蓝色", "黄色" }));


5. 树形结构

image.png

var root = new Tree("[yellow]项目结构[/]");
var src = root.AddNode("src");
src.AddNode("Program.cs");
src.AddNode("Services");
src.AddNode("Models");

var tests = root.AddNode("tests");
tests.AddNode("UnitTests");

AnsiConsole.Write(root);


6. 布局 / 网格

image.png

var layout = new Layout("Root")
    .SplitColumns(
        new Layout("Left").Size(30),
        new Layout("Right")
            .SplitRows(
                new Layout("Top"),
                new Layout("Bottom")));

layout["Left"].Update(new Panel("导航栏"));
layout["Top"].Update(new Panel("主内容区"));
layout["Bottom"].Update(new Panel("日志输出"));

AnsiConsole.Write(layout);


7. 实时更新

image.png

var table = new Table().AddColumn("Time").AddColumn("Message");
table.AddRow("10:00", "系统启动");

await AnsiConsole.Live(table)
    .StartAsync(async ctx =>
    {
        for (int i = 1; i <= 5; i++)
        {
            await Task.Delay(1000);
            table.AddRow($"10:0{i}", $"事件 {i}");
            ctx.Refresh(); // 刷新显示
        }
    });


8. 带样式的异常显示

image.png

try
{
    throw new InvalidOperationException("操作失败");
}
catch (Exception ex)
{
    AnsiConsole.WriteException(ex, ExceptionFormats.ShortenPaths);
}


xoyozo 2 小时前
16

安装虚拟声卡 VB-Cable 搞定。

若重启后未生效,在服务中启动 Windows Audio、Windows Audio Endpoint Builder 和 Multimedia Class Scheduler(如果有),并设置为自动启动。


如何希望使用 OBS 录制系统声音,在 OBS 菜单 - 文件 - 设置 - 音频 - 桌面音频 中选择正确的音源(如“远程音频”)。

xoyozo 23 小时前
19

C盘满了如何清理?特别是 C:\Windows\WinSxS 占用大量磁盘空间,删又不敢删。

推荐一个比较完美又彻底有效的办法:

设置-系统-恢复-使用 Windows 更新修复问题。

或下载与原系统版本一致的 Windows 原版安装镜像,双击运行,选择保留个人文件和应用,等待约半个小时。

完成后,原来安装的应用程序和设置会保留,无用的系统文件会移至 C:\Windows.old。

若新系统运行没有问题,则可删除该目录(设置-系统-存储-清理建议),释放磁盘空间;若有问题,可还原到原系统(设置-系统-恢复)。

xoyozo 2 天前
29

安装技能时

clawhub install xxx

报错:

Rate limit exceeded

原因:

未登录

需要先执行:

clawhub login


xoyozo 1 个月前
362

我来为你整理 Windows 本地部署 OpenClaw 并通过长连接方式接入企业微信的完整步骤:

前置条件

  • 已安装企业微信最新版客户端

  • 已安装 OpenClaw(Node.js 版本需 ≥ 22.0)

  • 管理员权限的企业微信账号(否则看不到 API 模式选项)

第一步:在企业微信创建长连接机器人

  1. 打开企业微信客户端 → 工作台 → 智能机器人 → 创建机器人

  2. 点击底部小字 "如需使用自有系统获取成员与机器人的聊天并输出回复,可切换至 API 模式创建"

  3. 选择 「长连接」 方式(不要选 Webhook 回调模式)

  4. 复制保存生成的 Bot ID 和 Secret(后续需要用到)

  5. 先不要点击保存,保持页面打开,等完成 OpenClaw 配对后再保存 

第二步:Windows 本地安装企微插件

打开 PowerShell 或 命令提示符,依次执行以下命令:

1. 安装企业微信插件

openclaw plugins install @wecom/wecom-openclaw-plugin

如果安装失败,可尝试备用命令: openclaw plugins install @tencent/openclaw-wecom

2. 重启 OpenClaw 网关

openclaw gateway start

重要:这个窗口不能关闭,关闭后机器人会掉线。需要再新开一个终端窗口执行后续命令。

3. 添加企业微信渠道

在新开的终端窗口执行:

openclaw channels add

按提示操作:

  1. 用方向键选择 企业微信(WeCom) → 回车

  2. 粘贴输入 Bot ID → 回车

  3. 粘贴输入 Secret → 回车

  4. 选择 Finished/Done 完成基础配置

  5. 配对方式选择 Pairing

第三步:完成配对授权

1. 回到企业微信,找到刚创建的机器人,发送任意消息(如"你好")

2. 机器人会自动回复一条配对码消息(包含授权命令)

3. 复制消息最后一行的配对码

4. 在终端中执行配对命令:

openclaw pairing approve openclaw-wecom 你的配对码

5. 提示"授权成功"即完成配对

第四步:保存并启用机器人

1. 回到企业微信机器人配置页面,点击 保存并创建

2. 现在可以在企业微信中与机器人正常对话了

长连接 vs 回调模式的优势

特性长连接模式传统回调模式
公网IP/域名❌不需要✅必须需要
内网穿透❌不需要✅必须配置
消息加解密❌无需处理✅需要处理
稳定性高(无回调失败问题)低(经常回调失败)
主动推送
✅支持✅支持

常见问题

问题解决方案
没有 API 模式选项确认你是企业微信管理员,普通成员看不到该选项
插件安装失败检查网络连接,或尝试切换 npm 镜像源: npm config set registry https://registry.npmmirror.com/
配对码无法获取确认选择了 API 模式和长连接,重启 OpenClaw 后重试
机器人不回复检查网关窗口是否保持运行,重新执行配对命令
需要 7×24 小时在线建议部署到云服务器,本地关机后机器人会离线

命令速查表

# 安装插件
openclaw plugins install @wecom/wecom-openclaw-plugin

# 启动网关(窗口不能关)
openclaw gateway start

# 添加渠道
openclaw channels add

# 配对授权
openclaw pairing approve openclaw-wecom 【配对码】

# 重启服务
openclaw gateway restart

# 查看状态
openclaw channels status

配置完成后,你就可以在企业微信中与 OpenClaw 对话了。如果需要让个人微信也能使用,可以在企业微信后台 "我的企业" → "微信插件" 中生成二维码,用个人微信扫码关注企业即可。

xoyozo 1 个月前
2,250

一般地,应选择尺寸小于显存的大模型版本,且适当冗余。

譬如,显存 8GB,选择尺寸为 5.2GB 的 deepseek-r1:8b。

这样,整个大模型都能被完整地读取到显存中。

若选择 9.0GB 的 deepseek-r1:14b 则显存不足,Ollama 会自动调用系统内存和 CPU 来协同工作,导致推理速度显著下降。

显卡的算力影响生成的速度,模型的参数决定生成的质量。

另外经实测,在 /api/generate 接口的 format 参数中设置返回的 JSON 格式,会缩短生成时间,降低生成质量,可能的原因是强制格式限制了词汇选择空间。

xoyozo 5 个月前
937

早前记录过在 CentOS 中部署 ASP.NET Core 网站,现在宝塔面板已经直接支持创建 .NET 网站了,再次记录一下。


本文环境:VS2022、.NET 9、宝塔面板v11。


一、在 VS 中创建一个 .NET 9 网站,项目名称例:WebApplication1

发布选项:

image.png

关于“生成单个文件”选项,若勾选,发布后的项目启动文件不带后缀名(.dll),尝试在宝塔面板 v11.0.0 中无法顺利启动。


二、在 Linux 服务器上创建目录:/www/wwwroot/WebApplication1/

将发布后的文件上传到这个目录上,最终的文件结构如下:

image.png


三、进入宝塔面板,在 网站-Net项目 中安装 .Net环境管理,这里以 9.0.201 为例:

image.png


四、添加项目

项目名称:随意

运行路径:项目所在目录,本例中为:

/www/wwwroot/WebApplication1

启动命令:使用 dotnet 命令,dotnet 命令可以不使用全路径(/www/server/dotnet/9.0.201/dotnet),第一个参数是项目启动文件,--urls 是反向代理的服务器和端口。服务器名可以是*也可以是localhost。例:

dotnet WebApplication1.dll --urls=http://*:5000

项目端口:与启动命令中的端口号一致

开机启动:一般会勾选

启动用户:尽量用 www,最小权限原则。

image.png

正常情况下,网站已启动,如果未启动,检查配置,根据报错内容排查问题。


五、配置网站

添加域名、SSL 证书等。


友情提示:

  • 网站版本更新重新发布后,需要手动重启网站才能生效,习惯于发布到 IIS(会自动生效)的同学要特别注意。

  • 新手尽量以空项目或默认项目来部署,避免因特殊原因导致一系列其它问题。

  • nginx 反向代理并不会转发所有 Header,需要手动配置。

xoyozo 7 个月前
7,337

Windows Server 安装 Synology Drive Client 说版本不兼容,怎么办?

选择 32 位的安装包就能安装成功。

xoyozo 8 个月前
5,889

AutoUpdater.NET 是一个开源库,专为 .NET 桌面应用程序设计,支持 Windows Forms 和 WPF 应用。它通过从服务器获取 XML 文件来检测新版本信息,当发现新版本时向用户显示更新对话框。

相对于 ClickOnce,AutoUpdater.NET 的配置更简单一些。

首先通过 NuGet 包管理器安装 Autoupdater.NET.Official,然后在应用程序入口点添加以下代码:

AutoUpdater.Start("http://yourserver.com/path/to/update.xml");

XML 文件结构如下:

<?xml version="1.0" encoding="UTF-8"?>
<item>
  <version>2.0.0.0</version> <!--必填:最新版本号-->
  <url>http://yourserver.com/path/to/updatefile.zip</url> <!--必填:更新文件下载地址-->
  <changelog>http://yourserver.com/path/to/changelog.txt</changelog> <!--可选:更新日志-->
  <mandatory>False</mandatory> <!--可选:是否强制更新-->
</item>

Windows Forms 在 Program.cs 文件的 Main() 方法中,WPF 在 App.xaml.cs 的 OnStartup() 中添加:

AutoUpdater.Start("http://yourserver.com/path/to/update.xml");
AutoUpdater.CheckForUpdateEvent += (e) =>
{
    if (e.Error != null)
    {
        MessageBox.Show($"检查版本更新失败:{e.Error.Message}");
    }
    if (e.IsUpdateAvailable)
    {
        if (e.Mandatory.Value)
        {
            // 强制更新
            AutoUpdater.DownloadUpdate(e);
        }
        else
        {
            // 可选更新
            if (MessageBox.Show("发现新版本,是否立即更新?", "更新提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes)
            {
                AutoUpdater.DownloadUpdate(e);
            }
        }
    }
};

这样就能简单实现打开应用时判断是否有更新。具体用法参:GitHub

对于控制台应用程序,AutoUpdater.NET 并不直接支持。可以使用 GeneralUpdate 等轻量级自动更新库。

其它:

  • 若希望通过标准安装流程(如添加到开始菜单),优先选择 ClickOnce,适合长期维护的内部工具。

  • 若追求快速集成和无感更新,AutoUpdater.NET 更灵活。

  • 无论哪种方案,务必对程序进行代码签名(如购买企业证书或生成测试证书),否则系统可能拦截安装。(你要允许来自未知发布者的此应用对你的设备进行更改吗)

  • 可以购买“OV 代码签名”证书或“EV 代码签名”证书,注意:“代码签名证书”与“域名证书”互不通用。

xoyozo 8 个月前
7,271

QQ20250716-111451.png

保存工作再继续。Visual Studio Standard Collector Service 150 (VSStandardCollectorService150)

尝试关闭正在运行的程序,发现是“腾讯元宝”启动了这个进程。

xoyozo 9 个月前
2,308