<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <author>
    <name>btjawa</name>
  </author>
  <generator uri="https://hexo.io/">Hexo</generator>
  <id>https://blog.btjawa.top/</id>
  <link href="https://blog.btjawa.top/" rel="alternate"/>
  <link href="https://blog.btjawa.top/atom.xml" rel="self"/>
  <rights>All rights reserved 2026, btjawa</rights>
  <subtitle>btjawa's simple blog.</subtitle>
  <title>btjawa's Blog</title>
  <updated>2025-08-05T16:00:00.000Z</updated>
  <entry>
    <author>
      <name>btjawa</name>
    </author>
    <category term="Vue" scheme="https://blog.btjawa.top/tags/Vue/"/>
    <category term="Typescript" scheme="https://blog.btjawa.top/tags/Typescript/"/>
    <content>
      <![CDATA[<p>众所周知，Vue 是一个极其庞大的框架库</p><p>以前我们用下面的语句来拓展全局属性</p><figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">declare</span> <span class="variable language_">module</span> <span class="string">&#x27;@vue/runtime-core&#x27;</span> &#123;&#125;</span><br></pre></td></tr></table></figure><p>但是这样做会搞坏其他属性的类型，你就能看到一大堆 <code>does not exist</code> 了</p><p>于是，现在 Vue docs 推荐使用</p><figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">declare</span> <span class="variable language_">module</span> <span class="string">&#x27;vue&#x27;</span> &#123;&#125;</span><br></pre></td></tr></table></figure><p>但是这样就会发现拓展的属性没有类型提示（变 <code>any</code>）了</p><p>经过一系列的网上冲浪，终于在 <a href="https://github.com/vuejs/pinia">pinia</a> 的类型定义里翻到了下面的这种方法</p><figure class="highlight ts"><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="keyword">declare</span> <span class="variable language_">module</span> <span class="string">&#x27;vue&#x27;</span> &#123;</span><br><span class="line">    <span class="keyword">interface</span> <span class="title class_">GlobalComponents</span> &#123;&#125;</span><br><span class="line">    <span class="keyword">interface</span> <span class="title class_">ComponentCustomProperties</span> &#123;</span><br><span class="line">        <span class="comment">// properties here</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// normally this is only needed in .d.ts files</span></span><br><span class="line"><span class="keyword">export</span> &#123;&#125;</span><br></pre></td></tr></table></figure><p>这样就可以让ts编译器屈服于你了</p>]]>
    </content>
    <id>https://blog.btjawa.top/posts/vue-typesafe-global-extend/</id>
    <link href="https://blog.btjawa.top/posts/vue-typesafe-global-extend/"/>
    <published>2025-08-05T23:17:23.000Z</published>
    <summary>
      <![CDATA[<p>众所周知，Vue 是一个极其庞大的框架库</p>
<p>以前我们用下面的语句来拓展全局属性</p>
<figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</s]]>
    </summary>
    <title>Vue 3 + Typescript 拓展全局属性</title>
    <updated>2025-08-05T16:00:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>btjawa</name>
    </author>
    <category term="中二节奏" scheme="https://blog.btjawa.top/tags/%E4%B8%AD%E4%BA%8C%E8%8A%82%E5%A5%8F/"/>
    <category term="ESP32" scheme="https://blog.btjawa.top/tags/ESP32/"/>
    <category term="工具" scheme="https://blog.btjawa.top/tags/%E5%B7%A5%E5%85%B7/"/>
    <content>
      <![CDATA[<p><em>这应该不算教程，只是分享一些思路</em></p><h2 id="前言">前言</h2><p>之前用 ESP32-S3-DEVKIT 做过中二的 Aime 读卡器，固件是用下面这个项目改的</p><div class="tag link"><a class="link-card" title="Sucareto/Arduino-Aime-Reader" href="https://github.com/Sucareto/Arduino-Aime-Reader"><div class="left"><img src="https://github.com/fluidicon.png" class="lazyload" data-srcset="https://github.com/fluidicon.png" srcset="data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="/></div><div class="right"><p class="text">Sucareto/Arduino-Aime-Reader</p><p class="url">https://github.com/Sucareto/Arduino-Aime-Reader</p></div></a></div><p>端午闲来无事，觉得之前做的读卡器体积太大了，决定重新做一版，顺便试试固件自己写</p><p>固件已开源</p><div class="tag link"><a class="link-card" title="btjawa/ESP32-CardReader" href="https://github.com/btjawa/ESP32-CardReader"><div class="left"><img src="https://github.com/fluidicon.png" class="lazyload" data-srcset="https://github.com/fluidicon.png" srcset="data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="/></div><div class="right"><p class="text">btjawa/ESP32-CardReader</p><p class="url">https://github.com/btjawa/ESP32-CardReader</p></div></a></div><h2 id="硬件">硬件</h2><ul><li>Elechouse PN532</li></ul><p>NFC 收发模块，用来和卡片交互</p><ul><li>ESP32</li></ul><p>主控，这次选择了 <a href="https://www.nologo.tech/product/esp32/esp32c3/esp32c3supermini/esp32C3SuperMini.html">ESP32C3 Supermini</a><br>体积足够小，半孔工艺可以当贴片处理，以及GPIO刚刚好可以用完</p><ul><li>SSD1306</li></ul><p>OLED 显示屏，用来显示读卡器模式以及读卡状态</p><ul><li>若干 WS2812B + 若干开关</li></ul><p>开关用来切换模式，WS2812B 装饰</p><ul><li>接线</li></ul><div class="note warning"><p><code>0</code>, <code>8</code>, <code>20</code>, <code>21</code> 这四个引脚不要接</p></div><p>每个模块按他们的协议接线，PN532 用SPI，SSD1306 用I²C<br>WS2812B 由于用了级联，所以只需要接第一个LED的DIN<br>开关接那些下拉不会导致主控出问题的引脚 (例如 <code>1</code>, <code>2</code>)</p><ul><li>原理图</li></ul><div class="img-wrap"><div class="img-bg"><img class="img lazyload" src="/img/posts/aime-cardreader/schematic.png" class="lazyload" data-srcset="/img/posts/aime-cardreader/schematic.png" srcset="data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="原理图"/></div><span class="image-caption">原理图</span></div><p>PCB 新版全部用了贴片，之前做的的全是插件，PCB 背面不太美观还割手</p><h2 id="软件">软件</h2><p><strong>具体实现可以查看 <a href="https://github.com/btjawa/ESP32-CardReader/blob/main/src/sega.cpp">src/sega.cpp</a>，这里只大致讲讲处理的逻辑</strong></p><p>用 <code>PlatformIO</code> + <code>arduino</code> framework<br>由于 ESP32C3 Supermini 没有串口转USB以及自动下载电路<br>所以需要手动进入下载模式，用USB CDC上传固件 (实测只有第一次上传需要手动进入下载模式，之后就不用了)</p><p>串口交互逻辑来自 <a href="https://github.com/djhackersdev/segatools">segatools</a> 模拟层<br>串口波特率需要根据 <code>segatools.ini -&gt; keychip -&gt; dipsw3</code> 动态设置<br>如果是 CVT -&gt; <code>38400</code>，否则 <code>115200</code></p><h3 id="请求帧">请求帧</h3><p>游戏默认通过 COM4 与读卡器通信，每次需要让读卡器做些什么时就会发送一个请求帧 (req_frame)<br>样本：<code>E0 05 00 02 30 00 37</code></p><ul><li><code>0xE0</code> -&gt; 同步字节</li><li><code>0x05</code> -&gt; 帧长度 (包含自身)</li><li><code>0x00</code> -&gt; 地址</li><li><code>0x02</code> -&gt; 序号，代表第 n+1 个请求帧</li><li><code>0x30</code> -&gt; CMD</li><li><code>0x00</code> -&gt; Payload 长度 (不包含自身)</li><li><code>....</code> -&gt; 如果 Payload 长度大于零，这里就会出现与 <code>Payload 长度</code> 相同数量的字节 (Payload Body)</li><li><code>0x37</code> -&gt; 校验值，除其自身与同步字节外其他字节的和 (<code>0x05</code> + <code>0x02</code> + <code>0x30</code> = <code>0x37</code>)</li></ul><div class="note info blue"><p><code>0xD0</code> 为转义字节，需要转义，流程为：忽略 <code>0xD0</code>，读取下一个字节并 +1<br> 例：<code>D0 DF</code>，转义后的字节为：<code>0xDF</code> + 1 = 0xE0<br> 如果转义后的字节为 <code>0xE0</code>，那么它不应再被视为同步字节</p></div><p>如果直接用 <code>Windows API</code> 的话，我们可以读到一个完整的帧 (<code>IRQ_MJ_WRITE</code>)<br>但是 Arduino 不行，所以我们只能按照上述含义用 <code>Serial.read()</code> 一个个读</p><h3 id="处理-CMD">处理 CMD</h3><p>CMD 字节就是这个指令的类型，映射表可以查看 <a href="https://github.com/btjawa/ESP32-CardReader/blob/main/src/sega.h">src/sega.h</a></p><p><code>...?</code> 即代表不确定</p><ul><li><code>0x30</code> -&gt; 返回固件版本</li><li><code>0x32</code> -&gt; 返回硬件版本</li><li><code>0x40</code> -&gt; 开启射频天线…?</li><li><code>0x41</code> -&gt; 关闭射频天线…?</li><li><code>0x42</code> -&gt; 开始轮询卡片，Mifare 返回 UID 长度与 UID，Felica 返回 IDm, PMm 与各自的长度</li></ul><div class="note warning"><p>此处注意，因为主线程是<strong>同步</strong>的，所以单次轮询读取的超时时间应该控制在 500ms 以内以防阻塞</p></div><ul><li><code>0x43</code> -&gt; 根据接收帧的 Payload 选择对应 UID 的 Mifare 卡片</li><li><code>0x44</code> -&gt; 未知</li><li><code>0x50</code> -&gt; Payload 为与 Aime 卡交互所需的 Key，储存</li><li><code>0x51</code> -&gt; 用上述 Aime Key 认证</li><li><code>0x52</code> -&gt; 读取 Mifare Block (一定发生在 Key 验证后)</li><li><code>0x54</code> -&gt; Payload 为与 Bana 卡交互所需的 Key，储存</li><li><code>0x55</code> -&gt; 用上述 Bana Key 认证</li><li><code>0x60</code> -&gt; 进入升级模式…?</li><li><code>0x61</code> -&gt; 发送数据…?</li><li><code>0x62</code> -&gt; 重置设备…?</li><li><code>0x71</code> -&gt; 用 Payload 中提供的命令请求 Felica 卡片，并返回卡片处理的结果</li><li><code>0x81</code> -&gt; 用 Payload 提供的颜色 (三个字节，对应 RGB) 设置 LED 灯</li><li><code>0xF5</code> -&gt; 重置 LED 灯</li><li><code>0xF0</code> -&gt; 返回 LED 灯版本</li></ul><h3 id="回复帧">回复帧</h3><p>处理完请求帧后，我们自然也需要构建回复帧 (res_frame)<br>这里的样本也对应上述请求帧的样本<br>样本：<code>E0 07 00 02 30 00 01 94 ce</code><br>结构基本与请求帧保持一致，只是：</p><ul><li><code>CMD</code> 后新增一个字节，对应响应状态：</li></ul><div class="note info blue"><p><code>0x00</code> -&gt; 成功<br> <code>0x01</code> -&gt; 失败 (游戏默认会重试，可以善用这个机制)<br> 其他字节意义不明</p></div><ul><li>请求帧中的 <code>Payload 长度</code>, <code>Payload Body</code> 在此处变为返回的 Payload：<br>上文中提到的 “返回xxx” 就是指填充此处数据，在样本中对应 <code>0x01</code>, <code>0x94</code></li></ul><p>然后将构建好的回复依次写回串口</p><h2 id="后记">后记</h2><p>WS2812B 在级联灯比较少的情况下用 <code>3.3v</code> 供电也能跑起来，还挺稳定的，就是不知道寿命了</p><p>看着一条条请求帧被正确回复真是有很大的成就感</p>]]>
    </content>
    <id>https://blog.btjawa.top/posts/aime-cardreader/</id>
    <link href="https://blog.btjawa.top/posts/aime-cardreader/"/>
    <published>2025-06-01T16:00:00.000Z</published>
    <summary>
      <![CDATA[<p><em>这应该不算教程，只是分享一些思路</em></p>
<h2 id="前言">前言</h2>
<p>之前用 ESP32-S3-DEVKIT 做过中二的 Aime 读卡器，固件是用下面这个项目改的</p>
<div class="tag link"><a class="]]>
    </summary>
    <title>自制 Aime 读卡器</title>
    <updated>2025-06-15T16:00:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>btjawa</name>
    </author>
    <category term="Tauri" scheme="https://blog.btjawa.top/tags/Tauri/"/>
    <category term="Rust" scheme="https://blog.btjawa.top/tags/Rust/"/>
    <content>
      <![CDATA[<p>Rust 下通过配置 Job Object 实现在主进程退出时自动清理创建的子进程</p><span id="more"></span><p>之前写 Tauri 应用（没错就是<a href="https://github.com/btjawa/bilitools">BiliTools</a>）时，需要在后台挂个 aria2c 实现多线程下载</p><p>然后发现很尴尬这玩意不会跟着应用退出而退出（理所当然）</p><p>本来想的是写一个结构体，存 Child，然后监听窗口关闭事件 <code>tauri::WindowEvent::Destroyed</code>，调用函数把进程杀了</p><p>这种方法能用是能用吧，但是如果 Panic，非正常关闭，应用更新什么的就会比较麻烦</p><p>不如找个一劳永逸的方法，就不用到处设 hook 监听退出了</p><h2 id="方案一">方案一</h2><p>这种方法 macOS / 其他Linux发行版 / Windows 都适用</p><p>就是运行一个监控脚本，传递主进程 PID 和子进程 PID</p><p>脚本定期检查主进程是否退出，一旦退出就杀掉指定子进程</p><p>这种方法的坏处就是需要在每个运行子进程的地方都设置一个监控</p><h3 id="Windows">Windows</h3><figure class="highlight powershell"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">param</span>(<span class="variable">$a</span>,<span class="variable">$b</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">while</span> ((<span class="built_in">Get-Process</span> <span class="literal">-Id</span> <span class="variable">$a</span> <span class="literal">-ErrorAction</span> SilentlyContinue) <span class="operator">-ne</span> <span class="variable">$null</span>) \</span><br><span class="line">&#123;&#123; <span class="built_in">Start-Sleep</span> <span class="literal">-Milliseconds</span> <span class="number">500</span> &#125;&#125;; <span class="built_in">Stop-Process</span> <span class="literal">-Id</span> <span class="variable">$b</span> <span class="literal">-Force</span></span><br></pre></td></tr></table></figure><p>实践：</p><figure class="highlight rust"><figcaption><span>main.rs</span></figcaption><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">use</span> std::process::&#123;Command, <span class="keyword">self</span>&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">fn</span> <span class="title function_">main</span>() <span class="punctuation">-&gt;</span> <span class="type">Result</span>&lt;(), <span class="type">Box</span>&lt;<span class="keyword">dyn</span> std::error::Error&gt;&gt;  &#123;</span><br><span class="line">    <span class="keyword">let</span> <span class="variable">child</span> = Command::<span class="title function_ invoke__">new</span>(<span class="string">&quot;aria2c&quot;</span>).<span class="title function_ invoke__">spawn</span>()?;</span><br><span class="line">    <span class="keyword">let</span> <span class="variable">child_id</span> = child.<span class="title function_ invoke__">id</span>();</span><br><span class="line">    <span class="keyword">let</span> <span class="variable">main_id</span> = process::<span class="title function_ invoke__">id</span>();</span><br><span class="line"></span><br><span class="line">    Command::<span class="title function_ invoke__">new</span>(<span class="string">&quot;powershell.exe&quot;</span>)</span><br><span class="line">        .<span class="title function_ invoke__">arg</span>(<span class="string">&quot;-Command&quot;</span>)</span><br><span class="line">        .<span class="title function_ invoke__">arg</span>(<span class="built_in">format!</span>(</span><br><span class="line">            <span class="string">&quot;while ((Get-Process -Id &#123;&#125; -ErrorAction SilentlyContinue) -ne $null) \</span></span><br><span class="line"><span class="string">            &#123;&#123; Start-Sleep -Milliseconds 500 &#125;&#125;; Stop-Process -Id &#123;&#125; -Force&quot;</span>, </span><br><span class="line">            main_id, child_id))</span><br><span class="line">        .<span class="title function_ invoke__">spawn</span>()?;</span><br><span class="line"></span><br><span class="line">    <span class="title function_ invoke__">Ok</span>(())</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="macOS-其他Linux发行版">macOS / 其他Linux发行版</h3><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">while</span> <span class="built_in">kill</span> -0 <span class="variable">$1</span> 2&gt;/dev/null; <span class="keyword">do</span> <span class="built_in">sleep</span> 0.5; <span class="keyword">done</span>; <span class="built_in">kill</span> <span class="variable">$2</span></span><br></pre></td></tr></table></figure><p>实践：</p><figure class="highlight rust"><figcaption><span>main.rs</span></figcaption><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"><span class="keyword">use</span> std::process::&#123;Command, <span class="keyword">self</span>&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">fn</span> <span class="title function_">main</span>() <span class="punctuation">-&gt;</span> <span class="type">Result</span>&lt;(), <span class="type">Box</span>&lt;<span class="keyword">dyn</span> std::error::Error&gt;&gt;  &#123;</span><br><span class="line">    <span class="keyword">let</span> <span class="variable">child</span> = Command::<span class="title function_ invoke__">new</span>(<span class="string">&quot;aria2c&quot;</span>).<span class="title function_ invoke__">spawn</span>()?;</span><br><span class="line">    <span class="keyword">let</span> <span class="variable">child_id</span> = child.<span class="title function_ invoke__">id</span>();</span><br><span class="line">    <span class="keyword">let</span> <span class="variable">main_id</span> = process::<span class="title function_ invoke__">id</span>();</span><br><span class="line"></span><br><span class="line">    Command::<span class="title function_ invoke__">new</span>(<span class="string">&quot;/bin/bash&quot;</span>)</span><br><span class="line">        .<span class="title function_ invoke__">arg</span>(<span class="string">&quot;-c&quot;</span>)</span><br><span class="line">        .<span class="title function_ invoke__">arg</span>(<span class="built_in">format!</span>(</span><br><span class="line">            <span class="string">&quot;while kill -0 &#123;&#125; 2&gt;/dev/null; do sleep 0.5; done; kill &#123;&#125;&quot;</span>, <span class="comment">// do sleep 后跟着的就是定期检查的间隔时间</span></span><br><span class="line">            main_id, child_id))</span><br><span class="line">        .<span class="title function_ invoke__">spawn</span>()?;</span><br><span class="line"></span><br><span class="line">    <span class="title function_ invoke__">Ok</span>(())</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="方案二（仅适用-Windows）">方案二（仅适用 Windows）</h2><p>WinAPI 下有个叫 <code>Job Object / 作业对象</code> 的东西，可以关联进程，从而实现退出时终止与作业关联的所有进程</p><div class="tag link"><a class="link-card" title="Job Objects - Win32 apps | Microsoft Learn" href="https://learn.microsoft.com/en-us/windows/win32/procthread/job-objects"><div class="left"><img src="https://learn.microsoft.com/favicon.ico" class="lazyload" data-srcset="https://learn.microsoft.com/favicon.ico" srcset="data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="/></div><div class="right"><p class="text">Job Objects - Win32 apps | Microsoft Learn</p><p class="url">https://learn.microsoft.com/en-us/windows/win32/procthread/job-objects</p></div></a></div><p>Rust 中有两种方式实现它：</p><ul><li><a href="https://crates.io/crates/winapi">Crate winapi</a> 自己用 winapi 写，工程量比较大</li><li><a href="https://github.com/ohadravid/win32job-rs">Crate win32job</a> GitHub 上有人封装了作业对象的 api，可以直接用</li></ul><p>下面是 <code>win32job</code> 的示例</p><figure class="highlight rust"><figcaption><span>main.rs</span></figcaption><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"><span class="keyword">use</span> win32job::Job;</span><br><span class="line"><span class="keyword">use</span> std::process::Command;</span><br><span class="line"></span><br><span class="line"><span class="keyword">fn</span> <span class="title function_">main</span>() <span class="punctuation">-&gt;</span> <span class="type">Result</span>&lt;(), <span class="type">Box</span>&lt;<span class="keyword">dyn</span> std::error::Error&gt;&gt;  &#123;</span><br><span class="line">    <span class="keyword">let</span> <span class="variable">job</span> = Job::<span class="title function_ invoke__">create</span>()?;</span><br><span class="line">    <span class="keyword">let</span> <span class="keyword">mut </span><span class="variable">info</span> = job.<span class="title function_ invoke__">query_extended_limit_info</span>()?;</span><br><span class="line">    info.<span class="title function_ invoke__">limit_kill_on_job_close</span>(); <span class="comment">// 确保当 Job Object 的句柄被关闭时，所有关联的进程都会被终止</span></span><br><span class="line">    job.<span class="title function_ invoke__">set_extended_limit_info</span>(&amp;<span class="keyword">mut</span> info)?;</span><br><span class="line">    job.<span class="title function_ invoke__">assign_current_process</span>()?; <span class="comment">// 让 Job Object 关联进程</span></span><br><span class="line"></span><br><span class="line">    Command::<span class="title function_ invoke__">new</span>(<span class="string">&quot;aria2c.exe&quot;</span>).<span class="title function_ invoke__">spawn</span>()?;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// job 被 drop 或者主进程退出时，aria2c 就会被杀死</span></span><br><span class="line">    </span><br><span class="line">    <span class="title function_ invoke__">Ok</span>(())</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]>
    </content>
    <id>https://blog.btjawa.top/posts/rust-job-object/</id>
    <link href="https://blog.btjawa.top/posts/rust-job-object/"/>
    <published>2024-03-26T18:15:16.000Z</published>
    <summary>
      <![CDATA[<p>Rust 下通过配置 Job Object 实现在主进程退出时自动清理创建的子进程</p>]]>
    </summary>
    <title>Rust 下实现自动清理子进程</title>
    <updated>2025-06-15T16:00:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>btjawa</name>
    </author>
    <category term="黑苹果" scheme="https://blog.btjawa.top/tags/%E9%BB%91%E8%8B%B9%E6%9E%9C/"/>
    <content>
      <![CDATA[<p>记一次黑苹果崩溃 - com.apple.filesystems.lifs</p><span id="more"></span><h2 id="起因">起因</h2><p>装好黑苹果突然心血来潮想在上面用水果（因为一帮人吹 macOS 编曲体验很好）</p><p>安装激活后挂载 NTFS 盘、搜索路径添加挂载路径</p><p>然后点 Find 的时候杯具了，系统卡死，所以只能强制关机再进系统看报错。</p><p>（有时也表现为直接黑屏panic，然后自动重启）</p><h2 id="解决过程">解决过程</h2><div class="img-wrap"><div class="img-bg"><img class="img lazyload" src="/img/posts/hackintosh-panic-lifs/panic.png" class="lazyload" data-srcset="/img/posts/hackintosh-panic-lifs/panic.png" srcset="data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="报错信息"/></div><span class="image-caption">报错信息</span></div><p>从报错来看似乎和 <code>com.apple.filesystems.lifs(1.0)</code> 有关</p><p>维基此文件系统无果，最后在 苹果开发者论坛 找到了这样一篇帖子：</p><div class="tag link"><a class="link-card" title="External drives reported as &quot;lifs&quot;" href="https://forums.developer.apple.com/forums/thread/712310"><div class="left"><img src="https://developer.apple.com/forums/public/assets/favicon.ico" class="lazyload" data-srcset="https://developer.apple.com/forums/public/assets/favicon.ico" srcset="data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="/></div><div class="right"><p class="text">External drives reported as &quot;lifs&quot;</p><p class="url">https://forums.developer.apple.com/forums/thread/712310</p></div></a></div><p>问题看起来是外部驱动器的问题</p><p>我黑苹果的配置是两块 SSD，第一块装 Windows，然后第二块分一块分区出来装 Hackintosh，所以理所当然为了兼容双系统插件音源什么的都装在 NTFS 下</p><p>NTFS 那个分区所在的硬盘尽管是 PCIE 板载，但是因为 macOS 默认只能读而不能写 NTFS 的缘故，估计把它当作外部硬盘了</p><p>所以我的切入点就改为了 “让这块 NTFS 可以读写，就不会被认成所谓 lifs 了”</p><h2 id="解决方案">解决方案</h2><p>一开始去必应 NTFS 读写工具，结果一看都是收费的，免费的也不怎么能用的样子</p><p>所以只剩两个选择</p><h3 id="使用市面上已有的一众-NTFS-读写工具">使用市面上已有的一众 NTFS 读写工具</h3><p>例如：</p><div class="tag link"><a class="link-card" title="Paragon NTFS for Mac" href="https://www.paragon-software.com/home/ntfs-mac"><div class="left"><img src="https://www.paragon-software.com/wp-content/themes/paragon_3_test/icons/apple-touch-icon.png" class="lazyload" data-srcset="https://www.paragon-software.com/wp-content/themes/paragon_3_test/icons/apple-touch-icon.png" srcset="data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="/></div><div class="right"><p class="text">Paragon NTFS for Mac</p><p class="url">https://www.paragon-software.com/home/ntfs-mac</p></div></a></div><del>小心不要进到苏州某企业网站</del><div class="tag link"><a class="link-card" title="NTFSTool" href="https://github.com/ntfstool/ntfstool"><div class="left"><img src="https://cdn.jsdelivr.net/gh/FortAwesome/Font-Awesome/svgs/brands/github.svg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/FortAwesome/Font-Awesome/svgs/brands/github.svg" srcset="data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="/></div><div class="right"><p class="text">NTFSTool</p><p class="url">https://github.com/ntfstool/ntfstool</p></div></a></div><h3 id="自己写脚本">自己写脚本</h3><p>这里使用 <code>ntfs-3g</code>，每次开机运行一下就可以了（脚本调用 sudo，可能会让你输密码）</p><p>使用前需要使用 <code>home-brew</code> 安装：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">brew tap gromgit/homebrew-fuse</span><br><span class="line">brew install ntfs-3g-mac</span><br></pre></td></tr></table></figure><details open><summary> ntfs.sh </summary>              <div class='content'>              <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></pre></td><td class="code"><pre><span class="line"><span class="meta">#!/bin/bash</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">echo</span> <span class="string">&quot;检测所有NTFS磁盘分区...&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 查找所有的NTFS磁盘分区</span></span><br><span class="line">PARTITIONS=$(diskutil list | grep <span class="string">&quot;Microsoft Basic Data&quot;</span> | awk <span class="string">&#x27;&#123;print $NF&#125;&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 第一步：先卸载所有已挂载的NTFS磁盘</span></span><br><span class="line"><span class="keyword">for</span> PARTITION <span class="keyword">in</span> <span class="variable">$PARTITIONS</span>; <span class="keyword">do</span></span><br><span class="line">    INFO=$(diskutil info <span class="variable">$PARTITION</span>)</span><br><span class="line">    DEVICE_NODE=$(<span class="built_in">echo</span> <span class="string">&quot;<span class="variable">$INFO</span>&quot;</span> | grep <span class="string">&quot;Device Node&quot;</span> | awk <span class="string">&#x27;&#123;print $NF&#125;&#x27;</span>)</span><br><span class="line">    <span class="keyword">if</span> [ ! -z <span class="string">&quot;<span class="subst">$(echo <span class="string">&quot;<span class="variable">$INFO</span>&quot;</span> | grep <span class="string">&quot;Mount Point&quot;</span>)</span>&quot;</span> ]; <span class="keyword">then</span></span><br><span class="line">        <span class="built_in">echo</span> <span class="string">&quot;卸载磁盘: <span class="variable">$PARTITION</span>&quot;</span></span><br><span class="line">        <span class="keyword">if</span> ! diskutil unmount <span class="variable">$DEVICE_NODE</span>; <span class="keyword">then</span></span><br><span class="line">            <span class="built_in">echo</span> <span class="string">&quot;卸载磁盘失败，请检查磁盘是否正在使用或其他问题。&quot;</span></span><br><span class="line">            <span class="built_in">exit</span> 1</span><br><span class="line">        <span class="keyword">fi</span></span><br><span class="line">    <span class="keyword">fi</span></span><br><span class="line"><span class="keyword">done</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 第二步：再次遍历并挂载每个NTFS磁盘</span></span><br><span class="line"><span class="keyword">for</span> PARTITION <span class="keyword">in</span> <span class="variable">$PARTITIONS</span>; <span class="keyword">do</span></span><br><span class="line">    INFO=$(diskutil info <span class="variable">$PARTITION</span>)</span><br><span class="line">    VOLUME_NAME=$(<span class="built_in">echo</span> <span class="string">&quot;<span class="variable">$INFO</span>&quot;</span> | grep <span class="string">&quot;Volume Name&quot;</span> | awk <span class="string">&#x27;&#123;for (i=3; i&lt;=NF; i++) printf $i &quot; &quot;; print &quot;&quot;&#125;&#x27;</span>)</span><br><span class="line">    VOLUME_NAME=<span class="string">&quot;<span class="variable">$&#123;VOLUME_NAME%&quot;<span class="variable">$&#123;VOLUME_NAME##*[![:space:]]&#125;</span>&quot;&#125;</span>&quot;</span>  <span class="comment"># 去除尾随空格</span></span><br><span class="line">    DEVICE_NODE=$(<span class="built_in">echo</span> <span class="string">&quot;<span class="variable">$INFO</span>&quot;</span> | grep <span class="string">&quot;Device Node&quot;</span> | awk <span class="string">&#x27;&#123;print $NF&#125;&#x27;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="comment"># 如果Volume Name为空，使用默认名称</span></span><br><span class="line">    <span class="keyword">if</span> [ -z <span class="string">&quot;<span class="variable">$VOLUME_NAME</span>&quot;</span> ]; <span class="keyword">then</span></span><br><span class="line">        VOLUME_NAME=<span class="string">&quot;NTFS Disk&quot;</span></span><br><span class="line">    <span class="keyword">fi</span></span><br><span class="line"></span><br><span class="line">    <span class="comment"># 生成不重复的挂载点名称</span></span><br><span class="line">    MOUNT_DIR=<span class="string">&quot;/Volumes/<span class="variable">$VOLUME_NAME</span>&quot;</span></span><br><span class="line">    SUFFIX=1</span><br><span class="line">    <span class="keyword">while</span> [ -e <span class="string">&quot;<span class="variable">$MOUNT_DIR</span>&quot;</span> ]; <span class="keyword">do</span></span><br><span class="line">        MOUNT_DIR=<span class="string">&quot;/Volumes/<span class="variable">$&#123;VOLUME_NAME&#125;</span> <span class="variable">$&#123;SUFFIX&#125;</span>&quot;</span></span><br><span class="line">        ((SUFFIX++))</span><br><span class="line">    <span class="keyword">done</span></span><br><span class="line"></span><br><span class="line">    <span class="comment"># 使用ntfs-3g挂载磁盘</span></span><br><span class="line">    <span class="built_in">echo</span> <span class="string">&quot;使用 ntfs-3g 挂载磁盘: <span class="variable">$PARTITION</span> (<span class="variable">$DEVICE_NODE</span>) 到 <span class="variable">$MOUNT_DIR</span>&quot;</span></span><br><span class="line">    <span class="built_in">sudo</span> ntfs-3g <span class="variable">$DEVICE_NODE</span> <span class="string">&quot;<span class="variable">$MOUNT_DIR</span>&quot;</span>  -o <span class="built_in">local</span> -o allow_other -o auto_xattr -o auto_cache -o volname=<span class="string">&quot;<span class="subst">$(basename <span class="string">&quot;<span class="variable">$MOUNT_DIR</span>&quot;</span>)</span>&quot;</span></span><br><span class="line"><span class="keyword">done</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">echo</span> <span class="string">&quot;所有NTFS磁盘处理完毕。&quot;</span></span><br></pre></td></tr></table></figure>              </div>            </details><del>感谢 GPT 4.0 支持</del><h2 id="结语">结语</h2><p>这个 panic 甚至可以复现：故意在水果里扫没处理过的 NTFS 盘（</p><p>我目前在用的 EFI：</p><div class="tag link"><a class="link-card" title="btjawa/i513600k-TUF_B660M_WIFI" href="https://github.com/btjawa/i513600k-TUF_B660M_WIFI"><div class="left"><img src="https://cdn.jsdelivr.net/gh/FortAwesome/Font-Awesome/svgs/brands/github.svg" class="lazyload" data-srcset="https://cdn.jsdelivr.net/gh/FortAwesome/Font-Awesome/svgs/brands/github.svg" srcset="data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="/></div><div class="right"><p class="text">btjawa/i513600k-TUF_B660M_WIFI</p><p class="url">https://github.com/btjawa/i513600k-TUF_B660M_WIFI</p></div></a></div>]]>
    </content>
    <id>https://blog.btjawa.top/posts/hackintosh-panic-lifs/</id>
    <link href="https://blog.btjawa.top/posts/hackintosh-panic-lifs/"/>
    <published>2024-03-22T16:00:00.000Z</published>
    <summary>
      <![CDATA[<p>记一次黑苹果崩溃 - com.apple.filesystems.lifs</p>]]>
    </summary>
    <title>记一次黑苹果崩溃</title>
    <updated>2025-06-15T16:00:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>btjawa</name>
    </author>
    <category term="工具" scheme="https://blog.btjawa.top/tags/%E5%B7%A5%E5%85%B7/"/>
    <category term="Tauri" scheme="https://blog.btjawa.top/tags/Tauri/"/>
    <category term="Rust" scheme="https://blog.btjawa.top/tags/Rust/"/>
    <content>
      <![CDATA[<p>💡 一个简约、轻量的哔哩哔哩工具箱，基于 <a href="https://github.com/tauri-apps/tauri">Tauri</a> 构建。</p><span id="more"></span><a class="ghcard" rel="external nofollow noopener noreferrer" href="https://github.com/btjawa/BiliTools"><img src="https://github-readme-stats.xaoxuu.com/api/pin/?username=btjawa&repo=BiliTools&show_owner=true" class="lazyload" data-srcset="https://github-readme-stats.xaoxuu.com/api/pin/?username=btjawa&repo=BiliTools&show_owner=true" srcset="data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="/></a><div class="note link blue"><p>本站文档已迁移，请查看 <a href="https://bilitools.btjawa.top">文档站</a> 或 <a href="https://github.com/btjawa/BiliTools/blob/master/docs">GitHub</a><br> <a href="https://bilitools.btjawa.top/guide/settings.html">设置</a><br> <a href="https://bilitools.btjawa.top/help/">常见问题</a><br> <a href="https://bilitools.btjawa.top/guide/install.html">下载 &amp; 安装</a><br></p></div> <div class="note quote light"><p>本项目基于用户账号解析资源，因此你需要订阅大会员、或是购买对应内容后才能解析对应资源<br> 关于声明请参见 <a href="https://github.com/btjawa/BiliTools?tab=readme-ov-file#%E5%A3%B0%E6%98%8E">README</a></p></div><table><thead><tr><th>暗色</th><th>亮色</th></tr></thead><tbody><tr><td><img src="https://ghfast.top/https://raw.githubusercontent.com/btjawa/BiliTools/12f9385dcea787a19f78103e77568b522ad34a4c/.github/dark.png" class="lazyload" data-srcset="https://ghfast.top/https://raw.githubusercontent.com/btjawa/BiliTools/12f9385dcea787a19f78103e77568b522ad34a4c/.github/dark.png" srcset="data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="Dark"></td><td><img src="https://ghfast.top/https://raw.githubusercontent.com/btjawa/BiliTools/12f9385dcea787a19f78103e77568b522ad34a4c/.github/light.png" class="lazyload" data-srcset="https://ghfast.top/https://raw.githubusercontent.com/btjawa/BiliTools/12f9385dcea787a19f78103e77568b522ad34a4c/.github/light.png" srcset="data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="Light"></td></tr></tbody></table><h2 id="🧪-支持功能">🧪 支持功能</h2><table><thead><tr><th>资源</th><th>状态</th><th>备注</th></tr></thead><tbody><tr><td>视频</td><td>✅ 已完成</td><td><ul><li>支持合集 / 分P / 互动、番剧 / 课程 / 电影</li><li>支持 DASH、MP4、FLV</li><li>支持 4K、8K、HDR、杜比视界</li></ul></td></tr><tr><td>音频</td><td>✅ 已完成</td><td><ul><li>支持 AVC、HEVC、AV1</li><li>支持 杜比全景声、Hi-Res</li></ul></td></tr><tr><td>实时弹幕</td><td>✅ 已完成</td><td><ul><li>ASS / XML 格式</li><li>可解析弹幕池中几乎所有弹幕</li></ul></td></tr><tr><td>历史弹幕</td><td>✅ 已完成</td><td>ASS / XML 格式</td></tr><tr><td>音乐</td><td>✅ 已完成</td><td>支持无损 FLAC、320Kbps 音乐 / 歌单</td></tr><tr><td>封面</td><td>✅ 已完成</td><td>支持番剧 / 电影海报 / 合集封面 / 课程预览等等</td></tr><tr><td>字幕</td><td>✅ 已完成</td><td>SRT 格式</td></tr><tr><td>用户投稿</td><td>✅ 已完成</td><td>支持用户投稿视频 / 图文 / 专栏 / 动态 / 音频</td></tr><tr><td>稍后再看</td><td>✅ 已完成</td><td>支持列表与单项</td></tr><tr><td>收藏夹</td><td>✅ 已完成</td><td>支持任意用户收藏夹</td></tr><tr><td>NFO刮削</td><td>✅ 已完成</td><td>合集/剧集刮削、单集刮削</td></tr><tr><td>元数据</td><td>✅ 已完成</td><td>支持 <code>ID3v2</code> / <code>Vorbis Comments</code></td></tr><tr><td>AI总结</td><td>✅ 已完成</td><td>Markdown格式，来自哔哩哔哩 <code>AI 小助手</code></td></tr></tbody></table><table><thead><tr><th>账号相关</th><th>状态</th></tr></thead><tbody><tr><td>扫码登录</td><td>✅ 已完成</td></tr><tr><td>密码登录</td><td>⚠️ 不稳定</td></tr><tr><td>短信登录</td><td>✅ 已完成</td></tr><tr><td>刷新登录</td><td>✅ 已完成</td></tr><tr><td>参数签名</td><td>✅ 已完成</td></tr><tr><td>风控验证</td><td>✅ 已完成</td></tr><tr><td>指纹验证</td><td>✅ 已完成</td></tr></tbody></table><table><thead><tr><th>其他</th><th>状态</th></tr></thead><tbody><tr><td>明暗主题</td><td>✅ 已完成</td></tr><tr><td>监听剪切板</td><td>✅ 已完成</td></tr><tr><td>HTTP 代理</td><td>✅ 已完成</td></tr><tr><td>过滤 PCDN</td><td>✅ 已完成</td></tr><tr><td>音频转 MP3</td><td>✅ 已完成</td></tr><tr><td>命名格式</td><td>✅ 已完成</td></tr><tr><td>历史记录</td><td>✅ 已完成</td></tr></tbody></table><h2 id="✨-新版本特性">✨ 新版本特性</h2><h3 id="1-4-3-2025-09-24">[1.4.3] - 2025-09-24</h3><h3 id="新增功能">新增功能</h3><ul><li><a href="https://github.com/btjawa/BiliTools/commit/efc3ed670ead3821b6861709a7c01b2451d5539c"><code>efc3ed6</code></a> 支持拖拽并自动搜索哔哩哔哩链接 (<a href="https://github.com/btjawa/BiliTools/issues/183">#183</a>)</li><li><a href="https://github.com/btjawa/BiliTools/commit/b5a760fb8ce05e06283b5c4bc4b06e9d534815c4"><code>b5a760f</code></a> 支持解析用户完整投稿视频列表</li></ul><h3 id="问题修复">问题修复</h3><ul><li><a href="https://github.com/btjawa/BiliTools/commit/d8b09fb5733ea0c15285dc8ea12e68bd55ffe42c"><code>d8b09fb</code></a> 修复数据库迁移与 <code>staff</code> 解析不完整的问题 (<a href="https://github.com/btjawa/BiliTools/issues/182">#182</a>)</li><li><a href="https://github.com/btjawa/BiliTools/commit/78b5f06088f13150f753f7b23055fc4293887b6f"><code>78b5f06</code></a> 修复 Linux 下 Sidecar 的打包策略问题 (<a href="https://github.com/btjawa/BiliTools/issues/182">#182</a>)</li></ul><h2 id="💫-鸣谢">💫 鸣谢</h2><a href="https://github.com/btjawa/BiliTools/graphs/contributors">  <img src="https://contrib.rocks/image?repo=btjawa/BiliTools&max=100" class="lazyload" data-srcset="https://contrib.rocks/image?repo=btjawa/BiliTools&max=100" srcset="data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" /></a><br><a href="https://www.star-history.com/#btjawa/BiliTools&Date" alt="Star History Chart"><picture><source    media="(prefers-color-scheme: dark)"    srcset="https://api.star-history.com/svg?repos=btjawa/BiliTools&type=Date&theme=dark"/><source    media="(prefers-color-scheme: light)"    srcset="https://api.star-history.com/svg?repos=btjawa/BiliTools&type=Date"/><img    alt="Star History Chart"    src="https://api.star-history.com/svg?repos=btjawa/BiliTools&type=Date"/></picture></a>]]>
    </content>
    <id>https://blog.btjawa.top/posts/bilitools/</id>
    <link href="https://blog.btjawa.top/posts/bilitools/"/>
    <published>2024-01-11T16:00:00.000Z</published>
    <summary>
      <![CDATA[<p>💡 一个简约、轻量的哔哩哔哩工具箱，基于 <a href="https://github.com/tauri-apps/tauri">Tauri</a> 构建。</p>]]>
    </summary>
    <title>BiliTools</title>
    <updated>2025-09-22T16:00:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>btjawa</name>
    </author>
    <content>
      <![CDATA[<p>Welcome to <a href="https://hexo.io/">Hexo</a>! This is your very first post. Check <a href="https://hexo.io/docs/">documentation</a> for more info. If you get any problems when using Hexo, you can find the answer in <a href="https://hexo.io/docs/troubleshooting.html">troubleshooting</a> or you can ask me on <a href="https://github.com/hexojs/hexo/issues">GitHub</a>.</p><h2 id="Quick-Start">Quick Start</h2><h3 id="Create-a-new-post">Create a new post</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo new <span class="string">&quot;My New Post&quot;</span></span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/writing.html">Writing</a></p><h3 id="Run-server">Run server</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo server</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/server.html">Server</a></p><h3 id="Generate-static-files">Generate static files</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo generate</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/generating.html">Generating</a></p><h3 id="Deploy-to-remote-sites">Deploy to remote sites</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo deploy</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/one-command-deployment.html">Deployment</a></p>]]>
    </content>
    <id>https://blog.btjawa.top/posts/hello-world/</id>
    <link href="https://blog.btjawa.top/posts/hello-world/"/>
    <published>2023-12-18T16:00:00.000Z</published>
    <summary>
      <![CDATA[<p>Welcome to <a href="https://hexo.io/">Hexo</a>! This is your very first post. Check <a href="https://hexo.io/docs/">documentation</a> for]]>
    </summary>
    <title>Hello World</title>
    <updated>2023-12-18T16:00:00.000Z</updated>
  </entry>
</feed>
