阅读视图

发现新文章,点击刷新页面。
🔲 ☆

Windows 11 26H1 显示所有托盘图标

<p>早期版本 Windows 11 还能通过运行 <code>shell:::{05d7b0f4-2121-4eff-bf6b-ed3f69b894d9}</code> 的方式来显示所有托盘图标,最新版本已经不行了。有什么新办法呢?</p><span id="more"></span><h2 id="方法一:Start-All-Back"><a href="#方法一:Start-All-Back" class="headerlink" title="方法一:Start All Back"></a>方法一:Start All Back</h2><p>这是一个收费软件,你可以在软件设置中找到「托盘图标」-「始终显示所有应用图标」</p><p><img src="/gallery/2025/win-11-show-all-tray-icon/1774926886009.webp"></p><p><strong>优点</strong>:一劳永逸</p><p><strong>缺点</strong>:需要安装软件并一直运行</p><h2 id="方法二:bat-脚本"><a href="#方法二:bat-脚本" class="headerlink" title="方法二:bat 脚本"></a>方法二:bat 脚本</h2><p>粘贴到记事本,保存为 <code>Win11托盘显示所有图标.bat</code>,右键以管理员身份运行:</p><figure class="highlight bat"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">:: NotifyIconSettings [SHOW ALL]</span><br><span class="line"><span class="keyword">for</span> /f &quot;tokens=*&quot; <span class="variable">%%A</span> <span class="keyword">in</span> (</span><br><span class="line"> &#x27;REG QUERY &quot;HKCU\Control Panel\NotifyIconSettings&quot; ^| <span class="built_in">findstr</span> /v &quot;REG_&quot; ^| <span class="built_in">findstr</span> /v &quot;NotifyIconSettings$&quot;&#x27;</span><br><span class="line">) <span class="keyword">do</span> (</span><br><span class="line"> REG ADD &quot;<span class="variable">%%A</span>&quot; /v &quot;IsPromoted&quot; /t REG_DWORD /d &quot;<span class="number">1</span>&quot; /f &gt;<span class="built_in">nul</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">:: SystemTrayChevronVisibility [ON]</span><br><span class="line">REG ADD &quot;HKCU\SOFTWARE\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify&quot; /v &quot;SystemTrayChevronVisibility&quot; /t REG_DWORD /d &quot;<span class="number">1</span>&quot; /f</span><br></pre></td></tr></table></figure><p><img src="/gallery/2025/win-11-show-all-tray-icon/1774927631097.webp"></p><p><strong>优点</strong>:不用安装,本质上是批量修改 Windows 设置中的「显示或隐藏其他系统托盘图标」</p><p><strong>缺点</strong>:每次托盘有新图标时,都需要再运行一遍脚本</p><p>此方法在 Windows 11 LTSC 上也同样验证有效。</p><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><p><a href="https://www.elevenforum.com/t/how-to-show-all-system-tray-icons-without-selecting-them-one-by-one-see-print-screen-for-more-details.33642/post-704847">https://www.elevenforum.com/t/how-to-show-all-system-tray-icons-without-selecting-them-one-by-one-see-print-screen-for-more-details.33642/post-704847</a></p><h2 id="以下内容由-AI-生成"><a href="#以下内容由-AI-生成" class="headerlink" title="以下内容由 AI 生成"></a>以下内容由 AI 生成</h2><p>这是一个 Windows 批处理脚本,用于修改 Windows 系统托盘(又称通知区域)的相关设置。它的作用是将系统托盘图标设置为“始终显示”,并确保用于展开隐藏图标的按钮可见。</p><p>下面是对每一部分的详细解释:</p><h3 id="第一部分:NotifyIconSettings-块"><a href="#第一部分:NotifyIconSettings-块" class="headerlink" title="第一部分:NotifyIconSettings 块"></a>第一部分:<code>NotifyIconSettings</code> 块</h3><ul><li><strong>目的</strong>:强制系统托盘中的所有图标都设为“显示图标和通知”(即始终可见),而不是“仅显示通知”(隐藏图标)。</li><li><strong>工作原理</strong>:<ol><li><strong><code>REG QUERY ...</code></strong>:查询注册表路径 <code>HKEY_CURRENT_USER\Control Panel\NotifyIconSettings</code> 下的所有子项。每个子项通常对应一个应用程序在系统托盘中的图标设置。</li><li><strong><code>findstr ...</code></strong>:过滤查询结果,排除包含“REG_”的行(这些是值的数据类型,如 REG_SZ)和标题行“NotifyIconSettings”,只留下子项(即图标设置项)的完整路径。</li><li><strong><code>for /f ... do (...)</code></strong>:对过滤后得到的每一个子项路径(保存在变量<code>%%A</code>中)执行循环体内的命令。</li><li><strong><code>REG ADD &quot;%%A&quot; /v &quot;IsPromoted&quot; ...</code></strong>:在每个图标设置子项下,<strong>添加或修改</strong>一个名为 <code>IsPromoted</code> 的 DWORD(32 位)注册表值,并将其数据设置为 <code>1</code>。<ul><li><code>/f</code> 表示强制覆盖已存在的值。</li><li><code>&gt;nul</code> 将命令的成功输出重定向到空设备,使运行时不显示信息。</li></ul></li></ol></li><li><strong>最终效果</strong>:将所有系统托盘图标的 <code>IsPromoted</code> 值设为 1。在 Windows 中,<code>IsPromoted=1</code> 通常意味着该图标被“提升”到可见区域,不会被系统自动隐藏。</li></ul><h3 id="第二部分:SystemTrayChevronVisibility-设置"><a href="#第二部分:SystemTrayChevronVisibility-设置" class="headerlink" title="第二部分:SystemTrayChevronVisibility 设置"></a>第二部分:<code>SystemTrayChevronVisibility</code> 设置</h3><ul><li><strong>目的</strong>:确保系统托盘区域旁边的“显示隐藏的图标”箭头按钮<strong>始终可见</strong>。</li><li><strong>工作原理</strong>:<ul><li>在 <code>HKEY_CURRENT_USER\...\TrayNotify</code> 路径下,<strong>添加或修改</strong>一个名为 <code>SystemTrayChevronVisibility</code> 的 DWORD 值,并将其数据设置为 <code>1</code>。</li><li><code>“Chevron”</code> 在这里指的就是那个小箭头按钮。将其值设为 <code>1</code> 可以防止这个按钮在某些情况下自动隐藏。</li></ul></li></ul>
🔲 ☆

盘点手里的电子产品传家宝

<p>2025~2026 年,内存价格疯涨,连我妈都破天荒问我家里有没有不用的内存条,涨到什么程度了呢?</p><ul><li>26 款比亚迪秦低配版直接缩水到 4G 内存 16G 存储;</li><li>海力士 256G DDR5 6400 内存的价格已经来到 79999 一根,可以买一辆比亚迪秦;</li><li>小米 17 Ultra 都能卖到 9000 了,欧版更是卖到一万六;</li><li>3 年前一加曾宣传全面淘汰 8G 内存手机,今年返璞归真,自己先用回了 8G 内存。</li></ul><p>今天就来数一数,自己有多少买来以后不降反涨的电子产品吧!</p><span id="more"></span><h2 id="RTX-4090"><a href="#RTX-4090" class="headerlink" title="RTX 4090"></a>RTX 4090</h2><p><strong>品牌</strong>:映众(Inno3D)<br><strong>型号</strong>:冰龙超级版 24GB GDDR6X<br><strong>购买价</strong>:¥12999<br><strong>现价</strong>:买不到,二手大概 ¥20000<br><strong>涨幅</strong>:54%</p><p><strong>真传家宝</strong>!畅玩 Steam 大作,畅跑 72B 以下的模型。就是待机功耗有点高,舍不得一直开着,后来又买了台 Mac mini,跑一堆容器,待机还不到 10W,才解决了这一难题。</p><h2 id="16G-DDR5-内存条×2"><a href="#16G-DDR5-内存条×2" class="headerlink" title="16G DDR5 内存条×2"></a>16G DDR5 内存条×2</h2><p><strong>品牌</strong>:金百达<br><strong>颗粒</strong>:海力士 A-die<br><strong>频率</strong>:6800<br><strong>时序</strong>:C34<br><strong>购买价</strong>:¥695.00(两条加起来)<br><strong>现价</strong>:¥3829.26<br><strong>涨幅</strong>:451%</p><p><img src="/gallery/2025/my-prized-tech-heirloom/1772700143078.webp"></p><p>呃,当时就应该咬咬牙直接上 32G×2 的,不过 32G 日常使用也基本没遇到过什么瓶颈,等降价了一定立马换 64G 了。</p><h2 id="固态硬盘"><a href="#固态硬盘" class="headerlink" title="固态硬盘"></a>固态硬盘</h2><p>手中一共有 6 块不同的固态硬盘。</p><h3 id="致态-TiPlus7100-1TB"><a href="#致态-TiPlus7100-1TB" class="headerlink" title="致态 TiPlus7100 1TB"></a>致态 TiPlus7100 1TB</h3><p>台式机在用,PCIe 4.0 满速,系统盘,离 CPU 最近的盘。</p><p><strong>购买价</strong>:¥449<br><strong>现价</strong>:¥1299<br><strong>涨幅</strong>:189%</p><p>系统盘用个口碑好点的盘,图个稳定。</p><h3 id="幻隐-HV3000GR-2TB"><a href="#幻隐-HV3000GR-2TB" class="headerlink" title="幻隐 HV3000GR 2TB"></a>幻隐 HV3000GR 2TB</h3><p>台式机在用,PCIe 4.0 满速,装游戏,离 CPU 稍远的盘。</p><p><strong>购买价</strong>:¥599<br><strong>现价</strong>:¥2279<br><strong>涨幅</strong>:280%</p><p><img src="/gallery/2024/hv3000-ssd/1.webp"></p><p>之前的博文我还介绍过它(<a href="/2024/hv3000-ssd/">读速 7000 的 2T 固态只卖 599,当游戏盘真香</a>),游戏盘不需要那么稳定,<strong>性价比高 + 容量大 + 速度快</strong>就够了,实际用了 2 年下来,也是啥毛病都没有。有点后悔当时没加点钱 ¥1000 买个 4T。</p><p><strong>PS</strong>:台式机除了这两块盘,还有一块希捷的 2T 机械(ST2000LM015),2.5 寸 7mm 叠瓦盘,购买价 ¥459(全新),机械盘主要存放照片、视频、音乐、素材等,不需要很快的速度,选 2.5 寸是因为我的是 mATX 机箱,没地方塞 3.5 寸盘。</p><p><img src="/gallery/2025/my-prized-tech-heirloom/1772701564564.webp"></p><h3 id="致态-PC005-1TB"><a href="#致态-PC005-1TB" class="headerlink" title="致态 PC005 1TB"></a>致态 PC005 1TB</h3><p>笔记本在用,3500MB&#x2F;s 的速度。</p><p><strong>购买价</strong>:¥809(图中 0 元是用了 E 卡支付)</p><p><img src="/gallery/2025/my-prized-tech-heirloom/1772700320024.webp"></p><p>这块买得比较早,21 年的,当时还在用联想,后来换笔记本,直接拆下来装到新笔记本上继续用。</p><h3 id="致态-PC300-1TB"><a href="#致态-PC300-1TB" class="headerlink" title="致态 PC300 1TB"></a>致态 PC300 1TB</h3><p>机械革命 15X 笔记本内置的盘,据说要抽奖,运气好了是三星内存 + 致态硬盘,运气不好就是别的牌子,真不错。</p><h3 id="梅捷-1TB-SATA"><a href="#梅捷-1TB-SATA" class="headerlink" title="梅捷 1TB SATA"></a>梅捷 1TB SATA</h3><p>华硕老爷机在用,换下机械盘,焕发老爷机第二春,平常浏览器上上网,WPS 改改文档,敲几行代码,一点不卡,还能再战 5 年,需要算力的时候就远程到台式机。</p><p><strong>购买价</strong>:¥192(史低,当时的固态硬盘普遍比机械硬盘还便宜)<br><strong>现价</strong>:¥800(同品牌已下架,类似产品价格)<br><strong>涨幅</strong>:317%</p><p><img src="/gallery/2025/my-prized-tech-heirloom/1772700385593.webp"></p><h3 id="三星-PM981A-512G"><a href="#三星-PM981A-512G" class="headerlink" title="三星 PM981A 512G"></a>三星 PM981A 512G</h3><p>联想笔记本内置的盘,现在拆下来装到 NAS 上当缓存用了(真的需要这么大的缓存吗 OwO)。</p><h2 id="12T-机械硬盘×2"><a href="#12T-机械硬盘×2" class="headerlink" title="12T 机械硬盘×2"></a>12T 机械硬盘×2</h2><p><strong>型号</strong>:东芝 MG07ACA12TE,西数 HUH721212ALE601,都是垂直盘<br><strong>购买价</strong>:东芝 ¥589,西数 ¥579<br><strong>现价</strong>:一块大概 ¥2000 左右,两块就是 ¥4000<br><strong>涨幅</strong>:242%</p><p><img src="/gallery/2025/my-prized-tech-heirloom/1772701573755.webp"></p><p>两块企业级机械硬盘,都是二手服务器淘汰下来的盘,SMART 和坏道扫描都正常,刚到手工作时长都在 9000~10000 小时。插进了我的 NAS(极空间 Z2 Pro)里面,互为备份。之所以专挑这种二手盘,一个是因为便宜,还有很重要的一点原因是,企业盘更适合 NAS 这种连续不间断开机的机器,机械硬盘故障大部分都出现在新盘的第一年使用中,二手盘能一万小时不出故障,后面出故障的概率也很低了。</p><h2 id="存储卡"><a href="#存储卡" class="headerlink" title="存储卡"></a>存储卡</h2><h3 id="平板-移速-128G"><a href="#平板-移速-128G" class="headerlink" title="平板 - 移速 128G"></a>平板 - 移速 128G</h3><p>移速金卡,128G,A2,V60,目前手里最快的卡,给联想拯救者平板用的。</p><p><strong>购买价</strong>:¥64(图中价格 ¥25 是用了 E 卡的价格)<br><strong>现价</strong>:¥176<br><strong>涨幅</strong>:175%</p><p><img src="/gallery/2025/my-prized-tech-heirloom/1772702342796.webp"></p><h3 id="Switch-移速-128G"><a href="#Switch-移速-128G" class="headerlink" title="Switch - 移速 128G"></a>Switch - 移速 128G</h3><p>用着不错,又买了一张,插到 Switch 游戏机了。</p><p><strong>购买价</strong>:¥67<br><strong>现价</strong>:¥176<br><strong>涨幅</strong>:163%</p><p><img src="/gallery/2025/my-prized-tech-heirloom/1772702481294.webp"></p><h3 id="监控-移速-64G"><a href="#监控-移速-64G" class="headerlink" title="监控 - 移速 64G"></a>监控 - 移速 64G</h3><p>移速 64G,最便宜的卡,速度不知道,10 块钱 64G 还想要什么自行车?客厅监控摄像头用的。</p><p><strong>购买价</strong>:¥11<br><strong>现价</strong>:¥63<br><strong>涨幅</strong>:473%</p><p><img src="/gallery/2025/my-prized-tech-heirloom/1772703203829.webp"></p><h3 id="无人机-大迈-64G"><a href="#无人机-大迈-64G" class="headerlink" title="无人机 - 大迈 64G"></a>无人机 - 大迈 64G</h3><p>大迈 64G,4K 卡性价比之王,大疆无人机 Mini 4K 航拍用的。</p><p><strong>购买价</strong>:¥19<br><strong>现价</strong>:¥70<br><strong>涨幅</strong>:268%</p><p><img src="/gallery/2025/my-prized-tech-heirloom/1772702355778.webp"></p><h3 id="全景相机-朗科-128G"><a href="#全景相机-朗科-128G" class="headerlink" title="全景相机 - 朗科 128G"></a>全景相机 - 朗科 128G</h3><p>朗科 128G,给影石 Insta360 X5,全景相机对卡的速度要求挺高的,而且全景视频文件都比较大。</p><p><strong>购买价</strong>:¥33<br><strong>现价</strong>:¥169<br><strong>涨幅</strong>:412%</p><p><img src="/gallery/2025/my-prized-tech-heirloom/1772702486812.webp"></p><h2 id="手机、平板"><a href="#手机、平板" class="headerlink" title="手机、平板"></a>手机、平板</h2><p>存储涨价也间接影响到手机和平板市场,所以我专门都买了顶配,准备多用几年。</p><h3 id="小米-17-Pro-Max-16G-1T"><a href="#小米-17-Pro-Max-16G-1T" class="headerlink" title="小米 17 Pro Max 16G + 1T"></a>小米 17 Pro Max 16G + 1T</h3><p>1T 看着大,其实几个米哈游、鹰角、库洛的手游安装下来,加上微信、哔哩哔哩,已经没了 500G 了。</p><p><strong>购买价</strong>:¥6198</p><p><img src="/gallery/2025/my-prized-tech-heirloom/1772704500330.webp"></p><h3 id="一加-Ace-5-竞速版-16G-512G"><a href="#一加-Ace-5-竞速版-16G-512G" class="headerlink" title="一加 Ace 5 竞速版 16G + 512G"></a>一加 Ace 5 竞速版 16G + 512G</h3><p>备用机,主要优势是电池大 + 能解锁 <strong>能 ROOT</strong>。</p><p><strong>购买价</strong>:¥2023</p><p><img src="/gallery/2025/my-prized-tech-heirloom/1772704651591.webp"></p><h3 id="联想-Y700-四代-16G-512G"><a href="#联想-Y700-四代-16G-512G" class="headerlink" title="联想 Y700 四代 16G + 512G"></a>联想 Y700 四代 16G + 512G</h3><p>8 寸小平板,配置强,主要优势是能插 TF 卡。</p><p><strong>购买价</strong>:¥3070</p><p><img src="/gallery/2025/my-prized-tech-heirloom/1772704619884.webp"></p><h2 id="结语"><a href="#结语" class="headerlink" title="结语"></a>结语</h2><p>买的时候也没想到会涨成今天这个样子,希望它们能多用几年,平安渡过这个存储寒冬。所以什么时候可以在期货交易市场看到内存条?</p>
🔲 ☆

基于 7z 的 NAS 到网盘备份解决方案,支持增量、分卷、加密、压缩

<h2 id="故事背景"><a href="#故事背景" class="headerlink" title="故事背景"></a>故事背景</h2><p>曾经,我组建了一个极空间的 NAS。往里面塞了两块 12T 的硬盘,将 20 年来的照片,音乐,电影,游戏、代码、文档都导了进去。虽然两块硬盘互为备份的机制一定程度解决了硬盘可能出现的寿命问题,但心里总是没底,毕竟两块硬盘在物理层面是放在一起的,万一出个什么断电或者天灾什么的,两块硬盘一起坏了怎么办?<strong>将数据备份到网盘是一个不错的选择</strong>。但问题马上出现,NAS 上的文件至少有几十万到上百万,有些文件的目录层级还藏的很深,还有一些超过 10G 的巨型文件。绝大多数网盘都无法处理这种海量文件和巨型文件的情况,另外,照片库是一个非常隐私的东西,我也不想直接把照片传到网盘上,被大数据精准营销,有些文件,比如游戏和电影资源,还可能会直接被网盘封杀,另外,每隔一段时间,我都需要向网盘上传新增的文件,很难整理出哪些文件是新的,将以上问题总结起来就是——</p><ol><li>要支持海量小文件的备份</li><li>要支持单个过大的文件的备份</li><li>要支持先加密再上传到网盘</li><li>要支持增量备份(你也不想每次备份完都上传几个 T 的文件吧)</li></ol><p>首先想到的方案是直接通过 7-Zip 分卷加密压缩,但是这样意味着当我想从网盘中取出某一个文件时,必须要把整整 2~3T 的文件全部下下来。后来我了解到了 Duplicati,这也是很多极空间用户的选择。他可以直接通过 Docker 的方式部署在极空间,实现文件的加密备份,你可以手动设置每个备份文件的最大大小,更方便的是需要某个文件时,只需要从网盘下载相关的分卷即可。但使用以后,我又发现以下两个问题——</p><span id="more"></span><p><img src="/gallery/2025/nas-backup/1772113623209.webp"></p><ol><li>Duplicati 生成的备份文件,必须由 Duplicati 读取,即使它产生的 AES 文件可以通过 AES Crypt 命令行解密,解密后的文件结构也难以恢复,我就是不想绑定这个工具!</li><li>备份文件名是完全随机的 hash 值,难以快速找到某个文件在哪个分卷中。有时出门在外,家里没网,想从网盘找个文件,完全没辙!</li></ol><p>对此,我想出了以下备份方案——</p><p><strong>总体思想</strong>:保持目录结构的同时,大文件分卷,小文件合并,使用 7-Zip 进行加密压缩</p><ol><li>递归 NAS 目录,如果目录小于指定的分卷大小,直接整目录压缩为一个文件</li><li>如果目录大于指定的分卷大小,没有子目录,就将整目录分卷压缩</li><li>如果目录大于指定的分卷大小,有子目录,对子目录执行以上判断,对子文件执行分卷压缩</li><li>支持增量备份,每次备份生成文件列表,文件列表中记录有文件的大小和修改时间,根据这两个属性判断文件是否有改动,后续备份只需要将新的备份目录上传到网盘即可,无需重新上传完整的备份</li></ol><p>这样当我在异地需要从网盘取回某个指定文件时,只需要到对应的目录,下载对应的压缩文件,用 7-Zip 解压,输入密码即可,只需要一个解压软件,其他任何工具都不需要装,是不是非常方便!</p><p>最近出了一个以 Spec Coding(规约编程)为卖点的 AI IDE 名叫 Kiro,正好拿这个项目试试水!你可以查看 <a href="https://github.com/imaegoo/zbak/blob/main/.kiro/specs/nas-backup-tool/requirements.md">requirements.md</a>、<a href="https://github.com/imaegoo/zbak/blob/main/.kiro/specs/nas-backup-tool/design.md">design.md</a>、<a href="https://github.com/imaegoo/zbak/blob/main/.kiro/specs/nas-backup-tool/tasks.md">tasks.md</a> 来看看 Kiro 是如何从 0 完成整个项目的,真的很强!</p><p>项目已开源:<a href="https://github.com/imaegoo/zbak">https://github.com/imaegoo/zbak</a></p><p>如果你认为这个备份方法适合你,欢迎下载使用!工具现支持命令行调用,也支持 Docker 调用。我是直接在极空间上的 Docker 跑的。</p><p><img src="/gallery/2025/nas-backup/1772113365140.webp"></p><h2 id="工作原理"><a href="#工作原理" class="headerlink" title="工作原理"></a>工作原理</h2><h3 id="备份流程"><a href="#备份流程" class="headerlink" title="备份流程"></a>备份流程</h3><ol><li><strong>增量检测</strong> - 扫描源目录,比对文件索引,识别新增、修改和删除的文件</li><li><strong>智能压缩</strong> - 根据目录大小和结构选择压缩策略:<ul><li>小目录(&lt; 分卷大小):单文件压缩</li><li>大目录无子目录:分卷压缩</li><li>大目录有子目录:递归处理</li></ul></li><li><strong>并发执行</strong> - 使用工作池并发处理多个压缩任务</li><li><strong>索引更新</strong> - 更新文件索引,记录备份信息</li><li><strong>时间戳管理</strong> - 将备份文件存储在时间戳目录中</li></ol><h3 id="恢复流程"><a href="#恢复流程" class="headerlink" title="恢复流程"></a>恢复流程</h3><ol><li><strong>发现备份</strong> - 扫描时间戳目录,识别所有压缩文件</li><li><strong>按序恢复</strong> - 按时间顺序依次解压备份文件</li><li><strong>覆盖更新</strong> - 新版本文件覆盖旧版本</li><li><strong>删除处理</strong> - 删除索引中标记为已删除的文件</li></ol><h3 id="目录结构"><a href="#目录结构" class="headerlink" title="目录结构"></a>目录结构</h3><p>备份出来的目录就长这样,保持源目录结构的同时,拆分了大文件,合并了小文件,全部实现加密压缩,每次备份都生成一个时间戳命名的目录。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">target_dir/</span><br><span class="line">├── index.yaml # 文件索引</span><br><span class="line">├── backup-2024-01-15-10-30-00.log # 备份日志</span><br><span class="line">├── 2024-01-15-10-30-00/ # 时间戳目录</span><br><span class="line">│ ├── dir1.7z.001 # 小目录压缩</span><br><span class="line">│ ├── dir2/</span><br><span class="line">│ │ ├── files.7z.001 # 目录中的文件</span><br><span class="line">│ │ ├── files.7z.002</span><br><span class="line">│ │ └── subdir1.7z.001 # 子目录压缩</span><br><span class="line">│ └── dir3/</span><br><span class="line">│ ├── subdir1.7z.001</span><br><span class="line">│ └── subdir2.7z.001</span><br><span class="line">└── 2024-01-16-14-20-00/ # 另一个时间戳目录</span><br><span class="line"> └── ...</span><br></pre></td></tr></table></figure><h2 id="配置说明"><a href="#配置说明" class="headerlink" title="配置说明"></a>配置说明</h2><p>写个 <code>config.yaml</code> 跟程序放一起就行。</p><table><thead><tr><th>配置项</th><th>类型</th><th>必需</th><th>说明</th></tr></thead><tbody><tr><td><code>source_dir</code></td><td>string</td><td>是</td><td>需要备份的源目录路径</td></tr><tr><td><code>target_dir</code></td><td>string</td><td>是</td><td>存储备份文件的目标目录路径</td></tr><tr><td><code>volume_size</code></td><td>int64</td><td>是</td><td>分卷大小(字节),建议4GB(4294967296)</td></tr><tr><td><code>password</code></td><td>string</td><td>是</td><td>加密密码,用于7zip AES-256加密</td></tr><tr><td><code>concurrency</code></td><td>int</td><td>是</td><td>并发压缩任务数,建议设置为CPU核心数</td></tr><tr><td><code>compression_level</code></td><td>int</td><td>否</td><td>压缩级别 (0-9),默认为1(极速)。0&#x3D;存储,1&#x3D;极速,5&#x3D;正常,9&#x3D;最大压缩</td></tr></tbody></table><h2 id="性能特点"><a href="#性能特点" class="headerlink" title="性能特点"></a>性能特点</h2><ul><li><strong>内存稳定</strong> - 处理大量小文件时保持稳定的内存使用</li><li><strong>高效索引</strong> - 使用哈希表实现O(1)查找性能</li><li><strong>并发优化</strong> - 合理利用CPU资源,支持多任务并发处理</li><li><strong>缓冲写入</strong> - 日志记录使用缓冲写入,提高I&#x2F;O性能</li></ul>
🔲 ☆

卸载百度网盘智能看图

<p>复制代码,粘贴到记事本,保存为 bat 文件,右键以管理员身份运行。</p><span id="more"></span><figure class="highlight bat"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line">@<span class="built_in">echo</span> off</span><br><span class="line"></span><br><span class="line"><span class="built_in">echo</span> 百度网盘智能看图卸载工具</span><br><span class="line"><span class="built_in">echo</span> 请以管理员身份运行此脚本!</span><br><span class="line"><span class="built_in">echo</span>.</span><br><span class="line"></span><br><span class="line"><span class="built_in">echo</span> 正在删除注册表项...</span><br><span class="line">:: 删除HKEY_CLASSES_ROOT\BaiduNetdiskImageViewerAssociations</span><br><span class="line"><span class="built_in">taskkill</span> /f /im BaiduNetdisk.exe &gt;<span class="built_in">nul</span> <span class="number">2</span>&gt;<span class="built_in">nul</span></span><br><span class="line">reg delete &quot;HKEY_CLASSES_ROOT\BaiduNetdiskImageViewerAssociations&quot; /f &gt;<span class="built_in">nul</span> <span class="number">2</span>&gt;<span class="built_in">nul</span></span><br><span class="line"></span><br><span class="line">:: 删除HKEY_CURRENT_USER\Software\Baidu\BaiduNetdiskImageViewer</span><br><span class="line">reg delete &quot;HKEY_CURRENT_USER\Software\Baidu\BaiduNetdiskImageViewer&quot; /f &gt;<span class="built_in">nul</span> <span class="number">2</span>&gt;<span class="built_in">nul</span></span><br><span class="line"></span><br><span class="line">:: 删除HKEY_CURRENT_USER\Software\RegisteredApplications\BaiduNetdiskImageViewer</span><br><span class="line">reg delete &quot;HKEY_CURRENT_USER\Software\RegisteredApplications&quot; /v &quot;BaiduNetdiskImageViewer&quot; /f &gt;<span class="built_in">nul</span> <span class="number">2</span>&gt;<span class="built_in">nul</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">echo</span>.</span><br><span class="line"><span class="built_in">echo</span> 正在删除文件夹...</span><br><span class="line">:: 安装位置不确定,但开始菜单中一定有快捷方式,通过快捷方式读取百度网盘的安装位置</span><br><span class="line"><span class="keyword">for</span> /f &quot;usebackq delims=&quot; <span class="variable">%%I</span> <span class="keyword">in</span> (`</span><br><span class="line"> powershell -NoLogo -NoProfile -Command ^</span><br><span class="line"> &quot;(New-Object -COM WScript.Shell).CreateShortcut(&#x27;<span class="variable">%APPDATA%</span>\Microsoft\Windows\<span class="built_in">Start</span> Menu\Programs\百度网盘\百度网盘.lnk&#x27;).TargetPath&quot;</span><br><span class="line">`) <span class="keyword">do</span> (</span><br><span class="line"> <span class="built_in">set</span> &quot;installDir=<span class="variable">%%~</span>dpI&quot;</span><br><span class="line">)</span><br><span class="line"><span class="built_in">set</span> &quot;installDir=<span class="variable">%installDir:~0,-1%</span>&quot;</span><br><span class="line"><span class="built_in">echo</span> 百度网盘安装位置:<span class="variable">%installDir%</span></span><br><span class="line"></span><br><span class="line">:: 查找并删除百度网盘根目录中的ImageViewer文件夹</span><br><span class="line"><span class="keyword">for</span> /d <span class="variable">%%i</span> <span class="keyword">in</span> (&quot;<span class="variable">%installDir%</span>&quot;, &quot;C:\Program Files\Baidu\BaiduNetdisk&quot;) <span class="keyword">do</span> (</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">exist</span> &quot;<span class="variable">%%i</span>\module\ImageViewer&quot; (</span><br><span class="line"> <span class="built_in">rd</span> /s /q &quot;<span class="variable">%%i</span>\module\ImageViewer&quot;</span><br><span class="line"> )</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="built_in">echo</span>.</span><br><span class="line"><span class="built_in">echo</span> 百度网盘智能看图卸载完成!</span><br><span class="line"><span class="built_in">pause</span></span><br></pre></td></tr></table></figure>
🔲 ☆

CDN 方式引入 Monaco Editor

<p>在前端工程中可以用 <code>@monaco-editor/loader</code> 来引入 Monaco,但有时候我们的前端项目不依赖 Webpack、Vite 等打包工具,如何在普通网页中用纯 CDN 的方式引入 Monaco Editor?</p><span id="more"></span><h3 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span> <span class="attr">lang</span>=<span class="string">&quot;zh-CN&quot;</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">&quot;utf-8&quot;</span> /&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">title</span>&gt;</span>Monaco Editor<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">style</span>&gt;</span><span class="language-css"></span></span><br><span class="line"><span class="language-css"> <span class="selector-tag">body</span> &#123;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">margin</span>: <span class="number">0</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">padding</span>: <span class="number">0</span>;</span></span><br><span class="line"><span class="language-css"> &#125;</span></span><br><span class="line"><span class="language-css"> <span class="selector-id">#editor</span> &#123;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">width</span>: <span class="number">100vw</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">height</span>: <span class="number">100vh</span>;</span></span><br><span class="line"><span class="language-css"> &#125;</span></span><br><span class="line"><span class="language-css"> </span><span class="tag">&lt;/<span class="name">style</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;editor&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;https://registry.npmmirror.com/monaco-editor/0.52.2/files/min/vs/loader.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript"> <span class="built_in">require</span>.<span class="title function_">config</span>(&#123;</span></span><br><span class="line"><span class="language-javascript"> <span class="attr">paths</span>: &#123;</span></span><br><span class="line"><span class="language-javascript"> <span class="attr">vs</span>: <span class="string">&quot;https://registry.npmmirror.com/monaco-editor/0.52.2/files/min/vs&quot;</span>,</span></span><br><span class="line"><span class="language-javascript"> &#125;,</span></span><br><span class="line"><span class="language-javascript"> &#125;);</span></span><br><span class="line"><span class="language-javascript"> <span class="variable language_">window</span>.<span class="property">MonacoEnvironment</span> = &#123;</span></span><br><span class="line"><span class="language-javascript"> <span class="attr">getWorkerUrl</span>: <span class="keyword">function</span> (<span class="params">workerId, label</span>) &#123;</span></span><br><span class="line"><span class="language-javascript"> <span class="keyword">return</span> <span class="string">`data:text/javascript;charset=utf-8,<span class="subst">$&#123;<span class="built_in">encodeURIComponent</span>(</span></span></span></span><br><span class="line"><span class="subst"><span class="string"><span class="language-javascript"> <span class="string">&#x27;self.MonacoEnvironment=&#123;baseUrl:&quot;https://registry.npmmirror.com/monaco-editor/0.52.2/files/min/&quot;&#125;;&#x27;</span> +</span></span></span></span><br><span class="line"><span class="subst"><span class="string"><span class="language-javascript"> <span class="string">&#x27;importScripts(&quot;https://registry.npmmirror.com/monaco-editor/0.52.2/files/min/vs/base/worker/workerMain.js&quot;);&#x27;</span></span></span></span></span><br><span class="line"><span class="subst"><span class="string"><span class="language-javascript"> )&#125;</span>`</span>;</span></span><br><span class="line"><span class="language-javascript"> &#125;,</span></span><br><span class="line"><span class="language-javascript"> &#125;;</span></span><br><span class="line"><span class="language-javascript"> <span class="built_in">require</span>([<span class="string">&quot;vs/editor/editor.main&quot;</span>], <span class="keyword">function</span> (<span class="params"></span>) &#123;</span></span><br><span class="line"><span class="language-javascript"> <span class="keyword">const</span> editorElement = <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&quot;editor&quot;</span>);</span></span><br><span class="line"><span class="language-javascript"> <span class="keyword">const</span> editor = monaco.<span class="property">editor</span>.<span class="title function_">create</span>(editorElement, &#123;</span></span><br><span class="line"><span class="language-javascript"> <span class="attr">value</span>:</span></span><br><span class="line"><span class="language-javascript"> <span class="string">&quot;function main() &#123;\n console.log(&#x27;Hello, iMaeGoo!&#x27;);\n&#125;\n\nmain();\n&quot;</span>,</span></span><br><span class="line"><span class="language-javascript"> <span class="attr">language</span>: <span class="string">&quot;javascript&quot;</span>,</span></span><br><span class="line"><span class="language-javascript"> &#125;);</span></span><br><span class="line"><span class="language-javascript"> <span class="variable language_">window</span>.<span class="title function_">addEventListener</span>(<span class="string">&quot;resize&quot;</span>, <span class="function">() =&gt;</span></span></span><br><span class="line"><span class="language-javascript"> editor.<span class="title function_">layout</span>(&#123;</span></span><br><span class="line"><span class="language-javascript"> <span class="attr">width</span>: editorElement.<span class="property">offsetWidth</span>,</span></span><br><span class="line"><span class="language-javascript"> <span class="attr">height</span>: editorElement.<span class="property">offsetHeight</span>,</span></span><br><span class="line"><span class="language-javascript"> &#125;)</span></span><br><span class="line"><span class="language-javascript"> );</span></span><br><span class="line"><span class="language-javascript"> &#125;);</span></span><br><span class="line"><span class="language-javascript"> </span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure><h3 id="效果"><a href="#效果" class="headerlink" title="效果"></a>效果</h3><iframe style="width:100%;height:300px" src="data:text/html,%3C!DOCTYPE%20html%3E%0A%3Chtml%20lang%3D%22zh-CN%22%3E%0A%20%20%3Chead%3E%0A%20%20%20%20%3Cmeta%20charset%3D%22utf-8%22%20%2F%3E%0A%20%20%20%20%3Ctitle%3EMonaco%20Editor%3C%2Ftitle%3E%0A%20%20%20%20%3Cstyle%3E%0A%20%20%20%20%20%20body%20%7B%0A%20%20%20%20%20%20%20%20margin%3A%200%3B%0A%20%20%20%20%20%20%20%20padding%3A%200%3B%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%23editor%20%7B%0A%20%20%20%20%20%20%20%20width%3A%20100vw%3B%0A%20%20%20%20%20%20%20%20height%3A%20100vh%3B%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%3C%2Fstyle%3E%0A%20%20%3C%2Fhead%3E%0A%20%20%3Cbody%3E%0A%20%20%20%20%3Cdiv%20id%3D%22editor%22%3E%3C%2Fdiv%3E%0A%20%20%20%20%3Cscript%20src%3D%22https%3A%2F%2Fregistry.npmmirror.com%2Fmonaco-editor%2F0.52.2%2Ffiles%2Fmin%2Fvs%2Floader.js%22%3E%3C%2Fscript%3E%0A%20%20%20%20%3Cscript%3E%0A%20%20%20%20%20%20require.config(%7B%0A%20%20%20%20%20%20%20%20paths%3A%20%7B%0A%20%20%20%20%20%20%20%20%20%20vs%3A%20%22https%3A%2F%2Fregistry.npmmirror.com%2Fmonaco-editor%2F0.52.2%2Ffiles%2Fmin%2Fvs%22%2C%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%7D)%3B%0A%20%20%20%20%20%20window.MonacoEnvironment%20%3D%20%7B%0A%20%20%20%20%20%20%20%20getWorkerUrl%3A%20function%20(workerId%2C%20label)%20%7B%0A%20%20%20%20%20%20%20%20%20%20return%20%60data%3Atext%2Fjavascript%3Bcharset%3Dutf-8%2C%24%7BencodeURIComponent(%0A%20%20%20%20%20%20%20%20%20%20%20%20'self.MonacoEnvironment%3D%7BbaseUrl%3A%22https%3A%2F%2Fregistry.npmmirror.com%2Fmonaco-editor%2F0.52.2%2Ffiles%2Fmin%2F%22%7D%3B'%20%2B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20'importScripts(%22https%3A%2F%2Fregistry.npmmirror.com%2Fmonaco-editor%2F0.52.2%2Ffiles%2Fmin%2Fvs%2Fbase%2Fworker%2FworkerMain.js%22)%3B'%0A%20%20%20%20%20%20%20%20%20%20)%7D%60%3B%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%7D%3B%0A%20%20%20%20%20%20require(%5B%22vs%2Feditor%2Feditor.main%22%5D%2C%20function%20()%20%7B%0A%20%20%20%20%20%20%20%20const%20editorElement%20%3D%20document.getElementById(%22editor%22)%3B%0A%20%20%20%20%20%20%20%20const%20editor%20%3D%20monaco.editor.create(editorElement%2C%20%7B%0A%20%20%20%20%20%20%20%20%20%20value%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%22function%20main()%20%7B%5Cn%20%20console.log('Hello%2C%20iMaeGoo!')%3B%5Cn%7D%5Cn%5Cnmain()%3B%5Cn%22%2C%0A%20%20%20%20%20%20%20%20%20%20language%3A%20%22javascript%22%2C%0A%20%20%20%20%20%20%20%20%7D)%3B%0A%20%20%20%20%20%20%20%20window.addEventListener(%22resize%22%2C%20()%20%3D%3E%0A%20%20%20%20%20%20%20%20%20%20editor.layout(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20width%3A%20editorElement.offsetWidth%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20height%3A%20editorElement.offsetHeight%2C%0A%20%20%20%20%20%20%20%20%20%20%7D)%0A%20%20%20%20%20%20%20%20)%3B%0A%20%20%20%20%20%20%7D)%3B%0A%20%20%20%20%3C%2Fscript%3E%0A%20%20%3C%2Fbody%3E%0A%3C%2Fhtml%3E"></iframe>
🔲 ☆

在线工具 - 富文本转 Markdown

<p>只需在以下文本框中粘贴网页或 Word 文档的内容,即可转换为 Markdown 格式!</p><p>与网上现有工具相比,这个能支持表格转换!</p><span id="more"></span><h3 id="粘贴网页内容-Word-文档内容"><a href="#粘贴网页内容-Word-文档内容" class="headerlink" title="粘贴网页内容 &#x2F; Word 文档内容"></a>粘贴网页内容 &#x2F; Word 文档内容</h3><style> #editor—wrapper { border: 1px solid #ccc; z-index: 999; } #toolbar-container { border-bottom: 1px solid #ccc; } #editor-container { height: 300px; } #html-content, #md-content { height: 300px; }</style><div id="editor—wrapper"> <div id="toolbar-container"></div> <div id="editor-container"></div></div><h3 id="转换后的-Markdown-内容"><a href="#转换后的-Markdown-内容" class="headerlink" title="转换后的 Markdown 内容"></a>转换后的 Markdown 内容</h3><textarea class="textarea" id="md-content" placeholder="转换后的 Markdown 内容"></textarea><script src="https://registry.npmmirror.com/@wangeditor/editor/5.1.23/files/dist/index.js"></script><script src="https://registry.npmmirror.com/turndown/7.2.1/files/dist/turndown.js"></script><script src="/js/imaegoo/turndown-plugin-gfm.js"></script><script> document.head.appendChild( Object.assign(document.createElement("link"), { rel: "stylesheet", href: "https://registry.npmmirror.com/@wangeditor/editor/5.1.23/files/dist/css/style.css", }) ); const { createEditor, createToolbar } = window.wangEditor; const turndownService = new TurndownService({ headingStyle: "atx", hr: "----", bulletListMarker: "-", codeBlockStyle: "fenced", }); turndownService.use(TurndownPluginGfmService.gfm); const editorConfig = { placeholder: "粘贴 HTML 内容", onChange(editor) { const html = editor.getHtml(); const markdown = turndownService.turndown(html); document.getElementById("md-content").value = markdown; }, }; const editor = createEditor({ selector: "#editor-container", html: "<p><br></p>", config: editorConfig, mode: "simple", }); const toolbar = createToolbar({ editor, selector: "#toolbar-container", config: {}, mode: "simple", });</script>
🔲 ☆

2025 年了,安卓平板上什么第三方九键输入法最好用?

<p>题外话,我换过好多平板,我理想中的平板是 11 寸,这个大小不至于太重,又不至于屏幕太小,要搭载顶级处理器,玩游戏不卡顿,最好支持解锁 BL。</p><p>第一台平板是 iPad Pro 2018 11 寸,这个平板陪伴了我整整 6 年,依然流畅如新,奈何现如今带不动绝区零等大型游戏了,卖掉了。</p><p>第二台平板是小米平板 7,太卡!本来澎湃就吃硬件,还用了个 7+ Gen 3,掉帧死机家常便饭,还无法通过小米的解锁考试,卖掉了。</p><p>第三台是一加平板 2 Pro,顶级配置,一个 fastboot 命令就能轻松解锁,然而第一次用 13 寸,好重啊,躺着更是没法玩,使用频率都降低了,卖掉了。</p><p>第四台也就是现在用的,联想拯救者 Y700,虽然 8 寸是小了点,但毕竟很轻,很容易就接受了。</p><p>联想平板系统就像毛坯房,预装的输入法功能实在太少,决定装一个第三方的输入法,于是考虑如下选择:</p><ul><li>Gboard(谷歌)</li><li>百度输入法</li><li>搜狗输入法</li><li>讯飞输入法</li><li>微信输入法</li></ul><span id="more"></span><p>首先我是一位九键用户,九键在横屏模式下好不好用是我选择一个输入法的重要标准,我认为理想的九键布局,是我正在使用的 VIVO 输入法的布局,这种布局能够在横屏(或者展开形态的折叠屏)状态时,轻松单手打字。</p><p><img src="/gallery/2025/android-pad-input-method/1756091985501.webp"></p><p>其次是支持剪切板、个性短语,方便快速输入地址、手机号等信息,这基本上已经是各家标配功能了。</p><h3 id="Gboard"><a href="#Gboard" class="headerlink" title="Gboard"></a>Gboard</h3><p><img src="/gallery/2025/android-pad-input-method/1756093349018.webp"></p><p><img src="/gallery/2025/android-pad-input-method/1756093360818.webp"></p><p>谷歌出品的输入法在风格上完全遵守自家的设计规范,英文键盘更加贴近实体键盘的键位,很容易上手,然而九键在横屏下不支持分屏,横屏打字就比较难受了。</p><h3 id="百度输入法"><a href="#百度输入法" class="headerlink" title="百度输入法"></a>百度输入法</h3><p><img src="/gallery/2025/android-pad-input-method/1756093512148.webp"></p><p><img src="/gallery/2025/android-pad-input-method/1756093515225.webp"></p><p><img src="/gallery/2025/android-pad-input-method/1756093517471.webp"></p><p>百度输入法的九键布局是我最喜欢的,自定义程度也很高,能合能分,但在联想平板上有一个 bug,清理后台会导致百度输入法失去默认输入法地位,每次清后台都要去重新设置回百度输入法,折腾几次就不想用了。</p><h3 id="百度输入法小米版"><a href="#百度输入法小米版" class="headerlink" title="百度输入法小米版"></a>百度输入法小米版</h3><p><img src="/gallery/2025/android-pad-input-method/1756093523827.webp"></p><p><img src="/gallery/2025/android-pad-input-method/1756093526380.webp"></p><p>小米版中文和原版相同,英文是和 Gboard 一样的实体键盘布局,但在联想平板上有一个 bug,每次弹出键盘都要弹出用户须知:</p><p><img src="/gallery/2025/android-pad-input-method/1756093529571.webp"></p><p>不管是同意还是拒绝,下次还会弹出,权限管理中授予了所有权限也不行,酷安里也看到有相同的反馈,但没有找到解决方案,遂放弃研究。</p><h3 id="搜狗输入法"><a href="#搜狗输入法" class="headerlink" title="搜狗输入法"></a>搜狗输入法</h3><p><img src="/gallery/2025/android-pad-input-method/1756093447517.webp"></p><p><img src="/gallery/2025/android-pad-input-method/1756093444958.webp"></p><p>搜狗输入法的九键布局有两个奇怪的地方:</p><ol><li>数字键 1 会显示为「分词」,去设置中关闭分词功能可以变回来,但没有分词就不能方便地打出「西安」、「酷安」这类词了;</li><li>符号中有一个歪歪扭扭的 <code>.COM</code>,还不能改,强迫症实在看不下去了。</li></ol><h3 id="讯飞输入法"><a href="#讯飞输入法" class="headerlink" title="讯飞输入法"></a>讯飞输入法</h3><p><img src="/gallery/2025/android-pad-input-method/1756093455731.webp"></p><p><img src="/gallery/2025/android-pad-input-method/1756093458336.webp"></p><p>讯飞九键中间可以手写,这个设计让人眼前一亮,但它占了很大的空间,无法调整,我用手写的频率是很少的,没必要为了这个牺牲九键的空间。</p><h3 id="微信输入法"><a href="#微信输入法" class="headerlink" title="微信输入法"></a>微信输入法</h3><p><img src="/gallery/2025/android-pad-input-method/1756093429699.webp"></p><p><img src="/gallery/2025/android-pad-input-method/1756093438238.webp"></p><p>微信输入法相比百度和搜狗,界面更加简洁干净无广告,和其他输入法数字键+九键的布局不同,微信一边是选词区,一边是九键,这种布局一开始不太适应,但用两分钟就会发现,选词的使用频率是高于数字键盘的,更大的选词区确实方便不少。微信输入法还直接支持外接键盘打字,外接键盘不用来回切换输入法了:</p><p><img src="/gallery/2025/android-pad-input-method/1756098085786.webp"></p><p>一个星期体验下来也没有什么明显的 bug。要说缺点,就是导入词库有点难搞,我 PC 上的主力输入法是 Rime 小狼毫,要是微信能直接导入 txt 词库就方便了。</p><p>经过以上对比,最后我选择了微信输入法。</p>
🔲 ☆

鸿蒙 PC 编译运行 Electron 应用

<p>华为推出的 MateBook Pro 首次搭载了鸿蒙 PC 操作系统,使其能够直接运行鸿蒙手机应用和鸿蒙平板应用,但仅仅这样只能称得上是『大号平板』。</p><p>Electron 框架是优秀的跨平台客户端框架,通过改造,鸿蒙 PC 上也能运行 Electron 应用,具体如何操作呢?</p><span id="more"></span><h2 id="编译-Electron"><a href="#编译-Electron" class="headerlink" title="编译 Electron"></a>编译 Electron</h2><p>可以自己编译,也可以用华为预编译好的版本。</p><h3 id="自己编译"><a href="#自己编译" class="headerlink" title="自己编译"></a>自己编译</h3><p>参考文档:<a href="https://gitcode.com/openharmony-sig/electron">https://gitcode.com/openharmony-sig/electron</a></p><p>编译环境必须使用 Ubuntu 22.04,可以用虚拟机。</p><p>编译耗时很长,我用 8 核虚拟机 <strong>跑了大概 8 个小时左右</strong>,如无特殊需求建议用华为预编译好的版本。</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 安装工具git-lfs, ccache。注:该步骤仅在首次拉取代码时需要执行</span></span><br><span class="line"><span class="built_in">sudo</span> apt install -y git-lfs ccache curl python3 python-is-python3 python3-pip</span><br><span class="line">python --version</span><br><span class="line">pip --version</span><br><span class="line"></span><br><span class="line"><span class="comment"># 下载码云repo工具(可以参考码云帮助中心:https://gitee.com/help/articles/4316)</span></span><br><span class="line"><span class="built_in">mkdir</span> -p ~/bin</span><br><span class="line">curl https://gitee.com/oschina/repo/raw/fork_flow/repo-py3 &gt; ~/bin/repo</span><br><span class="line"><span class="built_in">chmod</span> a+x ~/bin/repo</span><br><span class="line"><span class="built_in">echo</span> <span class="string">&#x27;export PATH=~/bin/:$PATH&#x27;</span> &gt;&gt; ~/.bashrc</span><br><span class="line"><span class="built_in">source</span> ~/.bashrc</span><br><span class="line">pip install -i https://pypi.tuna.tsinghua.edu.cn/simple requests</span><br><span class="line"></span><br><span class="line"><span class="comment"># 通过NodeSource仓库安装node和npm</span></span><br><span class="line">curl -fsSL https://deb.nodesource.com/setup_lts.x | <span class="built_in">sudo</span> -E bash -</span><br><span class="line"><span class="built_in">sudo</span> apt install -y nodejs</span><br><span class="line">node -v</span><br><span class="line">npm -v</span><br><span class="line"></span><br><span class="line"><span class="comment"># 使用https拉取chromium-electron代码</span></span><br><span class="line">git <span class="built_in">clone</span> -b master https://gitcode.com/openharmony-sig/electron.git</span><br><span class="line"></span><br><span class="line"><span class="comment"># 执行命令`git lfs pull`,确保仓库中的大文件已经下载完成</span></span><br><span class="line"><span class="built_in">cd</span> electron</span><br><span class="line">git lfs pull</span><br><span class="line"></span><br><span class="line"><span class="comment"># 拉取chromium-electron对应的ohos chromium代码</span></span><br><span class="line">git config --global user.name <span class="string">&quot;iMaeGoo&quot;</span></span><br><span class="line">git config --global user.email <span class="string">&quot;mail1st@qq.com&quot;</span></span><br><span class="line">repo init -u https://gitcode.com/openharmony-tpc/manifest.git -b pc_chromium_132 -m pc_chromium_132_20251106.xml --no-repo-verify</span><br><span class="line">repo <span class="built_in">sync</span> -c <span class="comment"># 可以执行多次,以确保代码全部拉取成功</span></span><br><span class="line">repo forall -c <span class="string">&#x27;git lfs pull&#x27;</span> <span class="comment"># 可执行多次,以确保大文件全部拉取成功</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 应用chromium-electron的patch到ohos chromium</span></span><br><span class="line"><span class="built_in">pushd</span> src</span><br><span class="line">find -name <span class="string">&quot;*.git*&quot;</span> -<span class="built_in">exec</span> <span class="built_in">rm</span> -rf <span class="string">&quot;&#123;&#125;&quot;</span> \;</span><br><span class="line"><span class="built_in">popd</span></span><br><span class="line"><span class="built_in">chmod</span> +x override_files.sh</span><br><span class="line">./override_files.sh</span><br><span class="line"></span><br><span class="line"><span class="comment"># 运行 Electron实际目录/src/build/install-build-deps.sh脚本,安装编译所需的软件包。注:该步骤仅在首次拉取代码时需要执行</span></span><br><span class="line"><span class="built_in">sudo</span> ./src/build/install-build-deps.sh --no-chromeos-fonts</span><br><span class="line"></span><br><span class="line"><span class="comment"># 运行脚本electron_build.sh</span></span><br><span class="line">./electron_build.sh</span><br><span class="line"></span><br><span class="line"><span class="comment"># 可以通过如下脚本拷贝所需资源(注:请参考修改为自己的source_path)</span></span><br><span class="line">source_path=./Electron实际目录/src/out/musl_64</span><br><span class="line">destination_path=./electron</span><br><span class="line"><span class="keyword">if</span> [ -d <span class="variable">$&#123;destination_path&#125;</span> ];<span class="keyword">then</span></span><br><span class="line"><span class="built_in">rm</span> -rf <span class="variable">$&#123;destination_path&#125;</span></span><br><span class="line"><span class="keyword">fi</span></span><br><span class="line"><span class="built_in">mkdir</span> <span class="variable">$&#123;destination_path&#125;</span></span><br><span class="line"><span class="built_in">cp</span> <span class="variable">$&#123;source_path&#125;</span>/libelectron.so <span class="variable">$&#123;destination_path&#125;</span></span><br><span class="line"><span class="built_in">cp</span> <span class="variable">$&#123;source_path&#125;</span>/libffmpeg.so <span class="variable">$&#123;destination_path&#125;</span></span><br><span class="line"><span class="built_in">cp</span> <span class="variable">$&#123;source_path&#125;</span>/libadapter.so <span class="variable">$&#123;destination_path&#125;</span></span><br><span class="line"><span class="built_in">cp</span> <span class="variable">$&#123;source_path&#125;</span>/electron <span class="variable">$&#123;destination_path&#125;</span></span><br><span class="line"><span class="built_in">cp</span> <span class="variable">$&#123;source_path&#125;</span>/icudtl.dat <span class="variable">$&#123;destination_path&#125;</span></span><br><span class="line"><span class="built_in">cp</span> <span class="variable">$&#123;source_path&#125;</span>/v8_context_snapshot.bin <span class="variable">$&#123;destination_path&#125;</span></span><br><span class="line"><span class="built_in">cp</span> <span class="variable">$&#123;source_path&#125;</span>/chrome_100_percent.pak <span class="variable">$&#123;destination_path&#125;</span></span><br><span class="line"><span class="built_in">cp</span> <span class="variable">$&#123;source_path&#125;</span>/chrome_200_percent.pak <span class="variable">$&#123;destination_path&#125;</span></span><br><span class="line"><span class="built_in">cp</span> <span class="variable">$&#123;source_path&#125;</span>/resources.pak <span class="variable">$&#123;destination_path&#125;</span></span><br><span class="line"><span class="built_in">mkdir</span> <span class="variable">$&#123;destination_path&#125;</span>/locales</span><br><span class="line"><span class="built_in">cp</span> <span class="variable">$&#123;source_path&#125;</span>/locales/zh-CN.pak <span class="variable">$&#123;destination_path&#125;</span>/locales</span><br><span class="line"><span class="built_in">cp</span> <span class="variable">$&#123;source_path&#125;</span>/locales/en-US.pak <span class="variable">$&#123;destination_path&#125;</span>/locales</span><br></pre></td></tr></table></figure><h3 id="使用预编译版本"><a href="#使用预编译版本" class="headerlink" title="使用预编译版本"></a>使用预编译版本</h3><p>没有调用 addon 和 ArkTS 的需求时可以直接使用以下二进制 release 包进行开发。</p><ol><li><p>获取最新日期的二进制 release 包,华为账号登录<a href="https://devcloud.cn-north-4.huaweicloud.com/codehub/project/b19f5ea8ffd4492ea8c06ca2ebf3f858/codehub/2821214/home?ref=electron34-release">仓库</a>,下载默认 Electron 34 的 release 包。</p></li><li><p>解压</p></li></ol><h2 id="搭建环境"><a href="#搭建环境" class="headerlink" title="搭建环境"></a>搭建环境</h2><p>安装 DevEco Studio,目前是 5.1.0,最新版即可</p><p><a href="https://developer.huawei.com/consumer/cn/download/">https://developer.huawei.com/consumer/cn/download/</a></p><p>配置环境变量,这样以后能方便地使用 hdc 等命令</p><p>假设安装路径是 <code>D:\dev\DevEcoStudio</code>,就在 PATH 中增加 <code>D:\dev\DevEcoStudio\sdk\default\openharmony\toolchains</code></p><h2 id="运行项目"><a href="#运行项目" class="headerlink" title="运行项目"></a>运行项目</h2><p>打开 DevEco,打开前面编译&#x2F;下载好的项目 ohos_hap</p><p>首次运行需要证书,按提示登录华为账号即可生成证书</p><p>跑起来的效果,按 Ctrl + Alt + I 可以打开调试</p><p><img src="/gallery/2025/harmony-pc-electron/1756091289483.webp"></p><p>Electron 的入口点在 <code>src/main/resources/resfile/resources/app/main.js</code>,修改后重新运行即可看到效果</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> &#123; app, <span class="title class_">BrowserWindow</span>, <span class="title class_">Tray</span>, nativeImage &#125; = <span class="built_in">require</span>(<span class="string">&#x27;electron&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> path = <span class="built_in">require</span>(<span class="string">&#x27;path&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> mainWindow, tray;</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">createWindow</span>(<span class="params"></span>) &#123;</span><br><span class="line"> tray = <span class="keyword">new</span> <span class="title class_">Tray</span>(nativeImage.<span class="title function_">createFromPath</span>(path.<span class="title function_">join</span>(__dirname, <span class="string">&#x27;electron_white.png&#x27;</span>)));</span><br><span class="line"> mainWindow = <span class="keyword">new</span> <span class="title class_">BrowserWindow</span>(&#123;</span><br><span class="line"> <span class="attr">width</span>: <span class="number">800</span>,</span><br><span class="line"> <span class="attr">height</span>: <span class="number">600</span>,</span><br><span class="line"> &#125;);</span><br><span class="line"> mainWindow.<span class="title function_">setWindowButtonVisibility</span>(<span class="literal">true</span>);</span><br><span class="line"> mainWindow.<span class="title function_">loadURL</span>(<span class="string">&#x27;https://caiyunapp.com/map/&#x27;</span>);</span><br><span class="line">&#125;</span><br><span class="line">app.<span class="title function_">whenReady</span>().<span class="title function_">then</span>(createWindow);</span><br></pre></td></tr></table></figure>
🔲 ☆

bat 脚本打印输出彩色文字

<p>要在 Windows 批处理脚本中打印彩色内容,通常的方式是 <code>echo [32mHello World[0m</code>,但这种方式需要输入特殊字符 <code>ESC</code>(ASCII 码为 27),我试过 Alt+027 的快捷键却怎么也打不出来这个字符,而且这种方式各个颜色的编码也很不好记,分享一种更简单的方法!</p><p><a href="https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/write-host">https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/write-host</a></p><figure class="highlight bat"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">powershell -Command &quot;Write-Host &#x27;This is Black&#x27; -ForegroundColor White -BackgroundColor Black&quot;</span><br><span class="line">powershell -Command &quot;Write-Host &#x27;This is DarkBlue&#x27; -ForegroundColor White -BackgroundColor DarkBlue&quot;</span><br><span class="line">powershell -Command &quot;Write-Host &#x27;This is DarkGreen&#x27; -ForegroundColor White -BackgroundColor DarkGreen&quot;</span><br><span class="line">powershell -Command &quot;Write-Host &#x27;This is DarkCyan&#x27; -ForegroundColor White -BackgroundColor DarkCyan&quot;</span><br><span class="line">powershell -Command &quot;Write-Host &#x27;This is DarkRed&#x27; -ForegroundColor White -BackgroundColor DarkRed&quot;</span><br><span class="line">powershell -Command &quot;Write-Host &#x27;This is DarkMagenta&#x27; -ForegroundColor White -BackgroundColor DarkMagenta&quot;</span><br><span class="line">powershell -Command &quot;Write-Host &#x27;This is DarkYellow&#x27; -ForegroundColor White -BackgroundColor DarkYellow&quot;</span><br><span class="line">powershell -Command &quot;Write-Host &#x27;This is Gray&#x27; -ForegroundColor Black -BackgroundColor Gray&quot;</span><br><span class="line">powershell -Command &quot;Write-Host &#x27;This is DarkGray&#x27; -ForegroundColor White -BackgroundColor DarkGray&quot;</span><br><span class="line">powershell -Command &quot;Write-Host &#x27;This is Blue&#x27; -ForegroundColor White -BackgroundColor Blue&quot;</span><br><span class="line">powershell -Command &quot;Write-Host &#x27;This is Green&#x27; -ForegroundColor White -BackgroundColor Green&quot;</span><br><span class="line">powershell -Command &quot;Write-Host &#x27;This is Cyan&#x27; -ForegroundColor Black -BackgroundColor Cyan&quot;</span><br><span class="line">powershell -Command &quot;Write-Host &#x27;This is Red&#x27; -ForegroundColor White -BackgroundColor Red&quot;</span><br><span class="line">powershell -Command &quot;Write-Host &#x27;This is Magenta&#x27; -ForegroundColor White -BackgroundColor Magenta&quot;</span><br><span class="line">powershell -Command &quot;Write-Host &#x27;This is Yellow&#x27; -ForegroundColor Black -BackgroundColor Yellow&quot;</span><br><span class="line">powershell -Command &quot;Write-Host &#x27;This is White&#x27; -ForegroundColor Black -BackgroundColor White&quot;</span><br></pre></td></tr></table></figure><p>其中单引号内是打印的文字内容,ForegroundColor 参数传文字颜色,BackgroundColor 参数传背景颜色,直接传颜色名字,非常方便。</p><span id="more"></span><p><img src="/gallery/2025/bat-color/1754448805064.webp"></p><p>如果在批处理中使用,可以定义一个函数,调用起来更简洁。</p><figure class="highlight bat"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">@<span class="built_in">echo</span> off</span><br><span class="line"></span><br><span class="line"><span class="keyword">call</span> :<span class="built_in">print</span> &quot;Hello, world!&quot; Yellow Red</span><br><span class="line"><span class="keyword">call</span> :<span class="built_in">print</span> &quot;Hello, iMaeGoo!&quot; White Blue</span><br><span class="line"><span class="keyword">exit</span> /b <span class="number">0</span></span><br><span class="line"></span><br><span class="line">:<span class="built_in">print</span></span><br><span class="line">powershell -Command &quot;Write-Host &#x27;%<span class="number">1</span>&#x27; -ForegroundColor %<span class="number">2</span> -BackgroundColor %<span class="number">3</span>&quot;</span><br><span class="line"><span class="function">goto:<span class="title">eof</span></span></span><br></pre></td></tr></table></figure><p>效果</p><p><img src="/gallery/2025/bat-color/1754449222262.webp"></p>
🔲 ☆

Android 强制锁定屏幕旋转方向

<p>在使用我的一加平板时,一直被一个问题困扰,由于我的桌面电源在左手边,平板横着放在桌上时,如果需要充电,就需要将 Type-C 接口对准左侧,这就需要先解除旋转锁定,立起平板,待屏幕旋转后,打开旋转锁定,再放平。使其锁定在充电口朝左的横屏状态(技术上称为 <code>SCREEN_ORIENTATION_REVERSE_LANDSCAPE</code>,屏幕方向反横向)。</p><p>以前用 iPad Pro 时,我也是一直都这么干的,这倒也没啥,但更麻烦的问题来了。有些 APP 由于代码实现问题,会强制屏幕旋转至某个方向,例如在平板打开美团时,会自动切换到竖屏,打开苍雾世界时,会自动切换到充电口朝右的横屏,退出应用时又会自动切回来。于是当我需要以上场景使用这些 APP 时,必须拖着充电线把平板转来转去,不够大的桌面,不够长的充电线,加上 13 寸 1 斤重的平板,让这一切显得格外艰难。</p><span id="more"></span><p>无法忍受的我便去寻找解决方案,有没有什么模块,能让旋转锁定真正发挥『锁定』的作用,让屏幕不受 APP 影响地保持在一个方向?</p><p>找到了 <a href="https://github.com/tuyafeng/OrientationLock">Orientation Lock</a>,这个只有 65 个 star 的软件可能鲜为人知,但作者 tuyafeng 的另一个软件『Via 浏览器』大家应该都听过。Orientation Lock 的体积只有 60 KB,非常符合该作者的风格,只需要悬浮窗权限,不需要 adb 不需要 root 也不需要安装模块。打开 APP,选择『反转横屏』,然后授予悬浮窗权限,好了,现在各个 APP 都可以在反横屏状态下使用了,解决了我的大麻烦!</p><p><img src="/gallery/2025/orientation-lock/1752201059692.webp"></p><p>附上下载地址:<a href="https://github.com/tuyafeng/OrientationLock/releases/download/1.0.0/OrientationLock_v1.0.apk">https://github.com/tuyafeng/OrientationLock/releases/download/1.0.0/OrientationLock_v1.0.apk</a></p>
🔲 ☆

腾讯代码托管服务 Coding 将停服

<p>腾讯云本周宣布 Coding 将在今年 9 月 1 日起停止免费版服务,2028 年 9 月 30 日彻底停止服务。</p><span id="more"></span><p><img src="/gallery/2025/coding-end-of-service/1750987354004.webp"></p><p>原公告:<a href="https://cloud.tencent.com/document/product/1726/116235">https://cloud.tencent.com/document/product/1726/116235</a></p><p>对此我居然一点也不感到意外,毕竟也不是被背刺一回两回了,就是花了点时间把 Coding 上面的代码迁移到阿里云 Codeup。</p><p>公告上说推荐迁移到他们的新一代产品《云原生构建》,我试了一下,连 SSH 都不支持,只能 HTTPS 方式克隆,直接告辞。</p><p><img src="/gallery/2025/coding-end-of-service/1750987517274.webp"></p>
🔲 ☆

微信快速找出自己创建的群聊

<p>微信本身没有筛选自己创建的群聊的功能,需要将微信的数据库解密,然后通过 SQL 语句查询。</p><span id="more"></span><h3 id="下载所需工具"><a href="#下载所需工具" class="headerlink" title="下载所需工具"></a>下载所需工具</h3><ol><li>微信 4.0.3.22 Windows 版本,最新版本的不行,下载地址: <a href="https://github.com/cscnk52/wechat-windows-versions/releases/tag/v4.0.3.22">https://github.com/cscnk52/wechat-windows-versions/releases/tag/v4.0.3.22</a> (如果这个地址没了就自己再找)</li></ol><p><img src="/gallery/2025/find-owned-weixin-group/1746690814601.webp"></p><ol start="2"><li>wechat-dump-rs,下载地址: <a href="https://github.com/0xlane/wechat-dump-rs/releases">https://github.com/0xlane/wechat-dump-rs/releases</a></li><li>DB Browser for SQLite,下载地址: <a href="https://sqlitebrowser.org/dl/#windows">https://sqlitebrowser.org/dl/#windows</a></li></ol><h3 id="解密数据库"><a href="#解密数据库" class="headerlink" title="解密数据库"></a>解密数据库</h3><ol><li>登录微信,保持微信运行</li><li>打开 cmd,cd 到 wechat-dump-rs.exe 所在目录</li><li>执行 <code>wechat-dump-rs.exe -a</code></li><li>如果看到 <code>decryption complete!!</code> 就成功了,output to 后面就是解密后的数据库路径</li></ol><p><img src="/gallery/2025/find-owned-weixin-group/1746690948415.webp"></p><h3 id="打开数据库"><a href="#打开数据库" class="headerlink" title="打开数据库"></a>打开数据库</h3><ol><li>到 DB Browser for SQLite 的安装目录,打开 <code>DB Browser for SQLCipher.exe</code></li></ol><p><img src="/gallery/2025/find-owned-weixin-group/1746691668841.webp"></p><ol start="2"><li>打开数据库,定位到上一步 output 的目录,打开 <code>contact/contact.db</code></li></ol><p><img src="/gallery/2025/find-owned-weixin-group/1746691078525.webp"></p><ol start="3"><li>点执行 SQL</li><li>粘贴以下语句,点执行</li></ol><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">SELECT</span> chat_room.owner, contact.nick_name</span><br><span class="line"><span class="keyword">FROM</span> chat_room</span><br><span class="line"><span class="keyword">LEFT</span> <span class="keyword">JOIN</span> contact</span><br><span class="line"><span class="keyword">ON</span> chat_room.username <span class="operator">=</span> contact.username</span><br><span class="line"><span class="keyword">WHERE</span> chat_room.owner <span class="operator">=</span> &quot;换成你的微信号&quot;</span><br><span class="line"><span class="keyword">AND</span> contact.is_in_chat_room <span class="operator">!=</span> <span class="number">2</span>;</span><br></pre></td></tr></table></figure><ol start="5"><li>就可以看到所有自己创建的微信群了</li></ol><p><img src="/gallery/2025/find-owned-weixin-group/1746691159125.webp"></p>
🔲 ☆

将扣子空间生成的 jsx 格式网页部署到自己的服务器

<p>扣子空间生成的网页是 jsx 格式的,在扣子空间内可以正常打开,如果想要部署到自己的服务器,则需要经过编译。</p><p>为此,我写了一个模板,只需将扣子空间生成的 jsx 重命名为 <code>coze.tsx</code>(注意后缀要改为 tsx)放入本项目 <code>src</code> 目录,即可编译出可静态部署的 dist 产物。</p><span id="more"></span><h2 id="详细步骤"><a href="#详细步骤" class="headerlink" title="详细步骤"></a>详细步骤</h2><ol><li>从扣子空间下载 jsx 文件</li></ol><p><img src="/gallery/2025/coze-space-jsx/1745907200269.webp"></p><ol start="2"><li>下载 <a href="https://github.com/imaegoo/coze-space-jsx-template">模板工程</a></li><li>安装 Node.js</li><li>进入本项目所在目录,运行 <code>npm install -g pnpm</code> 安装 pnpm 包管理器</li><li>运行 <code>pnpm install</code> 安装依赖</li><li>将扣子空间生成的 jsx 重命名为 <code>coze.tsx</code>(注意后缀要改为 tsx),放入 <code>src</code> 目录,覆盖原有的 <code>coze.tsx</code> 文件</li></ol><p><img src="/gallery/2025/coze-space-jsx/1745898560927.webp"></p><ol start="7"><li>检查 <code>coze.tsx</code> 中的 <code>import</code> 语句,确保所有第三方包都已经安装,举例:如果 <code>coze.tsx</code> 中有 <code>import Mermaid from &#39;mermaid&#39;;</code>,就执行安装 <code>pnpm install mermaid</code></li><li>运行 <code>pnpm run dev</code> 查看效果</li></ol><p><img src="/gallery/2025/coze-space-jsx/1745898552039.webp"></p><ol start="9"><li>运行 <code>pnpm run build</code> 编译</li><li>编译完成后,在 <code>dist</code> 目录下即可找到编译后的产物</li></ol>
🔲 ☆

扣子空间邀请码

字节跳动出了一个类 Manus 的 AI Agent 工具,叫扣子空间,目前是邀请码内测机制,在此分享几个邀请码。

邀请码使用地址: https://space.coze.cn

用完记得评论说下已使用,如果邀请码都已使用,可以评论提醒我补充更多的邀请码。

1
2
3
4
5
Q4RA5622 已激活
54W9053G 已激活
4YUTZNOV 已激活
XFZKRCIZ 已激活
HZFQRQVC 已激活

续 1

发出来才 3 分钟不到就全被用了,然而没一个人留言。有真正需求的可以关注博客页面左边的公众号(虹墨iMaeGoo)私信我获取。

续 2

我的所有 20 个邀请码都发放完毕了,你可以通过其他渠道获得邀请码 - https://docs.qq.com/sheet/DUkdXa1JtQWtlSXJp

续 3

更多邀请码放出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
8D01YILO 已激活
SCFBW27F 已激活
GPI4P0OL 已激活
EDW7VRLW 已激活
3HIZ37XF 已激活
Q4RA5622 已激活
54W9053G 已激活
4YUTZNOV 已激活
XFZKRCIZ 已激活
HZFQRQVC 已激活
D7FWIMJ4 已激活
H9ZM7KQ1 已激活
94PYYP6R 已激活
5HO53HQL 已激活
4YQYH3BC 已激活
C5QJ9RUZ 已激活
42BGV4OD 已激活
C5IKZ13G 已激活
F4R5RQWX 已激活
P449LTOC 已激活
RAL58FKV 已激活
H7K47ET3 已激活
IP765WVL 已激活
H8WDAT20 已激活
ST25AOYY 已激活
V0NRUE3G 已激活
KM0M6HN1 已激活
S97PP4AU 已激活
HE830CXE 已激活
I2ODIZ9M 已激活
CCLLI44L 已激活
MLNM7A0J 已激活
BB2HDWAE 已激活
MLS3IYRN 已激活
9LL7XO6G 已激活
WDIE546J 已激活
96OSOHQT 已激活
EDJ182QW 已激活
LUPTYN8S 已激活
OSIF6AYZ 已激活
BED56SSX 已激活
2M7GCFDZ 已激活
CSDP4RGF 已激活
YIMVWMDB 已激活
HFZAHFQV 已激活
1ZP0HMH5 已激活
HHF0R59D 已激活
8QPRC46N 已激活
G9GAKQ1V 已激活
VN8YCOSM 已激活
BKIE162P 已激活
K4U0ALR0 已激活
ZEC6EJN8 已激活
8LFS25M2 已激活
CGGCT0JK 已激活
33XCKI66 已激活
N32IX2ED 已激活
5BM48I2I 已激活
XJ8YJ9BQ 已激活
FG677MC8 已激活
CPQAI352 已激活
3FL0OJ28 已激活
FQQ6GR3O 已激活
HZX6TK2L 已激活
HEVFPIR7 已激活
BOLFJACA 已激活
7R7NYYSU 已激活
MZRZF6OO 已激活
N65LQH12 已激活
XH8QCFBT 已激活
🔲 ☆

Midscene.js:AI驱动的自动化测试工具

字节有一个很实用但不怎么火的项目,叫 Midscene.js,Chrome 商店上的安装数仅有 1 万,它是一个由多模态模型驱动的前端自动化测试插件。

Midscene.js 一共就三大 API:Action、Query、Assert

Action 交互

描述步骤并执行交互。例如,在 GitHub 上交互:查找 GitHub 上的 Twikoo 项目,点进详情页,点个 Star——

Query 提取

从 UI 中“理解”并提取数据,返回值是 JSON 格式,想要什么数据结构,它都可以给你。例如,在面试题宝典网站上提取:string[],所有面试题目——

Assert 断言

判断是否符合指定条件。例如,在智能家庭页面断言:电脑是关着的——

大模型支持情况

项目最初仅支持 GPT-4o 模型,跑一行用例的成本在 ¥0.1 左右,还挺贵的,后来支持了 Qwen-2.5-VL 和 UI-TARS,成本就大幅降低了。以下就以千问模型为例,带领大家上手这个神奇的插件。

安装

可以直接从 Chrome 商店安装:
https://chromewebstore.google.com/detail/midscene/gbldofcpkknbggpkmbdaefngejllnief

配置

从浏览器右上角的插件菜单中打开 Midscene.js 的侧边栏,会提示 No config,点击按钮会弹出 Env Config 的设置框,在里面配置以下变量

1
2
3
4
OPENAI_BASE_URL="https://dashscope.aliyuncs.com/compatible-mode/v1"
OPENAI_API_KEY="sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
MIDSCENE_MODEL_NAME="qwen-vl-max-latest"
MIDSCENE_USE_QWEN_VL=1

其中的 OPENAI_API_KEY 需要你自己申请,申请的地址是:
https://bailian.console.aliyun.com/?apiKey=1#/api-key

以上链接不包含推广,如果你是首次开通阿里云百炼,新用户是有免费额度的,请注意额度的有效期,避免浪费~

测试

接下来用自然语言随便写一条指令,点击 Run 按钮,见证 AI 开始接管你的浏览器……

代码集成

接下来我们尝试编写爬虫,组合这三大 API,完成复杂的自动化任务。

建一个新的 Node.js 项目,安装所需的依赖——

1
pnpm install @midscene/web tsx --save-dev

编写脚本 main.ts,执行你想要进行的操作,例如,打开必应,输入 iMaeGoo 点击搜索,并输出搜索结果——

main.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import { AgentOverChromeBridge } from "@midscene/web/bridge-mode";

function sleep(ms: number) {
return new Promise((r) => setTimeout(r, ms));
}

async function main() {
process.env.OPENAI_BASE_URL =
"https://dashscope.aliyuncs.com/compatible-mode/v1";
process.env.OPENAI_API_KEY = "sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
process.env.MIDSCENE_MODEL_NAME = "qwen-vl-max-latest";
process.env.MIDSCENE_USE_QWEN_VL = 1;
const agent = new AgentOverChromeBridge();
// 这个方法将连接到你的桌面 Chrome 的新标签页
// 记得启动你的 Chrome 插件,并点击 'allow connection' 按钮。否则你会得到一个 timeout 错误
await agent.connectNewTabWithUrl("https://www.bing.com");
// 这些方法与普通 Midscene agent 相同
await agent.ai("输入 iMaeGoo 点击搜索");
const result = await agent.aiQuery(
"{title: string, url: string}[], 搜索结果"
);
console.log("搜索结果", result);
await sleep(3000);
await agent.destroy();
}

main();

启动你的 Chrome 插件,点击 Bridge Mode,再点击 ‘Allow connection’ 按钮——

随后运行脚本——

1
pnpx tsx main.ts

可以看到脚本成功打开必应搜索 iMaeGoo 并打印出了搜索结果——

🔲 ⭐

仅需两个文件,实现在 VS Code 状态栏监控黄金价格

最近金价波动剧烈,要是能一边写代码,一边实时监控金价变动,就不会错过高低点了!

C:\Users\你的用户名\.vscode\extensions 新建文件夹 gold-monitor,在文件夹中创建两个文件 package.jsonextension.js

package.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
"name": "jd-gold-price-monitor",
"displayName": "JD Gold Price Monitor",
"description": "Monitor gold price from JD",
"version": "0.0.3",
"author": "iMaeGoo",
"publisher": "iMaeGoo",
"engines": {
"vscode": "^1.85.0"
},
"categories": [
"Other"
],
"activationEvents": [
"onStartupFinished"
],
"main": "./extension.js",
"contributes": {
"commands": [
{
"command": "gold-price-monitor.start",
"title": "Start Gold Price Monitor"
}
]
}
}
extension.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
const vscode = require("vscode");

let statusBarItem;
let intervalId;

function activate(context) {
// 创建状态栏项
statusBarItem = vscode.window.createStatusBarItem(
// 在状态栏左半边显示
vscode.StatusBarAlignment.Left,
// 数字越大,越靠左
-999
);
context.subscriptions.push(statusBarItem);

// 注册命令
let disposable = vscode.commands.registerCommand(
"gold-price-monitor.start",
() => {
startMonitoring();
}
);

context.subscriptions.push(disposable);

// 激活时自动开始监控
startMonitoring();
}

async function updateGoldPrice() {
try {
const price = await getPrice();
statusBarItem.text = price;
statusBarItem.show();
} catch (error) {
console.error("获取价格失败", error);
statusBarItem.text = error.message;
statusBarItem.show();
}
}

async function getPrice() {
// 获取京东金融民生银行积存金价
const response = await fetch(
"https://api.jdjygold.com/gw/generic/hj/h5/m/latestPrice?reqData={}"
);
const data = await response.json();
const price = data.resultData.datas.price;
return price;
}

function startMonitoring() {
// 清除现有的定时器
if (intervalId) {
clearInterval(intervalId);
}

// 立即更新一次
updateGoldPrice();

// 设置定时器,每隔 6666 毫秒更新一次
intervalId = setInterval(updateGoldPrice, 6666);
}

function deactivate() {
if (intervalId) {
clearInterval(intervalId);
}
}

module.exports = {
activate,
deactivate,
};

重新启动 VS Code(Ctrl + Shift + P,输入 reload window,回车)即可看到效果。

如果你想监测其他品牌金价,可以修改 getPrice 方法,具体实现如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
async function zheshang() {
// 获取京东金融浙商银行积存金价
const response = await fetch(
"https://api.jdjygold.com/gw2/generic/jrm/h5/m/stdLatestPrice?productSku=1961543816"
);
const data = await response.json();
const price = data.resultData.datas.price;
return price;
}

async function zhoushengsheng() {
// 获取周生生首饰金价
try {
const res = await fetch("https://cn.chowsangsang.com/gold-info");
const data = await res.text();
const gold_data_match = data.match(/:gold_data='(.*)'/);
const gold_data = gold_data_match
? JSON.parse(decode(gold_data_match[1]))
: [];
const price = gold_data.find(
(i: any) => i.description === "黄金金价"
).price;
return price;
} catch (e) {
console.error("zhoushengsheng", e);
}
}

async function laofengxiang() {
// 获取老凤祥首饰金价
const res = await fetch("http://lfx1848.com");
const data = await res.text();
const price_match = data.match(/<span id="labContent">(.*)<\/span>/);
const price = price_match ? price_match[1] : "";
return price;
}

async function zhouliufu() {
// 获取周六福首饰金价
const res = await fetch("https://price.zlf.cn/index_35.aspx");
const data = await res.text();
const price_match = data.match(/<span class="fr">(.*)<\/span>/);
const price = price_match ? price_match[1] : "";
return price;
}

async function liufuzhubao() {
// 获取六福珠宝首饰金价
const res = await fetch("https://www.lukfookeshop.com.cn");
const data = await res.text();
const price_match = data.match(/>:(.*?)元\/克/);
const price = price_match ? price_match[1] : "";
return price;
}

async function zhoudafu() {
// 获取周大福首饰金价
const res = await fetch(
`https://api2.ctfmall.com/gateway//ctfmall-common2-server/common/ctfTodayGoldPrice?timestamp=${Date.now()}`
);
const data: any = await res.json();
const price = data.data.todayPriceHK;
return price;
}

async function laomiao() {
// 获取老庙首饰金价
const res = await fetch(
"https://vip.laomiao.com.cn/index.php/m/home-gold_price.html"
);
const data: any = await res.json();
const price = data.data.price_list.find(
(i: any) => i.name === "足金饰品"
).price;
return parseInt(price);
}
🔲 ☆

Android 14 APP 全屏代码实现

新的 Android API 改变了应用全屏的方式,网上搜到的全屏代码都不管用了,甚至 谷歌自己的教程 都没有更新,看了 API 文档才研究明白最新代码怎么写。本篇讲述两种新的全屏方式,一种保留状态栏文字的全屏,一种隐藏状态栏的全屏。

保留状态栏,适配全面屏

默认情况下,应用界面不会延伸到系统状态栏、导航栏、导航条等区域,这会很丑,要想适配全面屏显示,在 Android 14 中,可以用一行代码简单实现。

1
2
3
// import androidx.activity.enableEdgeToEdg

enableEdgeToEdge()

隐藏状态栏,完全全屏

适配全面屏并不会隐藏系统状态栏、导航栏、导航条,如果想实现完全全屏,老办法一般是调用 setSystemUiVisibility(),然而这个方法在 14 中已经弃用了,获取 InsetsControllerViewCompat.getWindowInsetsController() 方法也被弃用了,最新的写法是:

1
2
3
4
5
6
7
8
9
// import androidx.core.view.WindowCompat
// import androidx.core.view.WindowInsetsCompat
// import androidx.core.view.WindowInsetsControllerCompat

val windowController = WindowCompat.getInsetsController(window, window.decorView)
// 应用全屏时,用户仍然可以从屏幕顶部下拉唤出状态栏,此行代码实现当用户唤出状态栏后,自动隐藏状态栏
windowController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
// 隐藏包括状态栏、导航栏、caption bar 在内的所有系统栏
windowController.hide(WindowInsetsCompat.Type.systemBars())
🔲 ⭐

前端人的 Python、Conda 环境搭建

前言

许多 AI 相关的项目、游戏辅助工具都使用 Python 语言开发,迫使我开始接触 Python 的环境搭建。作为一个前端人,我已经对 Node.js、NVM、NPM 等工具再熟悉不过了,但搭建 Python 的过程中还是碰到了不少困难,在此记录一下,让和我一样的前端人能更快地理解 Python 的生态体系。

Python 生态

  • Python: Python 解释器和运行时环境,对应前端体系中的 Node.js,官网 www.python.org
  • Pip: Python 的包管理工具,对应前端体系中的 NPM,官网 pypi.org
  • Conda: 用于管理 Python 环境,对应前端体系中的 NVM,但又略有区别

NPM 在安装项目依赖时,会安装在项目的 node_modules 目录下,也就是局部安装,各个项目之间互相不影响,而 Pip 则是默认装在全局,这和前端的思维不一致。装在全局会造成多个项目的管理不便,各个项目之间依赖冲突、相同依赖的不同版本无法同时存在。

为了解决这个问题,Conda 就出现了,它可以创建完全隔离的多个不同的 Python 环境,每个环境可以指定不同的 Python 版本,每个环境所安装的依赖也相互隔离。

环境安装

为了搭建 Python 环境,新手往往会先想到安装 Python,但实际上 Conda 已经内置了 Python,我们 只需要安装一个 Conda,就完成环境安装了。

Conda 有三个发行的安装包,分别是 Anaconda、Miniconda、Miniforge,其中 Anaconda 最出名,它已经内置了数千个常用的科学计算依赖包,属于是开箱即用,但缺点是安装包体积达到了惊人的 912 MB。

Miniconda 就比较小巧了,它没有内置常用依赖,体积也降到了 85 MB,对于我这种需求不高的用户,显然更合适。

  1. 下载 Miniconda: https://docs.anaconda.com/miniconda/#latest-miniconda-installer-links
  2. 安装时有一步 Advanced Installation Options,建议选中 “Clear the package cache upon completion”,可以节省部分硬盘空间

修改软件源

和 NPM 一样,默认的国外软件源在国内是无法流畅使用的。我们需要在用户根目录(C:\Users\你的用户名)创建一个 .condarc 文件,输入以下内容来切换成国内源

1
2
3
4
5
6
7
8
channels:
- defaults
show_channel_urls: true
default_channels:
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch

修改环境位置

如果你不想让以后安装的依赖占用 C 盘的空间,还需要提前修改环境位置,在上一步的 .condarc 文件中增加两行

1
2
envs_dirs:
- D:\dev\condaenvs

环境创建

在开始中搜索 “anaconda”,找到 “Anaconda Prompt (miniconda3)” 并打开,然后执行

1
conda create -n 环境名称 python=3.12 -y

替换命令中的环境名称为你定义的环境名称,替换命令中的 3.12 为你需要的 Python 版本

这样就完成环境的创建了,执行 conda env list 可以查看环境列表

环境切换

仍然是在 Anaconda Prompt 中执行

1
conda activate 环境名称

这样就切换到了对应的环境中

依赖安装

仍然是在 Anaconda Prompt 中执行

1
2
cd /d 项目目录
pip install -r requirements.txt

注意 -r 后跟项目依赖声明文件,有可能叫 requirements.txt,也有可能叫 requirements-prod.txt,之类的

安装好依赖后,就可以启动项目啦!具体如何启动可以参考项目的 README 文件。

在 bat 中切换 Conda 环境

有时候我们需要编写 bat 脚本来执行一些自动化任务(例如定时执行),这时我们会发现,由于脚本执行时没有切换到指定的 Conda 环境中,会报 Python 找不到的错误。怎样在 bat 脚本中切换 Conda 环境呢?

1
2
3
4
5
@echo off
cd /d 项目目录
call D:\dev\anaconda3\Scripts\activate.bat D:\dev\anaconda3
call conda activate 环境名称
python 项目主入口.py

替换命令中的 D:\dev\anaconda3 为你的 Conda 安装路径,替换最后一行命令为项目的启动命令

配置 PyCharm

如果你和我一样在用 PyCharm 开发工程,还需要在其中配置工程所使用的 Conda 环境

  1. 在 PyCharm 中打开工程
  2. 打开 文件-设置-项目-Python 解释器-添加解释器-添加本地解释器

  1. 选择 Conda 环境,选择 conda.exe 所在位置,然后选择刚才创建好的环境,然后确定

  1. 回到设置窗口选择刚刚添加好的解释器,大功告成
❌