<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/feed.xsl"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title><![CDATA[秋雪的小窝]]></title>
    <link>https://akiyuki.cn</link>
    <atom:link href="https://akiyuki.cn/feed.xml" rel="self" type="application/rss+xml"/>
    <description><![CDATA[秋天会下雪吗？]]></description>
    <language>zh-CN</language>
    <lastBuildDate>Fri, 16 Oct 2026 17:08:27 GMT</lastBuildDate>
    <item>
      <title><![CDATA[图片压裁器：pywebview + Pillow 写一个顺手的 Windows 小工具]]></title>
      <link>https://akiyuki.cn/post/image-cropper</link>
      <guid isPermaLink="true">https://akiyuki.cn/post/image-cropper</guid>
      <pubDate>Wed, 14 Oct 2026 09:30:47 GMT</pubDate>
      <category>项目</category>
      <category>Python</category>
      <category>pywebview</category>
      <category>Windows</category>
      <description><![CDATA[<p>有些工具的需求特别朴素：<strong>把一张图裁一下、压一下、转个格式。</strong></p>
<p>Windows 上做这件事的路子通常有三条——打开笨重的图像软件、用在线转换网站（图片得上传到别人服务器）、或者装一堆用不上的东西。我想要的是一条都不用走的方案：一个双击就开的本地小窗口，用完关掉，图片不离开这台电脑。</p>
<p><strong>图片压裁器（Image Cropper）</strong> 就是这么个东西。</p>
<h2 id="它做什么">它做什么</h2>
<ul>
<li>✂️ <strong>裁剪</strong>：自由比例，或者 1:1 / 4:3 / 16:9 / 3:2 / 2:3 等常见比例，可锁定比例</li>
<li>🔍 <strong>缩放</strong>：滑块或直接输入宽高，可锁定宽高比</li>
<li>🗜️ <strong>格式转换与压缩</strong>：JPEG / PNG / WebP，质量可调</li>
<li>📊 <strong>实时输出大小估算</strong>：改参数时立刻告诉你压完多大，并和原文件对比</li>
<li>🖼️ <strong>本地预览</strong>：拖拽、粘贴、点击三种方式选图</li>
<li>🌍 <strong>中 / 英 / 日三语界面</strong>，Fluent 2 风格，浅色 / 深色主题</li>
</ul>
<p>核心是<strong>实时反馈</strong>：拖动质量滑块的时候，输出体积的估算会跟着变，你不用反复导出再去看文件大小。这个循环一快，调参数就从「试错」变成了「手感」。</p>
<h2 id="技术选型">技术选型</h2>
<table>
<thead>
<tr>
<th>层</th>
<th>技术</th>
</tr>
</thead>
<tbody>
<tr>
<td>前端</td>
<td>原生 HTML / CSS / JavaScript（Fluent 2 设计语言）</td>
</tr>
<tr>
<td>后端</td>
<td>Python 3.10+，pywebview 6.2（WebView2）</td>
</tr>
<tr>
<td>图像处理</td>
<td>Pillow 12</td>
</tr>
<tr>
<td>打包</td>
<td>PyInstaller 6.21（onefile + UPX）</td>
</tr>
</tbody>
</table>
<p>用 pywebview 的好处是：<strong>界面能用 Web 技术写，但跑起来是原生窗口</strong>，用系统自带的 WebView2（Edge Chromium）渲染，不需要打包一个浏览器内核，也不需要起本地服务器。整个程序单机离线运行。</p>
<h2 id="关于那个-177-mb">关于那个 17.7 MB</h2>
<p>打包体积是这类小工具最容易失控的地方，所以 <code>build.spec</code> 上花了点功夫：</p>
<ul>
<li>用 <strong>UPX</strong> 压缩 <code>.pyd</code> 原生扩展——但<strong>排除 <code>*.dll</code></strong>，避免损坏 .NET 托管程序集；</li>
<li>排除 tkinter / setuptools / pip 等运行时用不到的模块。</li>
</ul>
<p>最终单文件 exe 约 <strong>17.7 MB</strong>，可以改成中文名（比如 <code>图片压裁器.exe</code>）直接用，是绿色版。</p>
<pre><code class="language-bash">pip install -r requirements-dev.txt
pyinstaller build.spec --clean --noconfirm
</code></pre>
<p>产物在 <code>dist\PicCropper.exe</code>。</p>
<h2 id="下载">下载</h2>
<p>最新版 <strong>v1.1.0</strong>：</p>
<h3 id="打开图片压裁器发布页下载"><strong><a href="https://github.com/Akiyuki1130/image-cropper/releases">→ 打开图片压裁器发布页下载</a></strong></h3>
<table>
<thead>
<tr>
<th>文件</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>PicCropper.exe</code></td>
<td>单文件绿色版，约 17.7 MB，双击即运行，<strong>无需安装 Python</strong></td>
</tr>
</tbody>
</table>
<p>运行环境要求：</p>
<ul>
<li>Windows 10 / 11</li>
<li>Microsoft Edge WebView2 Runtime（Windows 11 自带；Windows 10 可从<a href="https://developer.microsoft.com/en-us/microsoft-edge/webview2/">官方安装页</a>获取）</li>
<li>.NET Framework 4.8</li>
</ul>
<h2 id="从源码运行">从源码运行</h2>
<pre><code class="language-bash"><span class="hljs-comment"># 1. 安装依赖</span>
pip install -r requirements.txt

<span class="hljs-comment"># 2. 运行（Windows 也可直接双击 run.bat）</span>
py -3 main.py
</code></pre>
<p>目录结构很扁平：</p>
<pre><code class="language-text">image-cropper/
├── main.py               # 入口（pywebview 窗口与 JS 桥接）
├── image_processor.py    # 图像处理逻辑（Pillow）
├── build.spec            # PyInstaller 打包配置
├── run.bat               # 源码运行脚本（自动选择 Python）
├── requirements.txt      # 运行时依赖
├── requirements-dev.txt  # 打包依赖
├── ui/                   # 前端资源
│   ├── index.html        # 主页面
│   ├── styles.css        # 样式（浅色/深色主题）
│   ├── app.js            # 交互逻辑
│   └── i18n.js           # 多语言（zh / en / ja）
└── icon.ico              # 应用图标
</code></pre>
<p>改界面只动 <code>ui/</code> 下的东西就行，不用碰 Python 那侧。</p>
<h2 id="关于-ai-辅助">关于 AI 辅助</h2>
<p>这个项目的大部分代码是 AI 编程助手（Claude Code / opencode 等）辅助编写和审查的，包括前后端代码生成与重构、Bug 定位（图层 alpha 合成、裁剪竞态、pywebview 版本兼容）、PyInstaller 打包体积优化与 UPX 配置调优、多语言界面与无障碍改进。</p>
<p>需求梳理、验收测试和关键决策由人工完成。</p>
<h2 id="协议">协议</h2>
<p><a href="https://github.com/Akiyuki1130/image-cropper/blob/main/LICENSE">MIT</a>，欢迎使用与改进。</p>
<hr />
<p><strong><a href="https://github.com/Akiyuki1130/image-cropper">Akiyuki1130/image-cropper</a></strong></p>
]]></description>
    </item>
    <item>
      <title><![CDATA[Agent Provider Manager：把散落的模型配置收进一个窗口]]></title>
      <link>https://akiyuki.cn/post/agent-provider-manager</link>
      <guid isPermaLink="true">https://akiyuki.cn/post/agent-provider-manager</guid>
      <pubDate>Wed, 14 Oct 2026 09:30:47 GMT</pubDate>
      <category>项目</category>
      <category>Go</category>
      <category>Wails</category>
      <category>AI 工具</category>
      <category>Windows</category>
      <description><![CDATA[<p>同时用几个 coding agent 的人大概都遇到过同一个麻烦：<strong>模型配置是散的。</strong></p>
<p>ZCode 有一套 provider 配置，DeepSeek Harness 有另一套，格式不同、位置不同、字段名也不一样。想在两个工具之间共用一个供应商，就得手动改 JSON / YAML，还要担心把注释和缩进搞乱、把 API Key 写进一个不该提交的文件。</p>
<p><strong>Agent Provider Manager</strong>（简称 APM）就是来解决这件事的：一个 Windows 桌面窗口，直接管理这些 agent 的 provider、模型、API Key、备份和迁移。</p>
<h2 id="它是什么不是什么">它是什么，不是什么</h2>
<p>先说清楚边界，免得误会：</p>
<blockquote>
<p>APM <strong>不是</strong>代理服务器，<strong>不是</strong>模型网关，也<strong>不</strong>做云端密钥托管。</p>
</blockquote>
<p>它做的事很朴素——<strong>直接读写你指定的配置文件</strong>，然后在上面套一层图形界面：provider 列表、模型卡片、批量编辑、模型自动匹配、导入、迁移、备份恢复、API Key 钥匙串。</p>
<p>它不做的事情也很明确：不存在模型代理，没有计费，没有遥测，不会把你的配置或凭据上传到任何地方。</p>
<h2 id="支持的-agent">支持的 Agent</h2>
<table>
<thead>
<tr>
<th>Agent</th>
<th>默认配置位置</th>
<th>支持的操作</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>ZCode</strong></td>
<td><code>%USERPROFILE%\.zcode\v2\provider_config.json</code>（新版，优先）/ <code>config.json</code>（旧版）</td>
<td>读取、编辑、保存、还原点、provider/model 管理、旧版供应商一次性导入、ZCode 3.14 兼容性检查与一键修复、跨 Agent 迁移</td>
</tr>
<tr>
<td><strong>DeepSeek Harness 0.2</strong></td>
<td><code>profiles\desktop\cordis.patch.yml</code>（桌面端，优先）/ <code>profiles\web\cordis.patch.yml</code>（<code>dsh web</code>、CLI）/ <code>cordis.patch.yml</code>（home 级，优先级最高）</td>
<td>读取、编辑、保存、还原点、provider/model 管理、跨 Agent 迁移</td>
</tr>
<tr>
<td><strong>DeepSeek Harness 0.1</strong></td>
<td><code>settings.yaml</code>（<code>.yml</code> / <code>.json</code>）</td>
<td>同上，作为旧格式保留</td>
</tr>
</tbody>
</table>
<blockquote>
<p><strong>OpenCode</strong> 的入口已在应用内隐藏（暂不适配）。相关代码与历史还原点数据保留，但顶部栏、迁移页和编辑器里都不会再出现它。</p>
</blockquote>
<p>这里有个值得单独说的点：DSH 0.2 把用户配置从单个 <code>settings.yaml</code> 改成了 <strong>profile patch 层</strong>。provider 写在 patch 里 <code>id: llm-pi-ai</code> 条目的 <code>config.providers</code> 上，而 API Key 只写<strong>引用</strong>（<code>apiKeyEnv</code>），密钥本体落到 <code>~/.dsh/.credentials.yaml</code> 的 <code>version: 1</code> + <code>refs</code> 布局里。</p>
<p>APM 完整跟上了这套机制：写 <code>llm-pi-ai</code> 时只重写<strong>真正变化的节点</strong>，未被改动的 provider 子树连同其中的注释和 <code>!!js</code> 表达式原样保留。如果 <code>llm-pi-ai</code> 被 home 级 patch（<code>~/.dsh/cordis.patch.yml</code>）覆盖了，程序会<strong>拒绝写入并告诉你原因</strong>，而不是写一份看起来生效、实际被覆盖的配置。</p>
<h2 id="能做什么">能做什么</h2>
<p><strong>provider 管理</strong>：创建、编辑、删除、重命名；改名称、ID、类型、Base URL、API Key 和 options JSON。支持 <code>openai-compatible</code>、<code>anthropic</code>、<code>responses</code> 三种类型。</p>
<p><strong>模型卡片</strong>：添加、删除、搜索和批量编辑模型；能改 reasoning、variants、context window、output token、modalities、headers 和额外 options。常用模型的上下文长度和输出长度可以<strong>自动匹配</strong>，在导入页或管理页批量执行。</p>
<p><strong>从服务商拉模型</strong>：填 Base URL 和 API Key，点「获取模型列表」，程序会规范化 Base URL 后访问 <code>/v1/models</code>，并限制响应大小、模型数量和重定向次数。</p>
<p><strong>API Key 钥匙串</strong>：在 Windows 上用 <strong>DPAPI</strong> 加密保存。旧版本那种可逆 Base64 数据只用于一次性迁移读取，新的保存不会再静默降级成 Base64。</p>
<p><strong>跨 Agent 迁移</strong>：ZCode（新版 / 旧版）与 DeepSeek Harness（0.2 patch / 0.1 settings）之间可以互为源和目标，选择「追加 / 合并」或「覆盖」。</p>
<h2 id="我最看重的一块还原点">我最看重的一块：还原点</h2>
<p>配置文件是那种改坏了很麻烦的东西，所以 APM 在这上面做得比较重。</p>
<p><strong>每次修改前</strong>，它自动保存改动前文件的原文——<strong>逐字节保留注释和键序</strong>——并记录 Agent、绝对路径、格式、文件当时是否存在、大小、SHA-256、操作类型等元数据。</p>
<p>「还原点」页可以任选一个时间点回滚。而且<strong>回滚本身也能再回滚</strong>：回滚前会先给当前状态再建一个还原点。</p>
<p>容量上，单个目标保留最近 50 个还原点、合计不超过 64 MB，超出按最旧优先清理。</p>
<p>除此之外还有同级 <code>.bak_&lt;时间戳&gt;</code> 备份、SHA-256 指纹检查和「恢复最近备份」，默认每个文件最多保留 2 份同级备份。</p>
<h2 id="安全边界">安全边界</h2>
<p>这部分 README 里写得很细，我挑几条：</p>
<ol>
<li><strong>只允许 <code>http</code> / <code>https</code></strong>，且<strong>默认仅允许 HTTPS</strong>。要访问外部 HTTP 地址，得显式打开「允许 HTTP」——那会明文传输 API Key 和请求内容。</li>
<li>发请求前<strong>以及每一次重定向</strong>都会校验 host，默认拒绝 localhost、环回、私有、链路本地、未指定和其他保留地址；要访问本机模型服务得显式打开开关。这是<strong>防 SSRF</strong>，不等同于完整网络隔离。</li>
<li>还原点只写在本机 <code>%LOCALAPPDATA%\AgentProviderManager\restorepoints</code>，文件权限 <code>0600</code>，不上传、不写日志——但<strong>仍是明文副本</strong>，别把这些文件提交到 Git 或发给别人。</li>
<li>写入采用临时文件 + 重命名 + SHA-256 指纹 + 同级备份轮转 + 还原点，但<strong>不是数据库事务</strong>，不能替代你自己的离线备份。</li>
</ol>
<h2 id="下载">下载</h2>
<p>最新正式版是 <strong>2.0.7</strong>（<code>v2.0.8</code> 目前是 pre-release，想尝鲜可以选它）：</p>
<h3 id="打开-agent-provider-manager-发布页下载"><strong><a href="https://github.com/Akiyuki1130/AgentProviderManager/releases">→ 打开 Agent Provider Manager 发布页下载</a></strong></h3>
<table>
<thead>
<tr>
<th>文件</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>AgentProviderManager-2.0.7-windows-amd64.exe</code></td>
<td>单文件可执行，约 13 MB</td>
</tr>
<tr>
<td><code>AgentProviderManager-2.0.7-windows-amd64.zip</code></td>
<td>压缩包版，约 5 MB</td>
</tr>
<tr>
<td><code>SHA256SUMS.txt</code></td>
<td>校验文件</td>
</tr>
</tbody>
</table>
<p>解压 / 放到有执行权限的目录，确认系统装了 <strong>Microsoft Edge WebView2 Runtime</strong>（Wails 窗口依赖它），然后启动 <code>AgentProviderManager.exe</code>。</p>
<p>程序不会自动上传配置，也不会自动修改你没选中的 agent 文件。<strong>第一次保存前</strong>，建议先确认顶部栏里的 Agent、目标配置路径和备份状态都对。</p>
<p>「选项」页可以手动检查更新，也能打开自动更新（<strong>默认关闭</strong>）。开启后只从固定的 <code>Akiyuki1130/AgentProviderManager</code> 正式 Release 检查下载；下载完不会突然退出，而是弹确认框，点了「更新并重启」之后更新助手才等旧进程退出、校验 SHA-256、替换 EXE 并用原文件名启动。失败了会尝试回滚。</p>
<h2 id="已知限制">已知限制</h2>
<ul>
<li><strong>仅 Windows</strong>，依赖 WebView2；目前没有 Linux / macOS 发布包。</li>
<li>保存会<strong>重新序列化</strong>配置文件，注释和原始格式可能变化（ZCode 新版会按严格 schema 重编码；DSH 的 <code>llm-pi-ai</code> 条目里的注释也可能变）。</li>
<li>ZCode 遇到未知键会把整份配置当空，所以程序<strong>宁可报错也不写出这样的文件</strong>——这个检查在唯一的写盘入口，任何写入路径都绕不过去。</li>
<li>大量模型会产生较多 DOM，2000 个模型接近上限时低配机器可能不够流畅。</li>
<li>没有内置前端 E2E 测试，发布前需要在真实 Wails 窗口里验证剪贴板、WebView2、DPAPI 和配置备份恢复。</li>
</ul>
<h2 id="技术栈">技术栈</h2>
<p>Go + Wails + Vue 3，前端用 Pinia 管状态，UI 走 Fluent 风格设计语言。源码以 <strong>MIT</strong> 协议发布。</p>
<pre><code class="language-powershell"><span class="hljs-built_in">cd</span> frontend
npm ci
npm run build
<span class="hljs-built_in">cd</span> ..
go test ./...
go vet ./...
wails build
</code></pre>
<p>需要 Go 1.25+、Node.js 18+ 和固定版本的 Wails CLI。</p>
<hr />
<p><strong><a href="https://github.com/Akiyuki1130/AgentProviderManager">Akiyuki1130/AgentProviderManager</a></strong></p>
<blockquote>
<p>旧的 <code>ZCodeProviderManager</code> 是 v1.x 的 Python 版历史存档，已不再更新，全部开发都在 AgentProviderManager 继续。</p>
</blockquote>
]]></description>
    </item>
    <item>
      <title><![CDATA[YukiDesk：给 Windows 桌面加一条属于自己的顶栏]]></title>
      <link>https://akiyuki.cn/post/yukidesk-desktop-bar</link>
      <guid isPermaLink="true">https://akiyuki.cn/post/yukidesk-desktop-bar</guid>
      <pubDate>Wed, 14 Oct 2026 09:30:31 GMT</pubDate>
      <category>项目</category>
      <category>YukiDesk</category>
      <category>C#</category>
      <category>WPF</category>
      <category>Windows</category>
      <description><![CDATA[<p>Windows 桌面上的小工具很多，但很少有东西是「钉在桌面上、又永远不挡事」的。</p>
<p>要么是悬浮窗，一直飘在所有窗口上面；要么藏在托盘里，用一次要点两下。我想要的是一条<strong>长在桌面上的</strong>顶栏——它存在感很低，但伸手就能用。</p>
<p>这就是 <strong>YukiDesk</strong>。</p>
<h2 id="一条桌面层的顶栏">一条「桌面层」的顶栏</h2>
<p>YukiDesk 最核心的设计决定，是它住在<strong>桌面层</strong>，而不是普通窗口层。</p>
<p>具体说，它是一条 <strong>46px 高</strong>的透明分层窗口，通过 <code>SetWindowPos</code> 钉在桌面装饰层（壁纸引擎、桌面整理软件画的图标和挂件）正上方、<strong>所有普通软件窗口之下</strong>，并且每 3 秒兜底重钉一次——万一被别的软件误加了置顶标志，会被防御性地撤掉。</p>
<p>听起来只是个细节，但它直接决定了使用手感：</p>
<ul>
<li>你打开任何窗口，顶栏都会被<strong>自然盖住</strong>，永远不会挡着你干活；</li>
<li>你回到桌面，它就在那儿，不用切窗口、不用翻托盘；</li>
<li>开机自启，秒出。</li>
</ul>
<p>所以它的语义不是「悬浮小工具」，而是<strong>桌面的一部分</strong>。</p>
<p><img src="https://akiyuki.cn/uploads/202610/mv7wqcnr-240a022229.png" alt="YukiDesk 顶栏" /></p>
<blockquote>
<p>顶栏本体就是上面这一条。左侧是设置、电源、回收站、小文件夹，右侧是时间、性能监测、音频频谱、音乐播放器和音量。</p>
</blockquote>
<h2 id="上面都装了什么">上面都装了什么</h2>
<h3 id="小文件夹">小文件夹</h3>
<p>悬停选项卡向下展开一个文件面板（最高半屏，滚轮翻页，东西少时自动缩小），48px 图标，<strong>单击直接打开</strong>。</p>
<p>把文件拖到选项卡或面板上，默认是<strong>移动</strong>语义——来源只允许复制时会拒绝拖放，不会偷偷复制一份、让你回头找不到原件。同名项目可以替换，也可以自动编号保留为副本。</p>
<p><img src="https://akiyuki.cn/uploads/202610/mv7wqcna-40d125f747.png" alt="小文件夹展开" /></p>
<h3 id="回收站">回收站</h3>
<p>圆形垃圾桶按钮，<strong>单击展开</strong>（悬停不展开，避免误触），列出当前用户回收站的内容，包含可移动盘。</p>
<p>双击项目还原回原位置——用的是 <code>$I</code> 元数据里记录的原始路径，原位置被占了会自动加 <code>(1)</code> 后缀。右键单个项目可以还原 / 复制 / 永久删除；右键按钮可以「清空回收站」，带确认弹窗。</p>
<h3 id="时间">时间</h3>
<p>悬停展开星期、日期和农历。</p>
<p><img src="https://akiyuki.cn/uploads/202610/mv7wqcn5-49c4427b26.png" alt="时间展开" /></p>
<p>折叠态显示哪几项（秒数 / 日期 / 星期）和靠右还是居中，都能在设置里调。</p>
<h3 id="音乐播放器">音乐播放器</h3>
<p>播放音乐时自动出现。数据来自 Windows 的 <strong>SMTC</strong> 全局媒体会话，所以 QQ 音乐、网易云、Spotify 乃至浏览器里播放的音乐都能识别。悬停展开大封面、歌名、歌手和播放控制。</p>
<p>面板<strong>不显示时间轴和进度条</strong>——在 46px 的条上，你要的是「一眼看见在放什么」，而不是又一个播放器。</p>
<p><img src="https://akiyuki.cn/uploads/202610/mv7wqcne-ce4709d06d.png" alt="音乐播放器" /></p>
<h3 id="音频频谱">音频频谱</h3>
<p>播放器左边那条胶囊频谱，16 根对数频段柱跟着节拍跳。</p>
<p>实现是 WASAPI 共享模式环回采集系统播放流（专用后台线程）→ 2048 点 FFT 加汉宁窗 → 按 40Hz~15kHz 对数划分成 16 个频段 → <code>CompositionTarget.Rendering</code> 驱动自绘，UI 线程零阻塞。自动增益做得比较足，音量很小的时候柱子也看得出起伏。</p>
<p>它<strong>只读</strong>系统音频，不写音量、不影响播放。用不上可以在设置里关掉。</p>
<h3 id="性能监测">性能监测</h3>
<p>频谱左边四枚胶囊：CPU 占用、GPU 占用（多显卡可指定监测哪块）、内存占用、网络上下行。鼠标放上去自动展开详情——CPU / GPU 给占用、温度、频率，内存给占用 / 已用 / 容量 / 频率，网络给上下行速率。</p>
<p><img src="https://akiyuki.cn/uploads/202610/mv7wqcni-86e67defd7.png" alt="性能监测展开" /></p>
<p>温度这块做得比较克制。数据源：GPU 温度/频率在 AMD 上走显卡驱动 ADL，NVIDIA 走 NVML；CPU 温度默认按 <strong>原生 Tctl → APU 真 CPU 温度 → ACPI 热区 → CPU 侧 SoC 传感器</strong> 依次降级，读不到就往下退，不显示没有依据的数字。</p>
<p>AMD 平台想要原生 Tctl 核心温度（与 AIDA64 / HWiNFO 同源），可以在设置里一键安装开源的 <a href="https://github.com/namazso/PawnIO">PawnIO</a> 驱动运行时：一次管理员授权，创建一个登录时运行的提权温度任务，可随时停用，卸载 YukiDesk 时自动清理。</p>
<p>每项都能单独开关，<strong>全部隐藏时不采样</strong>。</p>
<h3 id="音量">音量</h3>
<p>右侧圆形喇叭按钮，展开后只调 Windows 当前默认输出设备。这里没有做设备切换下拉框——那个操作在 Windows 自带的音量面板里更顺手。</p>
<h2 id="外观几乎都能改">外观几乎都能改</h2>
<p>设置窗口分外观、时间、小文件夹、模块显示、通用、关于几页，<strong>改完实时生效</strong>：</p>
<p><img src="https://akiyuki.cn/uploads/202610/mv7wqcnn-7f837425aa.png" alt="设置窗口" /></p>
<ul>
<li><strong>外观</strong>：统一选项卡与展开页的色盘、文字与图标颜色、透明度、缩放、边框开关与颜色，还有壁纸明暗自动适配（一旦手动指定颜色，自动适配会自动关闭）。设置窗口本身也能单独跟随 Windows 深浅色，最小化 / 最大化 / 关闭按钮可自定义。</li>
<li><strong>小文件夹</strong>：存储路径（默认 <code>%LocalAppData%\YukiDesk\MiniFolders</code>，可改）、新建 / 重命名 / 移除。</li>
<li><strong>通用</strong>：开机自启、悬停关闭延迟、动画时长、桌面顶部空间预留，以及模块显示开关。开启「预留」后会通过 Shell AppBar 向资源管理器注册顶栏占用的区域，最大化窗口就不会压到顶栏上。</li>
<li><strong>关于</strong>：版本、项目主页、更新设置。</li>
</ul>
<p>托盘图标右键可以打开设置、显示 / 隐藏顶栏、打开数据目录或退出；顶栏被隐藏时也能从托盘重新叫回来。</p>
<h2 id="下载">下载</h2>
<p>安装包在 <strong>GitHub Releases</strong> 发布，最新版 <strong>v1.0.8</strong>：</p>
<h3 id="打开-yukidesk-发布页下载"><strong><a href="https://github.com/Akiyuki1130/YukiDesk/releases">→ 打开 YukiDesk 发布页下载</a></strong></h3>
<p>每次发布有 4 个包 —— x64 / ARM64 两种架构 × full / slim 两种运行时类型：</p>
<table>
<thead>
<tr>
<th>包</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>YukiDesk-Setup-x64-full-1.0.8.0.exe</code></td>
<td><strong>自包含</strong>，.NET 8 桌面运行时一并打包，无需预装任何东西。体积大，<strong>推荐大多数人</strong></td>
</tr>
<tr>
<td><code>YukiDesk-Setup-x64-slim-1.0.8.0.exe</code></td>
<td><strong>框架依赖</strong>，不含运行时，体积小；需系统已装 <a href="https://dotnet.microsoft.com/download/dotnet/8.0">.NET 8 Desktop Runtime</a>，没装安装器会提示</td>
</tr>
<tr>
<td><code>YukiDesk-Setup-arm64-full-1.0.8.0.exe</code></td>
<td>同上，Windows on ARM 设备用</td>
</tr>
<tr>
<td><code>YukiDesk-Setup-arm64-slim-1.0.8.0.exe</code></td>
<td>同上</td>
</tr>
</tbody>
</table>
<p>普通 Intel / AMD 电脑选 <code>x64</code>，Windows on ARM 选 <code>arm64</code>；不确定就选文件名带 <code>full</code> 的完整版。发布页同时提供 <code>SHA256SUMS</code> 校验文件。</p>
<p>安装是<strong>每用户模式，不需要管理员权限</strong>。卸载时会一并清理登录温度任务、开机自启注册表值和 <code>%TEMP%</code> 里的更新残留；配置和日志留在 <code>%AppData%\YukiDesk</code>，可手动删除。</p>
<p>程序内也内置了更新检查（设置 → 关于）：可自动检查、自动下载，或手动检查；系统开了代理会自动走系统代理。发现新版本后<strong>先下载再询问</strong>，确认了才装。</p>
<h2 id="已知边界">已知边界</h2>
<p>几个容易踩到的地方：</p>
<ul>
<li>顶栏<strong>只覆盖主屏</strong>，多屏暂不支持。</li>
<li>音量模块始终跟随当前默认播放设备，不提供设备切换。</li>
<li>回收站只显示<strong>当前用户</strong>的回收站（其他用户的目录需要管理员权限）。</li>
<li>音乐选项卡依赖播放器上报 SMTC，个别播放器关掉这个功能就检测不到。</li>
</ul>
<h2 id="技术栈">技术栈</h2>
<p>C# / .NET 8 / WPF，目标框架 <code>net8.0-windows10.0.19041.0</code>，引用 Windows SDK 的 WinRT 投影。全部用原生 Windows API + 托管代码实现，<strong>没有任何第三方 UI 框架依赖</strong>，支持 x64 与 ARM64。</p>
<p>唯一的可选内核组件就是上面提到的 PawnIO，需要你主动启用。</p>
<pre><code class="language-bash"><span class="hljs-built_in">cd</span> DesktopBar
dotnet build -c Release
</code></pre>
<p>要求 Windows 10 1809+ / Windows 11，以及 .NET 8 SDK。</p>
<p>配置存在 <code>%AppData%\YukiDesk\settings.json</code>，日志在 <code>%AppData%\YukiDesk\log.txt</code>。</p>
<hr />
<p>项目使用 AI 辅助完成，需求梳理、验收测试与关键决策由我负责。源码在这里：</p>
<p><strong><a href="https://github.com/Akiyuki1130/YukiDesk">Akiyuki1130/YukiDesk</a></strong></p>
]]></description>
    </item>
  </channel>
</rss>