<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[BrainBurst, HeadFirst]]></title><description><![CDATA[學習學到老，撞牆撞到腦.
A lifelong quest—with forehead dents.]]></description><link>https://blog.yu.money</link><generator>RSS for Node</generator><lastBuildDate>Mon, 01 Jun 2026 00:44:24 GMT</lastBuildDate><atom:link href="https://blog.yu.money/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Career-Ops 安裝與設定 — 用 AI 來幫你篩職缺、客製履歷]]></title><description><![CDATA[最近在看新的工作機會，光是瀏覽職缺、比對 JD、調整履歷就花了不少時間。
後來找到 Career-Ops 這個開源專案
作者 santifer 用這套系統篩了 740 多個職缺、產出 100 多份客製化履歷，最後拿到 Head of Applied AI 的 offer。
看起來蠻有意思的，所以我就在 Windows 上實際裝了一輪，這篇就來把整個安裝和設定的過程記錄下來。
我這邊搭配的 AI 後]]></description><link>https://blog.yu.money/career-ops-ai</link><guid isPermaLink="true">https://blog.yu.money/career-ops-ai</guid><category><![CDATA[AI]]></category><category><![CDATA[Career]]></category><category><![CDATA[career ops]]></category><dc:creator><![CDATA[Money Yu]]></dc:creator><pubDate>Sun, 12 Apr 2026 15:16:36 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/68367de88272b61f191620e6/f099fc2d-e850-47d6-8f83-038b7f4ab3d3.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>最近在看新的工作機會，光是瀏覽職缺、比對 JD、調整履歷就花了不少時間。</p>
<p>後來找到 <a href="https://github.com/santifer/career-ops">Career-Ops</a> 這個開源專案</p>
<p>作者 <a href="https://santifer.io">santifer</a> 用這套系統篩了 740 多個職缺、產出 100 多份客製化履歷，最後拿到 Head of Applied AI 的 offer。</p>
<p>看起來蠻有意思的，所以我就在 Windows 上實際裝了一輪，這篇就來把整個安裝和設定的過程記錄下來。</p>
<p>我這邊搭配的 AI 後端是 GitHub Copilot CLI。</p>
<h2>Career-Ops 是什麼</h2>
<p>在開始安裝之前，先簡單介紹一下 Career-Ops 提供了哪些功能：</p>
<ol>
<li><p><strong>職缺評估</strong>：用 A-F 的評分架構來分析一個職缺值不值得投遞</p>
</li>
<li><p><strong>客製化 PDF</strong>：根據每個 JD 的關鍵字，自動調整履歷內容，產出 ATS 友善的 PDF</p>
</li>
<li><p><strong>職缺掃描</strong>：可以自動掃 Greenhouse、Ashby、Lever 等平台，內建 45+ 家公司的設定</p>
</li>
<li><p><strong>批次處理</strong>：一次評估多個職缺，不用一個一個慢慢跑</p>
</li>
<li><p><strong>申請追蹤</strong>：用 Markdown 表格集中管理所有申請狀態</p>
</li>
</ol>
<p>這邊要特別提一下，Career-Ops 的設計理念比較偏向「篩選」而不是「海投」。簡單來說就是幫你從大量職缺中找出值得花時間的那幾個，如果評分低於 4.0/5，系統會直接建議不要投。</p>
<p>我實際跑了 12 個職缺下來，覺得這個門檻設定蠻合理的。</p>
<h2>環境需求</h2>
<table>
<thead>
<tr>
<th>工具</th>
<th>版本</th>
<th>說明</th>
</tr>
</thead>
<tbody><tr>
<td><a href="https://nodejs.org/">Node.js</a></td>
<td>18+</td>
<td>執行核心腳本</td>
</tr>
<tr>
<td><a href="https://git-scm.com/">Git</a></td>
<td>任意</td>
<td>Clone 專案用</td>
</tr>
<tr>
<td><a href="https://github.com/features/copilot">GitHub Copilot CLI</a></td>
<td>最新</td>
<td>我這邊使用的 AI 後端，也可以使用任何支援 Skill 的 AI CLI</td>
</tr>
<tr>
<td><a href="https://go.dev/">Go</a></td>
<td>1.21+（選用）</td>
<td>編譯 Dashboard 看板，不裝也不影響功能</td>
</tr>
<tr>
<td><a href="https://python.org/">Python</a></td>
<td>3.10+（選用）</td>
<td>用來把 PDF 履歷轉成 Markdown，使用微軟出的 Markitdown</td>
</tr>
</tbody></table>
<h2>安裝與設定</h2>
<h3>Clone 專案、安裝依賴</h3>
<p>首先把專案 Clone 下來並安裝相依套件：</p>
<pre><code class="language-bash">git clone https://github.com/santifer/career-ops.git
cd career-ops
npm install
</code></pre>
<p>相依套件蠻少的，就 <code>js-yaml</code> 和 <code>playwright</code> 兩個：</p>
<pre><code class="language-plaintext">added 4 packages, and audited 5 packages in 15s
found 0 vulnerabilities
</code></pre>
<h3>安裝 Playwright Chromium</h3>
<p>Career-Ops 使用 Playwright 來做兩件事：產生 PDF 以及到職缺頁面確認該職缺是否還在開放中。所以這邊需要安裝 Chromium：</p>
<pre><code class="language-bash">npx playwright install chromium
</code></pre>
<p>這邊會下載大概 290MB 左右，需要等一下。安裝完成後會顯示下載路徑：</p>
<pre><code class="language-plaintext">Chrome for Testing (playwright chromium) downloaded to C:\Users\{你的使用者}\AppData\Local\ms-playwright\chromium-xxxx
Chrome Headless Shell downloaded to ...
</code></pre>
<h3>設定個人資料</h3>
<p>這邊是整個安裝過程中最重要的部分。Career-Ops 需要先認識你，才能幫你評估職缺和客製化履歷。</p>
<p>首先把三個模板檔案複製出來：</p>
<pre><code class="language-bash"># 複製個人設定模板
cp config/profile.example.yml config/profile.yml

# 複製入口網站掃描器模板
cp templates/portals.example.yml portals.yml

# 複製個人化客製模板（這個檔案永遠不會被系統更新覆蓋）
cp modes/_profile.template.md modes/_profile.md
</code></pre>
<p>這三個檔案分別是個人資料、掃描器設定、以及個人化覆寫設定。其中第三個 <code>_profile.md</code> 比較特別，系統更新的時候不會動到它，所以個人的客製化設定放這裡最安全。</p>
<p>接下來打開 <code>config/profile.yml</code>，這是最核心的設定檔，修改成自己的資訊：</p>
<pre><code class="language-yaml">candidate:
  full_name: "你的名字"
  email: "your@email.com"
  phone: "+886-XXX-XXX-XXX"
  location: "Taipei, Taiwan"
  linkedin: "linkedin.com/in/yourprofile"
  portfolio_url: "https://yoursite.dev"
  github: "github.com/yourusername"

target_roles:
  primary:
    - "Senior Cloud Engineer"
    - "Senior Software Engineer"
  archetypes:
    - name: "Cloud/Platform Engineer"
      level: "Senior/Staff"
      fit: "primary"        # primary = 夢想職位
    - name: "Full Stack Developer"
      level: "Senior"
      fit: "secondary"      # secondary = 不錯的選擇
    - name: "Solutions Architect"
      level: "Senior"
      fit: "adjacent"       # adjacent = 延伸嘗試

narrative:
  headline: "你的一句話職業標題"
  exit_story: "你的獨特故事 — 是什麼讓你與眾不同"
  superpowers:
    - "你的超能力 1"
    - "你的超能力 2"
    - "你的超能力 3"
  proof_points:
    - name: "專案名稱"
      url: "https://your-project.dev"
      hero_metric: "量化的成果指標"

compensation:
  target_range: "TWD 2,000,000-3,000,000"
  currency: "TWD"
  minimum: "TWD 1,800,000"
  location_flexibility: "Taipei preferred, remote-friendly"

location:
  country: "Taiwan"
  city: "Taipei"
  timezone: "Asia/Taipei (UTC+8)"
  visa_status: "Local citizen"
</code></pre>
<p>這邊有個小細節要注意：<code>archetypes</code> 裡的 <code>fit</code> 欄位分成三種 — <code>primary</code> 代表最想要的目標方向，<code>secondary</code> 是也可以考慮的，<code>adjacent</code> 則是有點距離但願意嘗試看看。系統會根據這個設定來調整評分的權重。</p>
<h4>關於 <code>modes/_profile.md</code></h4>
<p>這個檔案是用來存放「你自己的規則」的地方，像是：</p>
<ul>
<li><p>希望怎麼包裝自己的經歷（敘事框架）</p>
</li>
<li><p>面試時薪資要怎麼談</p>
</li>
<li><p>哪些工作地點可以接受</p>
</li>
<li><p>職位原型的對應方式</p>
</li>
</ul>
<p>這邊有一條重要的規則：<strong>個人化的設定放</strong> <code>_profile.md</code> <strong>或</strong> <code>profile.yml</code><strong>，不要去修改</strong> <code>_shared.md</code>。因為 <code>_shared.md</code> 是系統檔，更新的時候會被覆蓋掉。</p>
<h3>準備履歷</h3>
<p>Career-Ops 需要一份 Markdown 格式的 <code>cv.md</code> 來當作所有評估和 PDF 產生的資料來源。</p>
<pre><code class="language-bash"># 方法 1：手動建立
# 直接建立 cv.md，用 Markdown 格式撰寫你的履歷

# 方法 2：從 PDF 轉換（需要 markitdown）
pip install "markitdown[pdf]"
python -m markitdown your-cv.pdf &gt; cv.md
</code></pre>
<h4>從 PDF 轉換</h4>
<p>我這邊手上有現成的 PDF 履歷，所以直接用 <a href="https://github.com/microsoft/markitdown">markitdown</a> 來轉換。這個工具是 Microsoft 出的，轉出來的格式還不錯：</p>
<pre><code class="language-bash"># 安裝 markitdown（含 PDF 支援）
pip install "markitdown[pdf]"

# 轉換你的 PDF 履歷
python -m markitdown path/to/your-cv.pdf &gt; cv.md
</code></pre>
<p>要注意的是轉完之後建議自己檢查一下，有些格式可能會跑掉，特別是表格和多欄排版的部分。主要確認以下幾個區段有正確抓到就好：Professional Summary、Work Experience、Technical Skills、Projects、Education、Certifications。</p>
<h4>設定 markitdown MCP（選用）</h4>
<p>如果也有在用 VS Code 或 Copilot CLI 的話，可以把 markitdown 設成 MCP server，這樣之後可以直接在對話中叫它轉檔：</p>
<pre><code class="language-bash">pip install "markitdown[mcp]"
</code></pre>
<p>在專案中建立 <code>.vscode/mcp.json</code>：</p>
<pre><code class="language-json">{
  "servers": {
    "markitdown": {
      "type": "stdio",
      "command": "python",
      "args": ["-m", "markitdown.mcp"]
    }
  }
}
</code></pre>
<h3>驗證安裝</h3>
<p>專案有內建一個 <code>doctor</code> 指令，跑一下就可以知道哪裡還有問題：</p>
<pre><code class="language-bash">npm run doctor
</code></pre>
<p>全部打勾就代表可以開始使用了：</p>
<pre><code class="language-plaintext">career-ops doctor
================

✓ Node.js &gt;= 18 (v24.13.1)
✓ Dependencies installed
✓ Playwright chromium installed
✓ cv.md found
✓ config/profile.yml found
✓ portals.yml found
✓ Fonts directory ready
✓ data/ directory ready
✓ output/ directory ready
✓ reports/ directory ready

Result: All checks passed. You're ready to go!
</code></pre>
<p>如果有 ✗ 的項目，它會告訴你要怎麼修，修完再重跑一次即可。</p>
<h2>使用方式</h2>
<h3>透過 GitHub Copilot CLI</h3>
<p>我這邊是在專案目錄中開啟 Copilot CLI，最直接的用法就是貼一個職缺 URL 進去：</p>
<pre><code class="language-plaintext"># 貼上職缺 URL，系統會自動執行完整 pipeline
https://apply.careers.microsoft.com/careers/job/xxxxx
</code></pre>
<p>貼進去之後它就會自動跑完整個流程 — 抓 JD、評估、產生報告、製作 PDF、更新追蹤器，全部自動完成。也可以透過指令單獨執行特定功能：</p>
<pre><code class="language-plaintext">career-ops              # 顯示所有可用指令
career-ops scan         # 掃描入口網站
career-ops pdf          # 產生 ATS 優化 PDF
career-ops tracker      # 查看申請狀態
career-ops batch        # 批次評估多個職缺
</code></pre>
<h3>透過 Claude Code</h3>
<p>如果使用的是 Claude Code：</p>
<pre><code class="language-bash">claude   # 在專案目錄中啟動 Claude Code
</code></pre>
<p>透過 slash 指令來操作：</p>
<pre><code class="language-plaintext">/career-ops              # 顯示選單
/career-ops scan         # 掃描入口網站
/career-ops pdf          # 產生 PDF
</code></pre>
<h3>Auto-Pipeline 流程</h3>
<p>那接下來就來看看貼一個 URL 進去之後到底會發生什麼事。整個流程如下：</p>
<ol>
<li><p>透過 Playwright 或 WebFetch 去抓取 JD 內容</p>
</li>
<li><p>執行 A-G 七個區塊的完整評估</p>
</li>
<li><p>將評估報告儲存到 <code>reports/</code></p>
</li>
<li><p>根據 JD 關鍵字重新編排履歷，產出 ATS 友善的 PDF</p>
</li>
<li><p>在 <code>data/applications.md</code> 新增一筆追蹤紀錄</p>
</li>
</ol>
<p>我第一次跑的時候蠻驚訝的 — 一個 URL 貼進去，幾分鐘之後就產出了一份完整報告、一份客製化 PDF，還自動更新了追蹤表。</p>
<h3>評估報告介紹</h3>
<p>每份報告包含七個區塊，下面來一一介紹：</p>
<table>
<thead>
<tr>
<th>區塊</th>
<th>說明</th>
</tr>
</thead>
<tbody><tr>
<td>A) 角色摘要</td>
<td>快速瀏覽這是什麼類型的職位、級別、是否支援遠端</td>
</tr>
<tr>
<td>B) CV 匹配</td>
<td>把 JD 的每個需求拿出來，逐一對照履歷中的對應經歷，有匹配的標記、沒有的會告訴你怎麼補</td>
</tr>
<tr>
<td>C) 等級策略</td>
<td>如果 JD 的職級比你低，會提供「如何避免被降級」的談判建議</td>
</tr>
<tr>
<td>D) 薪資研究</td>
<td>從 Glassdoor、Levels.fyi 抓取即時薪資數據，附上資料來源</td>
</tr>
<tr>
<td>E) 客製化計畫</td>
<td>針對這個職缺，列出 CV 和 LinkedIn 各自 Top 5 的修改建議</td>
</tr>
<tr>
<td>F) 面試準備</td>
<td>準備 6-10 個 STAR 故事，直接對應 JD 的需求</td>
</tr>
<tr>
<td>G) 職缺真實性</td>
<td>判斷這個職缺是否為真實開放中的機會，還是所謂的幽靈職缺</td>
</tr>
</tbody></table>
<h2>專案結構</h2>
<pre><code class="language-plaintext">career-ops/
├── cv.md                        # 你的履歷（必要）
├── config/profile.yml           # 你的個人設定（必要）
├── modes/_profile.md            # 你的客製化（不會被更新覆蓋）
├── portals.yml                  # 掃描器設定（建議）
├── data/applications.md         # 申請追蹤器
├── reports/                     # 評估報告（自動產生）
├── output/                      # PDF 檔案（自動產生）
├── modes/                       # 技能模式（系統檔案）
│   ├── _shared.md               # 共用系統設定
│   ├── oferta.md                # 單一職缺評估
│   ├── pdf.md                   # PDF 產生
│   ├── scan.md                  # 掃描器
│   └── ...
├── templates/
│   ├── cv-template.html         # ATS 優化 CV 模板
│   └── states.yml               # 標準狀態定義
└── batch/                       # 批次處理
</code></pre>
<h2>檔案分層架構</h2>
<p>這邊蠻重要的，Career-Ops 把檔案分成兩層：</p>
<p><strong>使用者層</strong>（系統更新時不會動到）：</p>
<ul>
<li><p><code>cv.md</code>、<code>config/profile.yml</code>、<code>modes/_profile.md</code></p>
</li>
<li><p><code>portals.yml</code>、<code>article-digest.md</code></p>
</li>
<li><p><code>data/*</code>、<code>reports/*</code>、<code>output/*</code>、<code>interview-prep/*</code></p>
</li>
</ul>
<p><strong>系統層</strong>（更新時會覆蓋，不要放個人資料）：</p>
<ul>
<li><p><code>modes/_shared.md</code>、<code>modes/oferta.md</code> 等系統模式檔</p>
</li>
<li><p><code>CLAUDE.md</code>、<code>*.mjs</code> 腳本、<code>templates/*</code></p>
</li>
</ul>
<p>簡單來說就是：個人化設定放 <code>_profile.md</code> 或 <code>profile.yml</code>，不要去修改 <code>_shared.md</code>。</p>
<h2>客製化</h2>
<p>Career-Ops 有一個我覺得設計得蠻好的地方：它的設定檔都是 Markdown 和 YAML 格式，AI 可以直接讀取也可以直接修改。所以不需要自己去翻文件找設定在哪裡，直接用自然語言跟 AI 講就好：</p>
<table>
<thead>
<tr>
<th>想做的事</th>
<th>跟 AI 說</th>
</tr>
</thead>
<tbody><tr>
<td>改變目標職位類型</td>
<td>"把 archetypes 改成後端工程師相關的角色"</td>
</tr>
<tr>
<td>翻譯模式檔案</td>
<td>"把所有 modes 翻譯成繁體中文"</td>
</tr>
<tr>
<td>新增掃描公司</td>
<td>"在 portals.yml 加入 Google、Apple、Meta"</td>
</tr>
<tr>
<td>修改評分權重</td>
<td>"把薪資維度的權重調高"</td>
</tr>
<tr>
<td>更新履歷</td>
<td>"用我剛貼的內容更新 cv.md"</td>
</tr>
<tr>
<td>修改 CV 模板設計</td>
<td>"把 CV 的配色改成藍色系"</td>
</tr>
</tbody></table>
<h2>使用心得</h2>
<p>實際使用了一段時間之後，有幾個地方值得注意：</p>
<ul>
<li><p>系統不會自動幫你送出申請。它會協助填表、撰寫回答、產生 PDF，但最後按下送出的動作一定是由自己來完成。這點我覺得設計得很好。</p>
</li>
<li><p>評分低於 4.0 的職缺建議就不要投了。我跑了 12 個職缺，4.0 以下的確實都有明顯不合適的地方，硬投反而浪費時間。</p>
</li>
<li><p>認真準備投 5 家，比亂投 50 家來得有效。</p>
</li>
<li><p>AI 偶爾會產生不正確的資訊，特別是薪資數據和公司資訊的部分，提交之前記得自己再確認一下。</p>
</li>
</ul>
<img src="https://cdn.hashnode.com/uploads/covers/68367de88272b61f191620e6/0c4f5e27-3b04-4f06-8af0-ab6460a3bb53.png" alt="" style="display:block;margin:0 auto" />

<img src="https://cdn.hashnode.com/uploads/covers/68367de88272b61f191620e6/18c12472-a2bf-46c6-b971-af27f5dcc202.png" alt="" style="display:block;margin:0 auto" />

<h2>小結</h2>
<p>這套系統在剛開始使用的時候評估不會太準確，因為它對你的了解還不夠。多跑幾次、多給它一些回饋（像是「這個分數太高了，我不會投這種」），它會越來越準。我大概到第五、六個職缺的時候，就覺得它的判斷跟我自己的直覺差不多了。</p>
<p>如果你也在找新的工作機會，推薦可以試看看。</p>
<hr />
<p><strong>參考連結：</strong></p>
<ul>
<li><p><a href="https://github.com/santifer/career-ops">Career-Ops GitHub</a></p>
</li>
<li><p><a href="https://github.com/santifer/cv-santiago">作者的作品集（也開源）</a></p>
</li>
<li><p><a href="https://discord.gg/8pRpHETxa4">Discord 社群</a></p>
</li>
<li><p><a href="https://santifer.io/career-ops-system">作者的案例研究</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[讓 LLM 自動化你的 N8N 工作流程：n8n-mcp-server 安裝指南]]></title><description><![CDATA[前言
網路上一大堆都是在介紹如何在 N8N 裡面用 MCP 來呼叫其他工具，但是更多時候我希望 LLM 能直接幫我寫好或是修改 N8N 的工作流程
所以這篇就來介紹如何設定與使用 n8n-mcp-server 來讓 LLM 幫忙操控 N8N
在 GitHub 上有不少的 n8n-mcp-server，經過一下下的簡單搜索，我決定使用這個專案: n8n-mcp-server
原因在於說這個專案的實作提供了基本上所有需要編輯工作流程的功能，以下就來記錄安裝過程

MCP Server 設定
首先當然...]]></description><link>https://blog.yu.money/llm-n8n-mcp-server</link><guid isPermaLink="true">https://blog.yu.money/llm-n8n-mcp-server</guid><category><![CDATA[n8n]]></category><category><![CDATA[mcp]]></category><category><![CDATA[llm]]></category><category><![CDATA[generative ai]]></category><dc:creator><![CDATA[Money Yu]]></dc:creator><pubDate>Wed, 28 May 2025 04:51:37 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-5ymn6kia">前言</h2>
<p>網路上一大堆都是在介紹如何在 N8N 裡面用 MCP 來呼叫其他工具，但是更多時候我希望 LLM 能直接幫我寫好或是修改 N8N 的工作流程</p>
<p>所以這篇就來介紹如何設定與使用 <a target="_blank" href="https://github.com/leonardsellem/n8n-mcp-server"><strong>n8n-mcp-server</strong></a> 來讓 LLM 幫忙操控 N8N</p>
<p>在 GitHub 上有不少的 n8n-mcp-server，經過一下下的簡單搜索，我決定使用這個專案: <a target="_blank" href="https://github.com/leonardsellem/n8n-mcp-server"><strong>n8n-mcp-server</strong></a></p>
<p>原因在於說這個專案的實作提供了基本上所有需要編輯工作流程的功能，以下就來記錄安裝過程</p>
<hr />
<h2 id="heading-mcp-server">MCP Server 設定</h2>
<p>首先當然要先有 Node.JS 的環境，這邊就不多作介紹了</p>
<p>我這邊使用的是 Local 的 MCP Server 模式</p>
<p>先透過以下指令將 Repo 複製到本地</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Clone the repository</span>
git <span class="hljs-built_in">clone</span> https://github.com/leonardsellem/n8n-mcp-server.git
<span class="hljs-built_in">cd</span> n8n-mcp-server
</code></pre>
<p>接下來就要透過 NPM 來安裝相依的套件，但是在這邊有一個要注意的地方</p>
<p>這個專案在 package.json 裡面有一個指令是只支援 Unix 環境，若直接在 Windows 環境下執行會掛掉</p>
<p>若你是 Windows 作業系統需要打開在根目錄下的 package.json，編輯 scripts/build 的段落，移除 <code>&amp;&amp; chmod +x build/index.js</code> 後存檔</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"n8n-mcp-server"</span>,
  <span class="hljs-attr">"version"</span>: <span class="hljs-string">"0.1.0"</span>,
  <span class="hljs-attr">"description"</span>: <span class="hljs-string">"Model Context Protocol (MCP) server for n8n workflow automation"</span>,
  <span class="hljs-attr">"main"</span>: <span class="hljs-string">"build/index.js"</span>,
  <span class="hljs-attr">"type"</span>: <span class="hljs-string">"module"</span>,
  <span class="hljs-attr">"scripts"</span>: {
    <span class="hljs-comment">// 編輯這一行，移除 '&amp;&amp; chmod +x build/index.js'，變成如下樣子</span>
    <span class="hljs-attr">"build"</span>: <span class="hljs-string">"tsc"</span>,
    <span class="hljs-attr">"start"</span>: <span class="hljs-string">"node build/index.js"</span>,
    <span class="hljs-attr">"dev"</span>: <span class="hljs-string">"tsc -w"</span>,
    <span class="hljs-attr">"lint"</span>: <span class="hljs-string">"eslint --ext .ts src/"</span>,
    <span class="hljs-attr">"test"</span>: <span class="hljs-string">"node --experimental-vm-modules run-tests.js"</span>,
    <span class="hljs-attr">"test:watch"</span>: <span class="hljs-string">"node --experimental-vm-modules run-tests.js --watch"</span>,
    <span class="hljs-attr">"test:coverage"</span>: <span class="hljs-string">"node --experimental-vm-modules run-tests.js --coverage"</span>,
    <span class="hljs-attr">"prepare"</span>: <span class="hljs-string">"npm run build"</span>
  }
}
</code></pre>
<p>編輯完後就可以執行以下指令</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Install dependencies</span>
npm install

<span class="hljs-comment"># Build the project</span>
npm run build
</code></pre>
<p>最終應該會得到類似以下畫面</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748405705321/080e8661-cf81-4497-8e47-7b2216c98e61.png" alt class="image--center mx-auto" /></p>
<p>到此為止，我們就將地端的 n8n-mcp-server 設定完成，接下來我們就要來設定 MCP Client 端</p>
<hr />
<h2 id="heading-mcp-client">MCP Client 設定</h2>
<p>我這邊使用 Claude Desktop 作為範例，但是可以應用到所有的 MCP Client 端，如: VSCode、Cline 等等</p>
<p>這邊打開 Claude 的 MCP 設定 JSON</p>
<p>加入以下相關設定</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"mcpServers"</span>: {
    <span class="hljs-comment">// Give your server a unique name</span>
    <span class="hljs-attr">"n8n-local"</span>: {
      <span class="hljs-comment">// Use 'node' to execute the built JavaScript file</span>
      <span class="hljs-attr">"command"</span>: <span class="hljs-string">"node"</span>,
      <span class="hljs-comment">// Provide the *absolute path* to the built index.js file</span>
      <span class="hljs-attr">"args"</span>: [
        <span class="hljs-string">"/path/to/your/cloned/n8n-mcp-server/build/index.js"</span>
        <span class="hljs-comment">// On Windows, use double backslashes:</span>
        <span class="hljs-comment">// "C:\\path\\to\\your\\cloned\\n8n-mcp-server\\build\\index.js"</span>
      ],
      <span class="hljs-comment">// Environment variables needed by the server</span>
      <span class="hljs-attr">"env"</span>: {
        <span class="hljs-attr">"N8N_API_URL"</span>: <span class="hljs-string">"http://your-n8n-instance:5678/api/v1"</span>, <span class="hljs-comment">// Replace with your n8n URL</span>
        <span class="hljs-attr">"N8N_API_KEY"</span>: <span class="hljs-string">"YOUR_N8N_API_KEY"</span>, <span class="hljs-comment">// Replace with your key</span>
        <span class="hljs-comment">// Add webhook credentials only if you plan to use webhook tools</span>
        <span class="hljs-attr">"N8N_WEBHOOK_USERNAME"</span>: <span class="hljs-string">"your_webhook_user"</span>,
        <span class="hljs-attr">"N8N_WEBHOOK_PASSWORD"</span>: <span class="hljs-string">"your_webhook_password"</span>
      },
      <span class="hljs-comment">// Ensure the server is enabled</span>
      <span class="hljs-attr">"disabled"</span>: <span class="hljs-literal">false</span>,
      <span class="hljs-comment">// Default autoApprove settings</span>
      <span class="hljs-attr">"autoApprove"</span>: []
    }
    <span class="hljs-comment">// ... other servers might be configured here</span>
  }
}
</code></pre>
<p>這邊需要注意一個地方，就是即使你沒有使用 N8N Webhook 相關功能，也請保留對應的設定，因為目前有 BUG，若找不到對應設定會直接出錯: <code>Failed to start n8n MCP Server: McpError: MCP error 1000: Missing required environment variable: N8N_WEBHOOK_USERNAME</code>，可參考對應 issue: <a target="_blank" href="https://github.com/leonardsellem/n8n-mcp-server/issues/1">Issue connecting to n8n-mcp-server · Issue #1 · leonardsellem/n8n-mcp-server</a>、<a target="_blank" href="https://github.com/leonardsellem/n8n-mcp-server/issues/13">N8N_WEBHOOK_USERNAME 和N8N_WEBHOOK_PASSWORD 必填要求 · Issue #13 · leonardsellem/n8n-mcp-server</a></p>
<hr />
<h2 id="heading-6zal5ael5l255so">開始使用</h2>
<p>完成後我們就可以實際來操作看看</p>
<ol>
<li>幫我整理有哪些 Workflow</li>
</ol>
<pre><code class="lang-markdown">User:
幫我看看 n8n 現在有哪些 workflow

Claude: 
我來幫您查看 n8n 中現有的工作流程。您的 n8n 實例中目前有 <span class="hljs-strong">**2 個工作流程**</span>：

<span class="hljs-section">## 工作流程清單</span>

<span class="hljs-section">### 1. 📍 Raindrop Knowledge Management</span>
<span class="hljs-bullet">-</span> <span class="hljs-strong">**狀態**</span>：已啟用 ✅
<span class="hljs-bullet">-</span> <span class="hljs-strong">**工作流程 ID**</span>：E1OK2GVGla40YBIp
<span class="hljs-bullet">-</span> <span class="hljs-strong">**最後更新**</span>：2025年5月27日 17:53

<span class="hljs-section">### 2. 📋 Raindrop 知識自動整理 copy</span>
<span class="hljs-bullet">-</span> <span class="hljs-strong">**狀態**</span>：未啟用 ⏸️
<span class="hljs-bullet">-</span> <span class="hljs-strong">**工作流程 ID**</span>：NRyh6e2T1Qanz5xX
<span class="hljs-bullet">-</span> <span class="hljs-strong">**最後更新**</span>：2025年5月27日 17:51

<span class="hljs-section">## 觀察</span>

看起來您有兩個相關的 Raindrop 知識管理工作流程，其中一個是另一個的副本。目前只有原始的 "Raindrop Knowledge Management" 工作流程正在運行。

如果您想要查看某個特定工作流程的詳細配置，或者需要啟用/停用某個工作流程，請告訴我！
</code></pre>
<ol start="2">
<li>刪除對應 Workflow</li>
</ol>
<pre><code class="lang-markdown">User:
幫我刪除 工作流程 ID：NRyh6e2T1Qanz5xX flow

Claude: 
我來幫您刪除工作流程 ID 為 <span class="hljs-code">`NRyh6e2T1Qanz5xX`</span> 的 "Raindrop 知識自動整理 copy" 工作流程。✅ <span class="hljs-strong">**工作流程刪除成功**</span>

工作流程 "Raindrop 知識自動整理 copy" (ID: NRyh6e2T1Qanz5xX) 已成功刪除。

現在您的 n8n 實例中只剩下一個工作流程：
<span class="hljs-bullet">-</span> <span class="hljs-strong">**Raindrop Knowledge Management**</span> (已啟用)
</code></pre>
<hr />
<h3 id="heading-5yv55so5yqf6io9">可用功能</h3>
<p>以下是所有 LLM 可以用的功能，可參考 <a target="_blank" href="https://github.com/leonardsellem/n8n-mcp-server?tab=readme-ov-file#available-tools"><strong>Available Tools</strong></a></p>
<p><strong>工作流程管理</strong></p>
<ul>
<li><p><code>workflow_list</code>: 列出所有工作流程</p>
</li>
<li><p><code>workflow_get</code>: 獲取特定工作流程的詳細資訊</p>
</li>
<li><p><code>workflow_create</code>: 建立新的工作流程</p>
</li>
<li><p><code>workflow_update</code>: 更新現有的工作流程</p>
</li>
<li><p><code>workflow_delete</code>: 刪除工作流程</p>
</li>
<li><p><code>workflow_activate</code>: 啟用工作流程</p>
</li>
<li><p><code>workflow_deactivate</code>: 停用工作流程</p>
</li>
</ul>
<p><strong>執行管理</strong></p>
<ul>
<li><p><code>execution_run</code>: 透過 API 執行工作流程</p>
</li>
<li><p><code>run_webhook</code>: 透過 webhook 執行工作流程</p>
</li>
<li><p><code>execution_get</code>: 獲取特定執行的詳細資訊</p>
</li>
<li><p><code>execution_list</code>: 列出工作流程的執行記錄</p>
</li>
<li><p><code>execution_stop</code>: 停止正在運行的執行</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[[IT 鐵人賽] ASP.NET Core 與 Log 紀錄和追蹤的愛恨交織 - Day 05 - Elmah - 02]]></title><description><![CDATA[.NET Core Logging- Elmah 02

上一篇我們提到了基本的使用方式，接下來的這一篇我們就來講講要怎麼把 Log 放到不同的儲存體上，以及如何過濾 Log

Log 儲存方式
我們先來看這些 Log 倒底存在哪裡，目前共有三種儲存方式，如下：

MemoryErrorLog — store errors in memory
預設為使用此方式，簡單來說就是將錯誤 Log 都存在記憶體裡，所以只要應用程式一重新啟動，Log 就沒了；但是也是最方便的方式，只是要注意如果 Log 太...]]></description><link>https://blog.yu.money/it-aspnet-core-log-day-05-elmah-02</link><guid isPermaLink="true">https://blog.yu.money/it-aspnet-core-log-day-05-elmah-02</guid><dc:creator><![CDATA[Money Yu]]></dc:creator><pubDate>Sat, 20 Oct 2018 04:56:08 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070454149/a0702417-5357-4217-a572-7ba53ea36735.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<hr />
<h4 id="heading-net-core-logging-elmah-02">.NET Core Logging- Elmah 02</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070454149/a0702417-5357-4217-a572-7ba53ea36735.png" alt /></p>
<p>上一篇我們提到了基本的使用方式，接下來的這一篇我們就來講講要怎麼把 Log 放到不同的儲存體上，以及如何過濾 Log</p>
<hr />
<h4 id="heading-log">Log 儲存方式</h4>
<p>我們先來看這些 Log 倒底存在哪裡，目前共有三種儲存方式，如下：</p>
<ul>
<li>MemoryErrorLog — store errors in memory
預設為使用此方式，簡單來說就是將錯誤 Log 都存在記憶體裡，所以只要應用程式一重新啟動，Log 就沒了；但是也是最方便的方式，只是要注意如果 Log 太多的話，記憶體的使用狀況，避免記憶體不足的情況。</li>
<li>XmlFileErrorLog — store errors in XML files
將 Log 存成 Xml 格式之檔案，並儲存於檔案系統上。</li>
<li>SqlErrorLog — store errors in MS SQL
將 Log 存到 SQL Server 上。</li>
</ul>
<blockquote>
<p><a target="_blank" href="https://github.com/funky81/ElmahCore">https://github.com/funky81/ElmahCore</a> 有額外提供 Redis 當作儲存體</p>
</blockquote>
<hr />
<p>如果要使用除了 <code>MemoryErrorLog</code> 以外的方式，下面一一介紹如何設定</p>
<h4 id="heading-xmlfileerrorlog">XmlFileErrorLog</h4>
<p>於 <code>Startup.cs</code> 之 <code>ConfigureServices</code> 中加入 <code>service.AddElmah();</code> 時，使用泛型來指定要儲存的方式，並指定儲存路徑</p>
<p>這樣就會將錯誤 Log 存成 Xml 格式，並放在指定目錄；以此為例就是在應用程式根目錄底下的 <code>logs</code> 資料夾，也可以直接指定絕對路徑，例如：<code>D:\ErrorLogs</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070509029/1ac28b57-edb2-408f-9402-bde8b8e57669.png" alt /></p>
<p>要注意的是每一個錯誤 Log 就是一個 Xml 檔案，所以有可能會塞爆檔案系統，或是檔案數量過多，導致系統效能低下</p>
<h4 id="heading-sqlerrorlog">SqlErrorLog</h4>
<p>於 <code>Startup.cs</code> 之 <code>ConfigureServices</code> 中加入 <code>service.AddElmah();</code> 時，使用泛型來指定要儲存的方式，並指定連線字串</p>
<pre><code><span class="hljs-string">"ConnectionStrings"</span>: {
    <span class="hljs-string">"ElmahConnectionString"</span>: <span class="hljs-string">"Server=(localdb)\\mssqllocaldb;Database=Elmah;Trusted_Connection=True;MultipleActiveResultSets=true"</span>
}
</code></pre><blockquote>
<p>需要先根據 <a target="_blank" href="https://bitbucket.org/project-elmah/main/downloads/ELMAH-1.2-db-SQLServer.sql">https://bitbucket.org/project-elmah/main/downloads/ELMAH-1.2-db-SQLServer.sql</a> 建立資料表</p>
</blockquote>
<p>這樣即可建立並使用資料庫收集錯誤 Log</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070510268/ec685ef4-7b65-4748-9684-960e1dbc828a.png" alt /></p>
<hr />
<h4 id="heading-filter">使用 Filter</h4>
<p>Elmah 預設會記錄所有例外錯誤，但是有些可能是很常見或是不需要理會的 Log，例如 HTTP 404 找不到資源錯誤，而且這種情況可能很多，導致產生大量無用 Log；因此可以透過 Filter 的方式過濾</p>
<p>這部分基本上與 Elmah 差不多相同，有兩種方式可以進行設定：</p>
<ol>
<li>透過程式動態設定</li>
</ol>
<p>透過實作 <code>IErrorFilter</code> 介面，當 <code>Filtering</code> 事件發生時，它會去看說是不是有任何的 <code>Filter</code>呼叫 <code>Dismiss</code> 方法，呼叫 <code>Dismiss</code> 方法代表 Elmah 會略過此 Log</p>
<p>以下面程式碼為例：實作當遇到 <code>NotImplementedException</code> 時就不會記錄 Log，並於 <code>Startup.cs</code> 之 <code>ConfigureServices</code> 加入 <code>service.AddElmah();</code> 時，加入相關設定</p>
<ol start="2">
<li>透過 XML 設定檔</li>
</ol>
<p>Elmah 可以讀取 XML 設定檔來進行 Filter 設定，這樣就不用每當需要修改不同條件時還需要修改程式</p>
<p>以下面為例，於設定檔中設定不要紀錄 HTTP 404 的 Log ，並於 <code>Startup.cs</code> 之 <code>ConfigureServices</code> 加入 <code>service.AddElmah();</code> 時，加入相關設定</p>
<p>上面的 <code>elmah.xml</code> 需要實作 <code>errorFilter</code> 區段</p>
<p><code>test</code> 代表的是要判斷是否相符，若相符則略過，底下有不同的運算子： <code>equal</code> 、 <code>lesser</code> 、 <code>greater</code> 、 <code>and</code> 、 <code>or</code> 等等</p>
<pre><code>&lt;test&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">and</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">greater</span> <span class="hljs-attr">binding</span>=<span class="hljs-string">"HttpStatusCode"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"399"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"Int32"</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">lesser</span> <span class="hljs-attr">binding</span>=<span class="hljs-string">"HttpStatusCode"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"500"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"Int32"</span> /&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">and</span>&gt;</span></span>
&lt;/test&gt;
</code></pre><p>以上面為例，就是要略過 HTTP 狀態碼大於 399 且小於 500 的所有錯誤 Log</p>
<p>詳細設定說明請參考：<a target="_blank" href="https://elmah.github.io/a/error-filtering/">https://elmah.github.io/a/error-filtering/</a></p>
<hr />
<h4 id="heading-5ykz6ycb6yca55l">傳送通知</h4>
<p>在正式環境發生嚴重例外時，除了記錄下來以外，最好也要可以及時通知相關人員，Elmah 也透過寄送 Email 的方式提供了基本的通知功能</p>
<p>直接在 <code>Startup.cs</code> 之 <code>ConfigureServices</code> 加入 <code>service.AddElmah();</code> 時，加入相關設定</p>
<p>每個 <code>ErrorMailNotifier</code> 實體都<strong>必須要有唯一的名字</strong>，<code>EmailOptions</code> 就是一些關於 Mail Server 與寄送相關資訊的設定，所以這邊就不再多詳談</p>
<hr />
<p>下一篇來介紹 Elmah 的雲端變種：Elmah.io</p>
]]></content:encoded></item><item><title><![CDATA[[IT 鐵人賽] ASP.NET Core 與 Log 紀錄和追蹤的愛恨交織 - Day 04 - Elmah - 01]]></title><description><![CDATA[.NET Core Logging- Elmah 01

Elmah 是我最一開始使用的 Log 工具，基本上它的功能就是將應用程式所有發生的錯誤記錄下來，不需要改變程式架構，而且又有介面可以觀看，十分的方便；它從 WebForm 時代就有了，到了 MVC 也是運作的很好，那這邊就來介紹一下 Elmah 要如何在 ASP.NET Core 中使用 (.NET Core 也可使用)。
不過很可惜的，目前並沒有釋出官方的 Elmah for .NET Core，不過有一個新專案： ElmahCore...]]></description><link>https://blog.yu.money/it-aspnet-core-log-day-04-elmah-01</link><guid isPermaLink="true">https://blog.yu.money/it-aspnet-core-log-day-04-elmah-01</guid><dc:creator><![CDATA[Money Yu]]></dc:creator><pubDate>Fri, 19 Oct 2018 15:04:16 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070454149/a0702417-5357-4217-a572-7ba53ea36735.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<hr />
<h4 id="heading-net-core-logging-elmah-01">.NET Core Logging- Elmah 01</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070454149/a0702417-5357-4217-a572-7ba53ea36735.png" alt /></p>
<p>Elmah 是我最一開始使用的 Log 工具，基本上它的功能就是將應用程式所有發生的錯誤記錄下來，不需要改變程式架構，而且又有介面可以觀看，十分的方便；它從 WebForm 時代就有了，到了 MVC 也是運作的很好，那這邊就來介紹一下 Elmah 要如何在 ASP.NET Core 中使用 (.NET Core 也可使用)。</p>
<p>不過很可惜的，目前並沒有釋出官方的 Elmah for .NET Core，不過有一個新專案： <a target="_blank" href="https://github.com/ElmahCore/ElmahCore">ElmahCore</a> By <a target="_blank" href="https://github.com/barestan">@barestan</a>，到目前為止最後更新時間是 2017–12–08，希望還會繼續維護。</p>
<blockquote>
<p>有一網友 Fork 了專案持續維護：<a target="_blank" href="https://github.com/funky81/ElmahCore">https://github.com/funky81/ElmahCore</a>，推薦可以使用此版</p>
</blockquote>
<hr />
<h4 id="heading-6kit5a6a6iih5l255so">設定與使用</h4>
<p>首先先從 <a target="_blank" href="https://www.nuget.org/">Nuget</a> 安裝 <a target="_blank" href="https://www.nuget.org/packages/ElmahCore/">ElmahCore</a></p>
<blockquote>
<p>因為 Nuget 原作者已經沒有再更新了，所以推薦使用 <a target="_blank" href="https://github.com/funky81/ElmahCore">https://github.com/funky81/ElmahCore</a> 自己 Build 一版出來</p>
</blockquote>
<pre><code>Package Explorer: Install-Package ElmahCore
DotNet CLI: dotnet add package ElmahCore
</code></pre><p>安裝完畢後，於 <code>Startup.cs</code> 分別於 <code>ConfigureServices</code> 中加入 <code>service.AddElmah();</code> 與 <code>Configure</code> 中加入 <code>app.UseElamh();</code></p>
<p>這樣就設定完成了，夠簡單吧</p>
<hr />
<p>接下來我們就來直接測試一下，在 HomeController 中的 Index 裡，故意產生 Exception</p>
<p>執行後，並故意瀏覽錯誤頁面，就已經開始記錄例外了</p>
<p>預設的查看的介面網址為：<strong>https://{url}:{port}/elmah</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070456486/36bc8ee7-adcc-47a9-ae38-f1d92cbf2b9b.png" alt /></p>
<hr />
<h4 id="heading-5lul6z2i5lul57s5">介面介紹</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070458444/5b70b732-6641-440f-b81f-c089df1c1049.png" alt /></p>
<ol>
<li>RSS Feed: 讓你可以使用 RSS 來訂閱錯誤訊息，透過 RSS Reader 來接收每一筆最新例外資訊。</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070464122/ea0be9d9-3f44-4c1b-ae96-057c5d062630.png" alt /></p>
<ol start="2">
<li>RSS Digest: 同樣也是提供 RSS 訂閱，但是此 RSS 所提供的資訊為每日的例外狀態統整資訊。</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070465479/43f221bf-55c3-430e-8623-c5218491c4a9.png" alt /></p>
<ol start="3">
<li><p>Download log: 可以所有的 Log 匯出成 .csv 檔案，供使用別的軟體或工具進行分析，或是提供給開發人員處理。</p>
</li>
<li><p>Host: 發生例外錯誤的主機，如果系統是同時 RUN 在多台時，就可以快速分辨是哪一台主機產生了例外。</p>
</li>
<li><p>Code: 錯誤代碼。</p>
</li>
<li><p>Type: 例外類型。</p>
</li>
<li><p>User: 已登入的使用者，若發生的例外是在使用者已經登入的情況之下，它還可以把登入的使用者名稱列出來，以供日後追蹤。</p>
</li>
<li><p>Error: 例外詳細資訊，點 <code>Details</code> 可以看更多，甚至還有 Call Stack 以及相關變數，完全可以知道到底是哪個 Function 產生了例外</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070468151/f0b9fdcc-4394-446e-a32d-7e2f5bdca39b.png" alt /></p>
<hr />
<h4 id="heading-elmah">確保 Elmah 頁面安全</h4>
<p>在上面的範例中，Elmah 是可以公開被存取的，這肯定不合資訊安全，所以 Elmah 有提供了一點點的資訊安全</p>
<p>修改 Elmah 介面路徑
只需要在<code>Startup.cs</code> 之 <code>ConfigureServices</code> 加入 <code>service.AddElmah();</code> 時，加入相關設定即可完成</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070469498/062f5da5-62f0-4b76-a3c2-55ae222caa2d.png" alt /></p>
<p>不過很可惜的，現在看起來還沒登入驗證的支援，如果有興趣的或許可以去貢獻看看</p>
<hr />
<p>下一篇來介紹把 Log 放到不同的儲存體上，以及如何過濾 Log</p>
]]></content:encoded></item><item><title><![CDATA[[IT 鐵人賽] Azure Data Service - Day 04 - Cognitive Service - 辨識 - Video Indexer]]></title><description><![CDATA[Azure Data Service - Day 04 - Cognitive Service - Vision - Video Indexer

前面幾篇都是介紹靜態影像的辨識與分析，那這篇就來到針對影片來做處理。
Cognitive Service 針對影片辨識的部分提供了：Video Indexer
它整合了許多功能，在這邊列出一些比較重要的功能：

語系偵測
可以自動偵測出這個影片是屬於哪個語系，目前支援： English, Spanish, French, German, Italia...]]></description><link>https://blog.yu.money/it-azure-data-service-day-04-cognitive-service-video-indexer</link><guid isPermaLink="true">https://blog.yu.money/it-azure-data-service-day-04-cognitive-service-video-indexer</guid><dc:creator><![CDATA[Money Yu]]></dc:creator><pubDate>Fri, 19 Oct 2018 15:02:44 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070473207/6423fd4a-4041-4bb2-b918-4cfe3f9aea5e.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<hr />
<h4 id="heading-azure-data-service-day-04-cognitive-service-vision-video-indexer">Azure Data Service - Day 04 - Cognitive Service - Vision - Video Indexer</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070473207/6423fd4a-4041-4bb2-b918-4cfe3f9aea5e.png" alt /></p>
<p>前面幾篇都是介紹靜態影像的辨識與分析，那這篇就來到針對影片來做處理。</p>
<p>Cognitive Service 針對影片辨識的部分提供了：Video Indexer</p>
<p>它整合了許多功能，在這邊列出一些比較重要的功能：</p>
<ul>
<li>語系偵測
可以自動偵測出這個影片是屬於哪個語系，目前支援： English, Spanish, French, German, Italian, Chinese (Simplified), Japanese, Russian, and Portuguese (Brazilian)。</li>
<li>語音轉字幕
透過 Cognitive Service 語音轉文字的技術，將所有語音轉為字幕，並提供不同的字幕檔格式；如果影片的內容是屬於特殊領域或是發音較為特殊，也可以透過 Custom Speech 的方式來增進辨識率。</li>
<li>降噪
透過 Skype 的過濾器，濾除像是電話噪音或是背景雜音。</li>
<li>角色分析
可以知道哪個角色在何時說了那些話、語速如何，將這些資訊變成結構化資料提供搜尋。</li>
<li>文字辨識 (OCR)
透過 OCR 的方式辨識影片有出現的任何文字。</li>
<li>擷取品牌資訊
除了透過 OCR 辨識品牌文字以外，也會透過影像辨識品牌的 LOGO。</li>
</ul>
<blockquote>
<p>提供的功能實在很多，詳細請看：<a target="_blank" href="https://docs.microsoft.com/zh-tw/azure/cognitive-services/video-indexer/video-indexer-overview">https://docs.microsoft.com/zh-tw/azure/cognitive-services/video-indexer/video-indexer-overview</a></p>
<p>Video Indexer 是個 SaaS 服務，所以這次就沒有 Coding 的部分，但是它還是有提供 API 可以讓你自己來串接，從上傳檔案到取得分析完的結果。</p>
</blockquote>
<hr />
<p>我們直接開啟網站：<a target="_blank" href="https://www.videoindexer.ai/">https://www.videoindexer.ai/</a>，點選「登入」，如果沒有帳號就自己註冊啦</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070475741/43f80c17-592d-4589-ad2f-6ea3facec016.png" alt /></p>
<blockquote>
<p>直接免費試用，如果要付費再透過 Azure 付費就好</p>
</blockquote>
<p>登入完後就可以看到以下畫面</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070477428/7a13fa22-0062-49b1-a5de-d820ed939eda.png" alt /></p>
<p>我就使用 Microsoft Ignite 2018 的其中一段影片作為範例：<a target="_blank" href="https://www.youtube.com/watch?v=5quEOAM_jnc">https://www.youtube.com/watch?v=5quEOAM_jnc</a></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070479487/3d67c16b-fff9-4428-b760-6e761c1eb0b1.png" alt /></p>
<p>點選上傳來上傳影片檔案</p>
<ul>
<li>Video source language
可以手動選擇影片的語系，也可以切成自動偵測。</li>
<li>Privacy
選擇影片的隱私設定，分為公開跟私密。</li>
<li>Indexing preset
可以指定音訊要處理的方式，有 Default、Audio only 與 Noise reduction。</li>
<li>Streaming quality
選擇影片的編碼方式，有單一編碼、適應性編碼或者是不編碼。</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070481481/fcd99f4c-71cb-4ad4-91fc-27a7b6f06be1.png" alt /></p>
<p>按下送出後就會開始進行處理。</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070483513/1b08c625-07e8-4aa4-b1a5-7dfb984e02c6.png" alt /></p>
<p>處理完畢就回如上圖所顯示，直接點開 Play，來看看相關資訊。</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070485523/074ddcdf-0e75-41e9-a182-101acd0bc480.png" alt /></p>
<p>可以在上圖看到 Overview 介面，下面來一一介紹。</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070487905/ca959b46-1ced-414d-b004-31c32da50c2e.png" alt /></p>
<p>首先先來看看影片的播放介面，這就是一般常見的播放介面。</p>
<p>一號紅框是它轉換完成的字幕，英文基本上都是很準的。</p>
<p>二號紅框是影片編碼率，如果在編碼時就有指定自適應性編碼率，就可以有多個編碼品質可以選擇。</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070489434/cb827d61-c74b-48e3-b526-fb74065f8561.png" alt /></p>
<p>在人員區塊中，它會秀出所有有在影片中出現的人，如果是名人的話，甚至會自動幫你標記出他是誰，除此之外，在下方有一時間軸，有在影片中出現的時間都會標成黑色，點選後就影片就會自動跳到時間區段。</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070491563/301fb8e2-a333-4348-b37b-2e2b29111ac5.png" alt /></p>
<p>這邊會自動判斷出影片中所有的關鍵字，把它一一列出來，同樣的，下方也提供時間軸，有出現關鍵字的時間區段會標為黑色，點選後讓影片可以快進到該關鍵字出現的時間區段。</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070493339/59a29a24-eca8-4f5b-8566-ff06c8cdca93.png" alt /></p>
<p>這區是提供所有場景的 TAG 列表，同樣的會在下面時間軸顯示有出現的時間區段，點選後會自動跳的影片的該時間區段。</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070495393/d2021a7b-b5a7-455d-9886-c8adb3c6bff4.png" alt /></p>
<p>這邊會顯示所有有在影片裡面偵測到不論是文字或者是商標的品牌，都會顯示在這邊。</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070497394/ccc89e58-7495-4d4e-86f3-75a19d54f866.png" alt /></p>
<p>也會整合情緒偵測，偵測在影片的每個時間裡的情緒表現為何，把它做成時間軸來顯示。</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070499556/3f226d96-1c96-4074-83fe-e49567a63745.png" alt /></p>
<p>最後就是整合了智慧縮圖技術，它會自動尋找精彩焦點自動截圖。</p>
<hr />
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070501446/81825047-c0b4-45ae-bdf6-505594e10be3.png" alt /></p>
<p>切到另一個頁籤：「Timeline」，這邊主要就是依據時間一一把不論是字幕或者是有在影片中被辨認出來的關鍵字或人物顯示出來</p>
<hr />
<p><strong>小結</strong></p>
<p>透過上面的介紹，我們可以看到 Video Indexer 其實是把 Cognitive Service 所提供的不同服務集大成在這一個服務裡。</p>
<hr />
<p>下一篇來介紹一下針對影片與圖片所提供的「內容仲裁」服務。</p>
]]></content:encoded></item><item><title><![CDATA[[IT 鐵人賽] ASP.NET Core 與 Log 紀錄和追蹤的愛恨交織 - Day 03 - ASP.NET Core 內建之 Logger 02]]></title><description><![CDATA[.NET Core Logging- Logging in ASP.NET Core 02
上一篇已經介紹了 ASP.NET Core 內艦之 Logger 的簡單使用，那接下來就要進階一點了
來介紹一下 ASP.NET Core 內建之 Logger 如何透過設定檔來設定 Log 層級等相關組態與將 Log 輸出到不同地方

首先先來看要如何設定 Log 層級，在一般沒有任何設定也就是預設的情況下，預設 Log 層級是 Information，所以會在 Console 中顯示除了 Trace ...]]></description><link>https://blog.yu.money/it-aspnet-core-log-day-03-aspnet-core-logger-02</link><guid isPermaLink="true">https://blog.yu.money/it-aspnet-core-log-day-03-aspnet-core-logger-02</guid><dc:creator><![CDATA[Money Yu]]></dc:creator><pubDate>Thu, 18 Oct 2018 11:55:50 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070422200/bec68388-3c79-4c8d-b277-e6b4ae175891.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<hr />
<h4 id="heading-net-core-logging-logging-in-aspnet-core-02">.NET Core Logging- Logging in ASP.NET Core 02</h4>
<p>上一篇已經介紹了 ASP.NET Core 內艦之 Logger 的簡單使用，那接下來就要進階一點了</p>
<p>來介紹一下 ASP.NET Core 內建之 Logger 如何透過設定檔來設定 Log 層級等相關組態與將 Log 輸出到不同地方</p>
<hr />
<p>首先先來看要如何設定 Log 層級，在一般沒有任何設定也就是預設的情況下，預設 Log 層級是 Information，所以會在 Console 中顯示除了 Trace 和 Debug 以外所有的訊息，如下圖紅框顯示</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070422200/bec68388-3c79-4c8d-b277-e6b4ae175891.png" alt /></p>
<p>如果我們想要設定只有 Warning 以上才顯示，最簡單的方式就是直接在 <code>Program.cs</code> 的 <code>BuildWebHost</code> 方法中加入 <code>ConfigureLogging()</code> 設定</p>
<p>這樣最低 Log 層級就會被設為 Warning 以上</p>
<p>但是如果每次要更改 Log 層級都要修改程式碼，這樣也太擾人了，所以其實它還支援其他方式進行設定，包括透過設定檔的方式，設定方式如下：</p>
<ul>
<li>檔案格式 (INI、JSON 及 XML)。</li>
<li>命令列引數。</li>
<li>環境變數。</li>
<li>記憶體內部 .NET 物件。</li>
<li>未加密的<a target="_blank" href="https://docs.microsoft.com/zh-tw/aspnet/core/security/app-secrets?view=aspnetcore-2.1">祕密管理員</a>儲存體。</li>
<li>類似 <a target="_blank" href="https://docs.microsoft.com/zh-tw/aspnet/core/security/key-vault-configuration?view=aspnetcore-2.1">Azure Key Vault</a> 的加密使用者存放區。</li>
<li>自訂提供者 (已安裝或已建立)。</li>
</ul>
<p>預設就已經會讀取 <code>appsettings.json</code>中的 <code>Logging</code>區段設定組態</p>
<hr />
<p>除此之外還可以透過設定來進行 Log Filter 功能，這邊以<code>appsettins.json</code>為範例說明</p>
<p>在 Logging 區段中，分為 Debug、Console、LogLevel 三個，一一來說明</p>
<p>Debug 區段，Debug 在這邊代表的是輸出到 Debug Provider 中，有可能是 Debug 視窗或是 Debug 指定的容器</p>
<ul>
<li>Default: 簡單來說就是會套用到未明確列出條件的所有 Log
這邊就是記錄 Information 層級以上的 Log</li>
</ul>
<p>Console 區段，Console 在這邊代表的是輸出到 Console 中</p>
<ul>
<li>IncludeScopes: 用來設定是否啟用 <a target="_blank" href="https://docs.microsoft.com/zh-tw/aspnet/core/fundamentals/logging/?view=aspnetcore-2.1#log-scopes">L</a>ogScope，若為是則會將 LogScope 中所產生的 Log 輸出出來，若否則相反；LogScope 請參考：<a target="_blank" href="https://bit.ly/2PUO6Ws">https://bit.ly/2PUO6Ws</a></li>
</ul>
<p>LogLevel 用來設定相關紀錄層級</p>
<ul>
<li>Microsoft.AspNetCore.Hosting.Internal.WebHost: 當 Log 的來源之 namespace 為 Microsoft.AspNetCore.Hosting.Internal.WebHost 時，就會套用此條件
紀錄 Warning 層級以上的 Log</li>
<li>Microsoft.AspNetCore.Mvc.*: 當 Log 的來源之 namespace 為 Microsoft.AspNetCore.Mvc <strong>底下所有的 namespace</strong> 時 (包含 Microsoft.AspNetCore.Mvc )，就會套用此條件
紀錄 Warning 層級以上的 Log</li>
<li>System.*: 當 Log 的來源之 namespace 為 System <strong>底下所有的 namespace</strong> 時 (包含 System )</li>
<li>Default: 簡單來說就是會套用到未明確列出條件的所有 Log
這邊就是記錄 Warning 層級以上的 Log</li>
</ul>
<p>LogLevel 區段，假設上面都不符合的話，會套用到此條件</p>
<ul>
<li>Default: 簡單來說就是會套用到未明確列出條件的所有 Log
這邊就是記錄 Warning 層級以上的 Log</li>
</ul>
<blockquote>
<p>NOTE: 若 namespace 無 * 時，namespace 必須完全符合才會觸發規則
NOTE: 若都無指定時，預設 Log Filter 為記錄 Debug 以上所有 Log</p>
</blockquote>
<hr />
<p>若要修改設定所存放之地方，可以於 <code>Program.cs</code> 中的 <code>CreateWebHostBuilder</code>，加上 <code>ConfigureLogging</code> 相關設定，以下面為例，就是從 <code>CustomLogging</code> 區段中讀取 Log 設定</p>
<blockquote>
<p>也可以從其他檔案中讀取相關設定</p>
</blockquote>
<hr />
<p>最後來介紹要如何把 Log 輸出到不同的地方</p>
<p>ASP.NET Core 內建以下 Provider：</p>
<ul>
<li>Console</li>
<li>Debug</li>
<li>EventSource</li>
<li>EventLog</li>
<li>TraceSource (必須執行在 .NET Framework 中)</li>
<li>Azure App Service (會將 Log 輸出至診斷紀錄 (Diagnostics) 中，配合 App Service 中針對診斷紀錄的設定即可達成；例如輸出到儲存體)</li>
</ul>
<p>也有第三方提供者，參考：<a target="_blank" href="https://bit.ly/2zmZpRO">https://bit.ly/2zmZpRO</a></p>
<p>使用方式其實很簡單，只要在 <code>Program.cs</code> 中的 <code>CreateWebHostBuilder</code>，加上 <code>ConfigureLogging</code> 相關設定</p>
<hr />
<p>ASP.NET Core 內建 Logging 就介紹到此，下一篇將介紹使用 Elamh 來進行紀錄</p>
]]></content:encoded></item><item><title><![CDATA[[IT 鐵人賽] ASP.NET Core 與 Log 紀錄和追蹤的愛恨交織 - Day 02 - ASP.NET Core 內建之 Logger 01]]></title><description><![CDATA[.NET Core Logging- Logging in ASP.NET Core 01

ASP.NET Core 其實本身已經內建了一套 Log 工具，透過 DI 的方式注入，就可以直接取得並使用 Log 的物件實體，而且也可以外掛第三方的 Log 架構
方便的是 ASP.NET Core 預設就已經將 Logger 物件放入 DI 容器中了，所以不需要再額外進行設定，只要直接透過 DI 的方式取得 Logger 物件實體

Logger 物件提供了不同層級的 Log，共分為六種，定義在 ...]]></description><link>https://blog.yu.money/it-aspnet-core-log-day-02-aspnet-core-logger-01</link><guid isPermaLink="true">https://blog.yu.money/it-aspnet-core-log-day-02-aspnet-core-logger-01</guid><dc:creator><![CDATA[Money Yu]]></dc:creator><pubDate>Thu, 18 Oct 2018 11:53:11 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070382146/2114d364-34c0-4fd0-9c4e-a75718dd403a.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<hr />
<h4 id="heading-net-core-logging-logging-in-aspnet-core-01">.NET Core Logging- Logging in ASP.NET Core 01</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070382146/2114d364-34c0-4fd0-9c4e-a75718dd403a.png" alt /></p>
<p>ASP.NET Core 其實本身已經內建了一套 Log 工具，透過 DI 的方式注入，就可以直接取得並使用 Log 的物件實體，而且也可以外掛第三方的 Log 架構</p>
<p>方便的是 ASP.NET Core 預設就已經將 Logger 物件放入 DI 容器中了，所以不需要再額外進行設定，只要直接透過 DI 的方式取得 Logger 物件實體</p>
<hr />
<p>Logger 物件提供了不同層級的 Log，共分為六種，定義在 <a target="_blank" href="https://docs.microsoft.com/zh-tw/dotnet/api/microsoft.extensions.logging.loglevel?view=aspnetcore-2.1">LogLevel</a> 列舉中</p>
<ul>
<li>Trace = 0
通常是用來輸出在開發或是偵錯過程中想要看到的資訊。 這些訊息可能包含敏感資訊，因此不應該在正式環境中啟用。
<strong>預設為不輸出</strong>。
例如：<code>Credentials: {"User":"User", "Password":"P@ssw0rd"}</code></li>
<li>Debug = 1
通常是用來在正式環境中記錄一些除錯資訊。 由於此層級的 Log 數量可能很可觀，所以平常是不會開啟的，直到有需要時再開啟。
<strong>預設為不輸出</strong>。
例如：<code>Emergency flag set to true.</code></li>
<li>Information = 2
通常是用來追蹤應用程式的操作或是運作流程。
例如：<code>Request received for order id: 201809191111</code></li>
<li>Warning = 3
在應用程式流程中發生異常或意外事件。 這些記錄可能包含不會造成應用程式停止，但可能需要進行調查的錯誤或其他狀況。 已處理的例外狀況即為使用 <code>Warning</code> 記錄層級的常見位置。
例如：<code>FileNotFoundException for file quotes.txt.</code></li>
<li>Error = 4
發生無法處理的錯誤和例外狀況。 這些訊息會指出目前的活動或作業 (例如目前的 HTTP 要求） 中的失敗，而不是整個應用程式的失敗。
例如：<code>Cannot insert record due to duplicate key violation.</code></li>
<li>Critical = 5
發生需要立即注意的失敗。
例如：資料庫連線失敗、磁碟空間不足等情況。</li>
</ul>
<hr />
<p>如以下範例程式碼，直接宣告 Logger 物件，並透過 DI 容器注入，注意要引用 <code>using Microsoft.Extensions.Logging;</code> 命名空間，且 Logger 物件為泛型，所以要指定 Class 名稱，以此為例就是： <code>ILogger&lt;HomeController&gt;</code></p>
<p>寫完程式碼後，就可以執行來看看，先在 <code>terminal</code>中輸入 <code>dotnet run</code> 指令來進行編譯並把應用程式跑起來，跑起來後就可以直接呼叫網頁，最後在 <code>terminal</code> 中就可以看到 Log 的輸出結果</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070416914/c996e0de-40db-4175-b4e4-744e82bbdc8c.png" alt /></p>
<p>在上圖的第二步驟紅框中，就可以看到 Log 輸出的結果，針對不同層級也會有不同的顯示樣式</p>
<p>而在第二步驟的綠框中則是<strong>事件代碼</strong>，通常在系統中都會定義事件代碼
例如說：資料庫無法連線的錯誤代碼設定為 001</p>
<p>因此在寫入 Log 時也可以傳入事件代碼以供事後快速辨別</p>
<hr />
<p>還有一小部分要提到的是預設格式化訊息的方式，假設有 Log 事件如下</p>
<p>因其格式化的方式是依照參數的先後順序，而非於字串中的變數名稱而定
所以其輸出結果會為：name1 not match with: name2</p>
<hr />
<p>也可以將例外傳入到 Log 裡</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070418295/84a427c5-f8f1-4d08-b540-d91ff8a54a7f.png" alt /></p>
<hr />
<p>下一篇來介紹ASP.NET Core 內建之 Logger的組態設定、如何設定要記錄的 Log 層級以及如何輸出 Log 到不同的地方，而不是只是寫到 Console</p>
]]></content:encoded></item><item><title><![CDATA[[鐵人賽] Azure Data Service - Day 03 - Cognitive Service - 辨識 - Face API]]></title><description><![CDATA[[IT 鐵人賽] Azure Data Service - Day 03 - Cognitive Service - 辨識 - Face API
Azure Data Service - Day 03 - Cognitive Service - Vision - Face API

上一篇我們介紹了讓電腦看圖說故事，那這篇我們就要來介紹更需要具體細節的部分：Face API。
Cognitive Service 針對臉部辨識的部分提供了以下的功能

臉部驗證
檢查兩張臉部是屬於同一個人的可能性。...]]></description><link>https://blog.yu.money/azure-data-service-day-03-cognitive-service-face-api</link><guid isPermaLink="true">https://blog.yu.money/azure-data-service-day-03-cognitive-service-face-api</guid><dc:creator><![CDATA[Money Yu]]></dc:creator><pubDate>Thu, 18 Oct 2018 11:35:46 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070400179/8dfa5e88-5ce9-4762-b71a-b9959f57abe7.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<hr />
<h3 id="heading-it-azure-data-service-day-03-cognitive-service-face-api">[IT 鐵人賽] Azure Data Service - Day 03 - Cognitive Service - 辨識 - Face API</h3>
<h4 id="heading-azure-data-service-day-03-cognitive-service-vision-face-api">Azure Data Service - Day 03 - Cognitive Service - Vision - Face API</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070400179/8dfa5e88-5ce9-4762-b71a-b9959f57abe7.jpeg" alt /></p>
<p>上一篇我們介紹了讓電腦看圖說故事，那這篇我們就要來介紹更需要具體細節的部分：Face API。</p>
<p>Cognitive Service 針對臉部辨識的部分提供了以下的功能</p>
<ul>
<li>臉部驗證
檢查兩張臉部是屬於同一個人的可能性。API 會傳回信心分數，顯示兩張臉部是屬於同一個人的可能性。</li>
<li>臉部偵測
偵測影像中的一或多張人臉，並取得影像臉部位置所在的臉部矩形及臉部屬性，該屬性內含以機器學習為基礎的臉部特徵預測。可用的臉部屬性功能 包括：年齡、表情、性別、姿勢、微笑及鬍子，以及影像中每張臉部的 27 個地標。</li>
<li>表情辨識
臉部 API 現在與表情辨識整合，並傳回影像中每個臉部之一組表情的信心分數，例如生氣、藐視、厭惡、恐懼、快樂、不表意見、憂傷及驚奇。這些表情已知可跨文化普遍地與特定臉部表情溝通。</li>
</ul>
<hr />
<p><strong>範例網站介紹</strong></p>
<p>Face API 可以分成兩大部分，第一個是針對單一臉部做偵測，可以得知這些臉部的相關資訊，甚至是情緒的部分；另一個則是針對多個臉部，用來比對這多的臉部是否為相同人，簡單來說就是認臉。</p>
<p>我們先來看一下官網的範例，後面再來實際用程式動手做</p>
<ul>
<li><a target="_blank" href="https://azure.microsoft.com/zh-tw/services/cognitive-services/face/#detection">偵測影像中的臉部</a></li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070402778/ff8ac5a0-ac3b-4bb6-b1bd-0ec2a67ef3fe.png" alt /></p>
<p>這邊就用是大家的老婆：新垣結衣，來做為範例一下；這是一張「逃避可恥但有用」的劇照，可以看出它辨識出新垣結衣是女生，年紀只有 20 歲！不虧是大家的老婆；甚至還有是否有戴眼鏡以表情等資訊。</p>
<ul>
<li><a target="_blank" href="https://azure.microsoft.com/zh-tw/services/cognitive-services/face/#recognition">辨識影像中的情感</a></li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070404742/1ee236e7-61a1-4cba-bd18-89f962f219dc.png" alt /></p>
<p>在這個範例中就可以看到這是完全針對情緒的參數去做顯示，Cognitive Service 會給每個情緒都有一個分數，最高的分數通常就是結果；以這張來說，新垣結衣被判斷為目前表情情緒是中立。</p>
<ul>
<li><a target="_blank" href="https://azure.microsoft.com/services/cognitive-services/face/#verification">影像中類似臉部的辨識與分組</a></li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070406767/d4b2ead2-556d-45c3-b892-7c504c36af9c.png" alt /></p>
<p>這邊我特地找了「周杰倫」不同時期的照片來測試一下，左邊那張是近期的照片，右邊則是周杰倫超年輕時候的照片。</p>
<p>可以看到其實還是辨識的出來，只是信心程度沒有很高</p>
<blockquote>
<p>沒有說信心程度很低就為不可能，有可能正解的信心程度為 0.4，但是其他選項的信心程度只有 0.1，所以最佳解仍為正解。</p>
</blockquote>
<hr />
<p><strong>實際動手做</strong></p>
<p>介紹完範例後，又到了動手做時間，廢話已經說很多，就直接進入 Coding 階段吧</p>
<blockquote>
<p>在 Azure Portal 上建立 API Key 與新增專案的部分已於上一篇講解過，所以這邊就不騙篇幅了</p>
</blockquote>
<p>這次要新增：人臉辨識 API Key</p>
<p>新增完專案後，首先先來安裝 Nuget 套件：Microsoft.Azure.CognitiveServices.Vision.Face</p>
<p>此 Nuget 套件已經有實作 .NET Standard 所以 .NET Core 也可以使用</p>
<p>現在只有 Preview 版本，所以後面要指定版本號</p>
<pre><code>dotnet add package Microsoft.Azure.CognitiveServices.Vision.Face -v <span class="hljs-number">2.2</span><span class="hljs-number">.0</span>-preview
</code></pre><p>如果是使用 Package Explorer</p>
<pre><code>Install-Package Microsoft.Azure.CognitiveServices.Vision.Face -Version <span class="hljs-number">2.2</span><span class="hljs-number">.0</span>-preview
</code></pre><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070408443/a3bf3c64-3a6a-435e-be42-a8825121168f.png" alt /></p>
<ul>
<li>示範臉部偵測與表情辨識</li>
</ul>
<p>我這邊程式就直接使用從 Url 方式來拿到圖片的方式，這邊照片就使用剛剛的範例照片</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070410417/14cd03da-0873-4268-b606-c715a8bc253d.jpeg" alt /></p>
<p>先把相關變數設定好，像是 API Key 跟 ImageUrl，我把 apiKey 放在 appsettings.json 裡</p>
<p>接下來我們就把 <code>FaceClient</code> 給 New 起來，並根據 Azure Portal 上之資訊設定 <code>Endpoint</code></p>
<blockquote>
<p>因為這次安裝的 SDK 為 Preview 狀態，所以 EndPoint 不能這定成跟 Azure Portal 上顯示的一樣，要設為： https://[location].api.cognitive.microsoft.com/；參考：<a target="_blank" href="https://github.com/Azure/azure-sdk-for-net/issues/4534">https://github.com/Azure/azure-sdk-for-net/issues/4534</a></p>
</blockquote>
<p>設定完後，在把圖片送出去之前還有最後一步，就是設定你要取得那些資訊欄位，我在這邊就把所有的欄位加進來</p>
<p>都設定完成後，我們就可以把圖片送出去做辨識啦</p>
<p>結果如下</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070412523/9bd45ffc-f8b5-4599-aece-7a46c7418223.png" alt /></p>
<p>完整範例程式：<a target="_blank" href="https://github.com/MoneyYu/2019ItHelpData/tree/master/Day01-02%20Computer%20Vision">https://github.com/MoneyYu/2019ItHelpData</a></p>
<hr />
<p>下一篇來講影片索引器</p>
]]></content:encoded></item><item><title><![CDATA[Azure Data Service - Day 02 - Cognitive Service - 辨識 - Computer Vision - 01]]></title><description><![CDATA[[IT 鐵人賽] Azure Data Service - Day 02 - Cognitive Service - 辨識 - Computer Vision

在一般常用的 AI 領域中，電腦視覺肯定是非常常被使用的服務類型，而且其應用類型也很多，從最常見的人臉辨識到自訂的物件偵測等等。
當然我們可以自幹這些服務，但是因為這些服務太常見而且廣被應用，所以大部分雲端提供商都有提供已經建立好的模型直接可以使用，這樣我們就沒有必要花時間一直做別人做過的事情。

Cognitive Service 在...]]></description><link>https://blog.yu.money/azure-data-service-day-02-cognitive-service-computer-vision-01</link><guid isPermaLink="true">https://blog.yu.money/azure-data-service-day-02-cognitive-service-computer-vision-01</guid><dc:creator><![CDATA[Money Yu]]></dc:creator><pubDate>Thu, 18 Oct 2018 09:28:28 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070426158/e3ce3deb-bab4-4a5f-8746-815ab8137bdb.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<hr />
<h3 id="heading-it-azure-data-service-day-02-cognitive-service-computer-vision">[IT 鐵人賽] Azure Data Service - Day 02 - Cognitive Service - 辨識 - Computer Vision</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070426158/e3ce3deb-bab4-4a5f-8746-815ab8137bdb.png" alt /></p>
<p>在一般常用的 AI 領域中，電腦視覺肯定是非常常被使用的服務類型，而且其應用類型也很多，從最常見的人臉辨識到自訂的物件偵測等等。</p>
<p>當然我們可以自幹這些服務，但是因為這些服務太常見而且廣被應用，所以大部分雲端提供商都有提供已經建立好的模型直接可以使用，這樣我們就沒有必要花時間一直做別人做過的事情。</p>
<hr />
<p>Cognitive Service 在電腦視覺中提供了以下服務：</p>
<ul>
<li>分析影像
這項功能會傳回在影像中找到的視覺化內容資訊。使用標記、特定領域模型及四種語言描述，從容地識別內容並將其加上標籤。套用成人 / 猥褻設定，以協助您偵測潛在成人內容。識別圖片中的影像類型及色彩配置。</li>
<li>辨識名人和地標
辨識超過 200,000 名來自商業界、政界、體壇及娛樂圈的名人，以及世界各地 9,000 個自然與人工地標。</li>
<li>文字辨識
使用光學字元辨識 (OCR) 來偵測影像中的文字，然後將辨識出的字詞擷取到電腦可讀取的字元資料流中。分析影像，進而偵測內嵌的文字、產生字元資料流並啟用搜尋。替文字照相，省下複製文字所需的時間及精力。</li>
<li>近乎即時分析影片
近乎即時分析影片：從裝置擷取視訊框架，然後將其傳送至您所選的 API 呼叫，即可對您的視訊檔案使用任何一項電腦視覺 API。更快從影片取得結果。</li>
<li>產生縮圖
依據任何影像，產生高品質且具儲存體效益的縮圖，並修改影像以最符合您的大小、圖形和樣式需求。套用智慧裁剪，產生出外觀比例與原始影像不同的縮圖，同時保留所關注的區域。</li>
</ul>
<hr />
<p>在開始前，要先跟大家介紹一個觀念，就是：<strong>AI 幾乎沒有辦法 100% 的肯定它所辨認出來的結果是絕對正確</strong>，除非你拿的照片本來就是已經訓練過的照片也明確地跟它講這是甚麼東西。</p>
<p>因此你只要是在使用訓練完的模型所得到的結果，通常都會附上一個數值：<strong>信心程度</strong> (不同家會有不同的名字，意義相同)，它會給它所辨認出來的結果評一個分數，這個分數介於 0 ~ 1 之間，通常都不會看到 0 或 1，因為凡事都有可能，但是凡事也都有不可能。</p>
<p>所以在下面的範例中，都會看到一個欄位：confidence 或是 score，這都代表 AI 對於它所給出的結果之信心程度。</p>
<hr />
<p><strong>範例網站介紹</strong></p>
<p>簡單來說就是讓電腦來看圖說故事，他可以分析這張照片的內容並轉換為文字輸出回來，除了看圖說故事以外，如果圖片內含有人臉，它也會整合已經有的服務 (臉部辨識)，並把這些資訊一併輸出。</p>
<p>我們先來看一下官網的範例，後面再來實際用程式動手做</p>
<ul>
<li><a target="_blank" href="https://azure.microsoft.com/services/cognitive-services/computer-vision/#analyze">辨識影像中的場景及活動</a></li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070428735/7467142e-c23a-4150-b527-b7b10ee9854e.png" alt /></p>
<p>點開連結後，就會直接到範例網站裡</p>
<p>一號紅框是讓你看現在用的圖片是哪張，如果圖片裡有人臉，它也會在上面把人臉標記出來，並顯示相關資訊。</p>
<p>二號紅框則是辨識完後的結果檢視，Cognitive Service 辨識完後都會將結果用 JSON 格式回傳，而這邊就是把 JSON 結果視覺化出來，讓您看有哪些參數可以使用。</p>
<p>三號紅框則是讓你選擇範例圖片或是你也可以用自己的圖片，不論是透過 URL 或是電腦上傳的方式均可。</p>
<p>可以看到說明欄位裡有一屬性：text，這就是它會把它變成一句話來說明這張圖片，例如：a group of people posing for a photo</p>
<ul>
<li><a target="_blank" href="https://azure.microsoft.com/services/cognitive-services/computer-vision/#celebrities-landmarks">辨識影像中的名人與地標</a></li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070430483/ec684a23-ae60-493b-aaf3-1d3cb21bae20.png" alt /></p>
<p>這個服務可以拿來辨識全球大部分名人，像上面的圖片我就是自己上傳一張「周杰倫」的照片為範例，可以在右邊的 JSON 結果上看到它也正確的辨認出了他就是周杰倫，除了人以外，地標也是可以的，範例網站上有一張羅馬競技場的照片，他也的確辨認的出來，我這邊就不再多做截圖了。</p>
<ul>
<li><a target="_blank" href="https://azure.microsoft.com/services/cognitive-services/computer-vision/#text">影像中的光學字元辨識 (OCR)</a></li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070432731/5836383c-09eb-4b7d-b2b1-08cd11f8dd00.png" alt /></p>
<p>就是很常見的文字辨識，OCR 的全名是 Optical Character Recognition，光學字元辨識，在這服務它使用了深度學習演算法，提供了更好的辨識率，像是大小字等等，已經<strong>支援中文辨識，但是，目前辨識率沒有很好</strong>。</p>
<ul>
<li><a target="_blank" href="https://azure.microsoft.com/zh-tw/services/cognitive-services/computer-vision/#handwriting">手寫辨識</a></li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070434752/f5ffe905-8fc2-43da-b2f1-0e8f0db0a765.png" alt /></p>
<p>其實就還是文字辨識，只是有針對手寫的字跡做調教。</p>
<hr />
<p><strong>實際動手做</strong></p>
<p>Cognitive Service 提供了 C#、Node.js、Python、Java 與 Ruby SDK (服務涵蓋範圍略有不同)，如果你所愛的語言不在上面，不用擔心，Cognitive Service 全程提供的 RESTful API 使用，其實 SDK 也只是幫你把呼叫 RESTful API 的動作包起來而已。</p>
<blockquote>
<p>如果沒有對應的 SDK 可以參考：<a target="_blank" href="https://westus.dev.cognitive.microsoft.com/docs/services/5adf991815e1060e6355ad44/operations/56f91f2e778daf14a499e1fa">https://westus.dev.cognitive.microsoft.com/docs/services/5adf991815e1060e6355ad44/operations/56f91f2e778daf14a499e1fa</a></p>
</blockquote>
<p>在開始前，我們要先到 Azure Portal 上建立一個「電腦視覺 API」資源</p>
<blockquote>
<p>也可以直接在 Cognitive Service 點選「免費試用」</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070436460/5ff3442c-ad86-414d-b35d-9b456d1becc4.png" alt /><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070438649/4c68f7df-0466-4eaf-b1bb-3bddd460b052.png" alt /></p>
<ol>
<li>點選建立資源</li>
<li>於搜尋中輸入：「Computer Vision」</li>
<li>點選「電腦視覺」</li>
<li>點選「建立」</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070440428/b354bcbe-d9e0-46e2-b812-730980fa649e.png" alt /></p>
<p>填寫相關資訊後點選建立</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070442349/1d063334-6637-4a2a-ba36-59efc0623ced.png" alt /></p>
<p>建立完成後，我們需要取得金鑰(Key)，按照上圖步驟來開啟金鑰頁面，取得金鑰後，我們先暫時存著，等等會用到。</p>
<p>接下來就輪到程式部分啦，這邊為了方便起見，我的專案類型使用 Console 專案，實際上任何專案類型都不會有影響。</p>
<p>先在命令列上輸入 <code>dotnet new console</code> 來新增 Console 專案</p>
<p>新增完專案後，第一件事就是來安裝相關的 Nuget 套件：Microsoft.Azure.CognitiveServices.Vision.ComputerVision</p>
<p>此 Nuget 套件已經有實作 .NET Standard 所以 .NET Core 也可以使用</p>
<pre><code>dotnet add package Microsoft.Azure.CognitiveServices.Vision.ComputerVision
</code></pre><p>如果是使用 Package Explorer</p>
<pre><code>Install-Package Microsoft.Azure.CognitiveServices.Vision.ComputerVision
</code></pre><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070444617/cad26637-f023-418d-9949-684bd98b0df8.png" alt /></p>
<p>我這邊程式就直接使用 Url 方式來拿到圖片，就不示範存取本機圖片了</p>
<p>先把相關變數設定好，像是 API Key 跟 ImageUrl，我把 apiKey 放在 appsettings.json 裡，圖片我就偷懶用一下蘋果日報的圖片</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070446288/dca29578-bd2f-4730-9255-c0583ae82202.jpeg" alt /></p>
<p>接下來我們就把 <code>ComputerVisionClient</code> 給 New 起來，並根據 Azure Portal 上之資訊設定 <code>Endpoint</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070448461/c1066597-e543-4920-9bc3-3da74377f918.png" alt /></p>
<p>設定完後，在把圖片送出去之前還有最後一步，就是設定你要取得那些資訊欄位，我在這邊就只設定四個欄位</p>
<p>詳細欄位資訊如下</p>
<p>都設定完成後，我們就可以把圖片送出去做辨識啦</p>
<p>結果如下</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070450306/85d72d29-09c6-4409-bd95-7262c275d611.png" alt /></p>
<blockquote>
<p>影片分析其實也是使用相同的方式，只是要將影片切成 Frame，然後再送出去做辨識</p>
</blockquote>
<p>完整範例程式：<a target="_blank" href="https://github.com/MoneyYu/2019ItHelpData/tree/master/Day01-02%20Computer%20Vision">https://github.com/MoneyYu/2019ItHelpData</a></p>
]]></content:encoded></item><item><title><![CDATA[Azure Data Service - Day 01 - Intro]]></title><description><![CDATA[[IT 鐵人賽] Azure Data Service - Day 01 - Intro
Azure Data Service - Day 01 - Introduction
現在 AI 當道，但是在 AI 的背後其實還是由 Big Data 所組成的，俗話說的好：「沒有 Data 就沒有 AI」。
當然在這現代分工非常明確與細緻的時代，我們沒有必要全部都自己來，往大了說可以專精 Data，AI 的部分就交給別人來做，反之亦然。甚至你都不需要懂，也是有直接現成好的服務提供使用。


Micros...]]></description><link>https://blog.yu.money/azure-data-service-day-01-intro</link><guid isPermaLink="true">https://blog.yu.money/azure-data-service-day-01-intro</guid><dc:creator><![CDATA[Money Yu]]></dc:creator><pubDate>Mon, 15 Oct 2018 16:46:47 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070396300/68ec465f-97f9-42a7-9dc5-b974ac8c5b54.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<hr />
<h3 id="heading-it-azure-data-service-day-01-intro">[IT 鐵人賽] Azure Data Service - Day 01 - Intro</h3>
<h4 id="heading-azure-data-service-day-01-introduction">Azure Data Service - Day 01 - Introduction</h4>
<p>現在 AI 當道，但是在 AI 的背後其實還是由 Big Data 所組成的，俗話說的好：「沒有 Data 就沒有 AI」。</p>
<p>當然在這現代分工非常明確與細緻的時代，我們沒有必要全部都自己來，往大了說可以專精 Data，AI 的部分就交給別人來做，反之亦然。甚至你都不需要懂，也是有直接現成好的服務提供使用。</p>
<hr />
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070396300/68ec465f-97f9-42a7-9dc5-b974ac8c5b54.png" alt /></p>
<p>Microsoft Azure 身為一個正統雲端服務提供商，當然也提供了許多相關類型的服務，我在這邊統一稱為 Azure Data Service。</p>
<p>從最基本的數據儲存開始，例如：</p>
<ul>
<li>Azure SQL Database</li>
<li>Azure SQL Database for MySQL</li>
<li>Azure SQL Database for MariaDB</li>
<li>等等</li>
</ul>
<p>到儲存極大數據與不同類型資料的服務：</p>
<ul>
<li>Azure Cosmos DB</li>
<li>Azure Data Lake</li>
<li>等等</li>
</ul>
<p>有了數據以後就可以開始使用這些數據進行機器學習的訓練，Azure 所提供的相關服務有：</p>
<ul>
<li>Azure Machine Learning Studio</li>
<li>HDInsight</li>
<li>Azure Databricks</li>
<li>等等</li>
</ul>
<blockquote>
<p>Azure Machine Learning Studio 跟 HDInsight 看起來已經有大大的主題是這一塊了，所以我到時候應該不會著墨太多。</p>
</blockquote>
<p>另外還有剛剛提到的已經建立好的服務直接提拱給你使用：Cognitive Service，他提供了許多面向類型：</p>
<ul>
<li>辨識
可聰明地識別、標示及 控管圖片的影像處理演算法。</li>
<li>語音
將語音轉換成文字、使用語音來驗證，或將說話者 辨識新增至您的應用程式。</li>
<li>知識
對應複雜資訊和資料，以解決 智慧建議和語意搜尋等工作。</li>
<li>搜尋
將 Bing 搜尋 API 新增至您的應用程式，並充分利用 以單一 API 呼叫合併數十億個網頁、影像、影片和新聞的能力。</li>
<li>語言
讓您的應用程式能夠透過預先建置的指令碼處理自然語言、 評估情感，以及了解如何辨識使用者想要的項目。</li>
</ul>
<p>我會首先詳細介紹與使用 Cognitive Service，再來的話回到 Data 相關，最後就是關於機器學習的部分；如果還有多的時間的話，還可以介紹一下擁有 GPU 的虛擬機器類型。</p>
<p>在這 30 天內，透過撰寫不同服務類型的文章，期許我自己可以從一個 Data、AI 雙白，轉變成小白。</p>
]]></content:encoded></item><item><title><![CDATA[[IT 鐵人賽] ASP.NET Core 與 Log 紀錄和追蹤的愛恨交織 - Day 01   - 前言]]></title><description><![CDATA[.NET Core Logging - Intro

.NET Core
我想大部分的程式開發者都有遇到過一種情況，別人所開發撰寫的程式，平時運行的好好的，突然就在某一刻出現了 Bug，很不幸的維護的責任剛好落在自己身上，到處求助無門，連系統架構都還不太明瞭，無法知道問題到底會出在哪，測試環境也無法重現問題，這時突然發現在記錄檔中有紀錄使用者於正式環境中的操作與錯誤紀錄，終於知道問題出在哪並順利的修復了 Bug；透過此情境大家都可以了解 Log 的重要性，他平常或許不重要，但是到了需要用到時，絕...]]></description><link>https://blog.yu.money/it-aspnet-core-log-day-01</link><guid isPermaLink="true">https://blog.yu.money/it-aspnet-core-log-day-01</guid><dc:creator><![CDATA[Money Yu]]></dc:creator><pubDate>Mon, 15 Oct 2018 16:08:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070380125/cd45a645-dd46-4dc3-a005-1fdafd5ca919.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<hr />
<h4 id="heading-net-core-logging-intro">.NET Core Logging - Intro</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070380125/cd45a645-dd46-4dc3-a005-1fdafd5ca919.png" alt /></p>
<p>.NET Core</p>
<p>我想大部分的程式開發者都有遇到過一種情況，別人所開發撰寫的程式，平時運行的好好的，突然就在某一刻出現了 Bug，很不幸的維護的責任剛好落在自己身上，到處求助無門，連系統架構都還不太明瞭，無法知道問題到底會出在哪，測試環境也無法重現問題，這時突然發現在記錄檔中有紀錄使用者於正式環境中的操作與錯誤紀錄，終於知道問題出在哪並順利的修復了 Bug；透過此情境大家都可以了解 Log 的重要性，他平常或許不重要，但是到了需要用到時，絕對是超級重要的一件事。</p>
<p>Log 是甚麼？</p>
<p>簡單來說 Log 就是系統在操作時所產生的記錄。有可能是一般的操作紀錄或是發生錯誤的紀錄；俗話說：「凡走過必留下痕跡」，收集並分析 Log ，可讓維運或是開發人員監控系統的運作狀態，並判斷即將發生之事件，或是當發生錯誤時，可以立即通知相關人員。</p>
<hr />
<p>寫 Log 有那些好處呢</p>
<ul>
<li>快速偵錯
當發生問題時，可以透過 Log 知道到底是哪裡錯誤，若有紀錄 CallStack 的話還可以得知是哪個 Function 在哪一行發生例外</li>
<li>重現錯誤步驟
要修正問題前有一個必要步驟就是重現問題，但是有時候要發生某種例外需要特定的步驟或條件，若有 Log 紀錄使用者操作紀錄，就可以按照 Log 紀錄重現問題</li>
<li>效能調教
當有效能問題時，Log 通常都會有時間戳記，因此可以先觀看每項工作運行所花費時間，再從耗費最久部分開始處理</li>
</ul>
<hr />
<p>這 30 天會針對以下的 Log 工具進行介紹與使用方式說明</p>
<ul>
<li><a target="_blank" href="https://docs.microsoft.com/zh-tw/aspnet/core/fundamentals/logging/?view=aspnetcore-2.1">ASP.NET Core 內建之紀錄工具</a></li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070382146/2114d364-34c0-4fd0-9c4e-a75718dd403a.png" alt /></p>
<ul>
<li><a target="_blank" href="https://elmah.github.io/">Elmah</a></li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070384385/0ceb072e-c897-46f6-a609-f7910f83514a.png" alt /></p>
<ul>
<li><a target="_blank" href="https://logging.apache.org/log4net/">log4net</a></li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070386325/8e98dd7f-d270-4582-abd0-90612d6726fb.jpeg" alt /></p>
<ul>
<li><a target="_blank" href="https://nlog-project.org/">NLog</a></li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070388249/5d389cbd-de87-4b45-b622-7b1ce5f397a7.png" alt /></p>
<ul>
<li><a target="_blank" href="https://docs.microsoft.com/zh-tw/azure/application-insights/app-insights-overview">Application Insight</a></li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070390232/067b807f-443d-4615-b655-a3e5aeab3910.png" alt /></p>
<ul>
<li><a target="_blank" href="https://serilog.net/">SeriLog</a></li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070392351/4d3b3448-9553-44b2-a8ad-ce19f975815d.png" alt /></p>
<hr />
<p>下一篇會介紹 ASP.NET Core 內建之紀錄工具</p>
]]></content:encoded></item><item><title><![CDATA[Visual Studio 無法啟動 IIS Express Server 問題]]></title><description><![CDATA[Visual Studio Unable to launch the IIS Express Web server
最近時常在兩台電腦間交互辦公，一台在家裡一台是筆電，檔案用 OneDrive 自動同步，所以我每次打開電腦就可以立刻接上另外一台電腦的進度立刻開始辦公
最近開始遇到一個奇怪的問題就是偶爾 Visual Studio 無法啟動 IIS Express Server 開始進行偵錯，都會出現以下錯誤畫面

首先最快也最簡單的方式就是先把 Visual Studio 重開看看
不型的話則先...]]></description><link>https://blog.yu.money/visual-studio-iis-express-server</link><guid isPermaLink="true">https://blog.yu.money/visual-studio-iis-express-server</guid><dc:creator><![CDATA[Money Yu]]></dc:creator><pubDate>Wed, 05 Sep 2018 03:21:02 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070374150/ef8fe627-955a-4269-984d-840906c07c20.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<hr />
<h4 id="heading-visual-studio-unable-to-launch-the-iis-express-web-server">Visual Studio Unable to launch the IIS Express Web server</h4>
<p>最近時常在兩台電腦間交互辦公，一台在家裡一台是筆電，檔案用 OneDrive 自動同步，所以我每次打開電腦就可以立刻接上另外一台電腦的進度立刻開始辦公</p>
<p>最近開始遇到一個奇怪的問題就是偶爾 Visual Studio 無法啟動 IIS Express Server 開始進行偵錯，都會出現以下錯誤畫面</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070374150/ef8fe627-955a-4269-984d-840906c07c20.png" alt /></p>
<p>首先最快也最簡單的方式就是先把 Visual Studio 重開看看</p>
<p>不型的話則先透過 netstat 來判斷是否網站要使用的 port 已被占用</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070376464/ca28bc75-df69-49c8-b465-08e9c6da2209.png" alt /></p>
<p>netstat</p>
<p>透過 netstat 指令查詢後，可以發現指定的 port 並沒有被占用，所以不會是 port 的問題</p>
<pre><code># 也可以透過以下指令只看特定 port 的清單
netstat -ao | findstr &lt;port_number_to_search_for&gt;
</code></pre><p>再來的話，也是我這情況的原因就是 applicationhost.config 被鎖住了</p>
<p>先到 <code>{ProjectSource}\.vs\config</code> 資料夾中，將 <code>applicationhost.config</code> 此檔案刪除掉</p>
<p>最後再打開 Visual Studio 開始執行，就可以正常工作了</p>
<blockquote>
<p>備註：若刪除此檔案還不行，可以嘗試刪除 <code>Users/&lt;username&gt;/Documents/IISExpress/config</code> 下的 <code>applicationhost.config</code></p>
<p>若是專案放置於 One Drive 目錄下，可以先試試將 One Drive 關閉，然後砍掉 <code>applicationhost.config</code> <em>在開啟 Visual Studio 方式，有時會是 One Drive 導致的問題</em></p>
</blockquote>
<h4 id="heading-5yd6icd">參考</h4>
<p>[<strong>How to solve IIS issue in visual studio?</strong>
<em>This site uses cookies to deliver our services and to show you relevant ads and job listings. By using our site, you…</em>stackoverflow.com](https://stackoverflow.com/questions/29116292/how-to-solve-iis-issue-in-visual-studio "https://stackoverflow.com/questions/29116292/how-to-solve-iis-issue-in-visual-studio")</p>
]]></content:encoded></item><item><title><![CDATA[Surface 系列螢幕 3:2 低解析度選項]]></title><description><![CDATA[Surface Device Display Resolution 3:2 Alternate Options

我手頭上有兩台 Surface 裝置，Surface Pro 4 與 Surface Book 2，Surface 裝置的螢幕我覺得實在很不錯，PixelSense 是個好東西，不過對我來說有時候螢幕解析度太高也是個困擾，除了介面元素都會變小以外，也會稍微多耗點資源，所以我通常都習慣把解析度調低一點
不過 Surface 系列螢幕比例通常是 3:2，而 Windows 現在沒有辦法很...]]></description><link>https://blog.yu.money/surface-32</link><guid isPermaLink="true">https://blog.yu.money/surface-32</guid><dc:creator><![CDATA[Money Yu]]></dc:creator><pubDate>Tue, 04 Sep 2018 08:53:09 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070366330/229e42c9-7910-4b5e-832a-202647e44a16.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<hr />
<h4 id="heading-surface-device-display-resolution-32-alternate-options">Surface Device Display Resolution 3:2 Alternate Options</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070366330/229e42c9-7910-4b5e-832a-202647e44a16.jpeg" alt /></p>
<p>我手頭上有兩台 Surface 裝置，Surface Pro 4 與 Surface Book 2，Surface 裝置的螢幕我覺得實在很不錯，PixelSense 是個好東西，不過對我來說有時候螢幕解析度太高也是個困擾，除了介面元素都會變小以外，也會稍微多耗點資源，所以我通常都習慣把解析度調低一點</p>
<p>不過 Surface 系列螢幕比例通常是 3:2，而 Windows 現在沒有辦法很好的支援，所以找不到低 3:2 解析度選項，這邊就就介紹如何把這些解析度加入選項</p>
<p>其實有兩種方式，第一種方式是透過 Intel 繪圖驅動程式修改，第二種則是透過修改機碼，這邊先介紹第二種方式，方便又快速</p>
<h4 id="heading-6ycp6ygo5lu5ps55qmf56k85pa55byp">透過修改機碼方式</h4>
<p>首先先下載此 reg 檔案：<a target="_blank" href="http://bit.ly/2Q3SEdX">http://bit.ly/2Q3SEdX</a></p>
<p>下載完成後開啟此機碼檔案</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070368482/8e5880e5-789d-48f7-8ac1-006e8eec74d9.png" alt /></p>
<p>點選確定執行(若對檔案內容有疑慮的話就請不要執行)</p>
<p>執行完畢後，請重新開機</p>
<p>這樣解析度選項應該就會有很多 3:2 的選項</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070370578/37fe8029-f5bc-432a-a98d-c127aa61cb6c.png" alt /></p>
<h4 id="heading-5yd6icd">參考</h4>
<p>[<strong>Surface [Book/Book2/Pro3/Pro4/Pro2017] - high-dpi multi-monitor optimization regkey for alternate…</strong>
<em>Setting up a live Surface demo using the scaling tweak and Vertical Surface Docks at the Seattle Maker Faire (EMP…</em>dancharblog.wordpress.com](https://dancharblog.wordpress.com/2015/10/26/surface-book-and-surface-pro-4-high-dpi-multi-monitor-optimization-regkey-for-alternate-32-aspect-ratio-resolutions/ "https://dancharblog.wordpress.com/2015/10/26/surface-book-and-surface-pro-4-high-dpi-multi-monitor-optimization-regkey-for-alternate-32-aspect-ratio-resolutions/")</p>
]]></content:encoded></item><item><title><![CDATA[Microsoft Library Manager - VS 15.8 版本新樣貌]]></title><description><![CDATA[Microsoft Library Manager — VS 15.8 New Look
Microsoft Library Manager 隨著 Visual Studio 15.8 一起正式發布了，之前也撰寫了一篇完整的介紹文，然而隨著新版的發布，也增加了一些功能，所以這邊再來介紹一下新增加的功能
首先最明顯的是新增了 GUI 介面，在資料夾上按右鍵 -> 新增 -> Client-Side Library，就會出現 GUI 視窗

Add Client Side Library Menu
...]]></description><link>https://blog.yu.money/microsoft-library-manager-vs-158</link><guid isPermaLink="true">https://blog.yu.money/microsoft-library-manager-vs-158</guid><dc:creator><![CDATA[Money Yu]]></dc:creator><pubDate>Mon, 03 Sep 2018 08:06:15 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070354447/52c104ea-f462-4b74-bd16-c63937ae30d9.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<hr />
<h4 id="heading-microsoft-library-manager-vs-158-new-look">Microsoft Library Manager — VS 15.8 New Look</h4>
<p>Microsoft Library Manager 隨著 Visual Studio 15.8 一起正式發布了，之前也撰寫了一篇完整的<a target="_blank" href="https://blog.developer.money/asp-net-core-%E7%AE%A1%E7%90%86%E5%89%8D%E7%AB%AF%E5%A5%97%E4%BB%B6%E7%9A%84%E6%96%B0%E5%A5%BD%E5%B7%A5%E5%85%B7-microsoft-library-manager-a0acbd4be058">介紹文</a>，然而隨著新版的發布，也增加了一些功能，所以這邊再來介紹一下新增加的功能</p>
<p>首先最明顯的是新增了 GUI 介面，在資料夾上按右鍵 -&gt; 新增 -&gt; Client-Side Library，就會出現 GUI 視窗</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070354447/52c104ea-f462-4b74-bd16-c63937ae30d9.png" alt /></p>
<p>Add Client Side Library Menu</p>
<p>你可以在此視窗選擇 Provider，與輸入 Library 名稱，Library 名稱現在也支援自動完成了，選擇完 Library 名稱後，輸入 <code>@</code> 也會出現版本的選擇提示</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070356573/42116c23-bbd3-482e-b38c-7ce4c1f79d36.png" alt /></p>
<p>Enter Library Name</p>
<p>可以透過此視窗選擇要下載哪些檔案，預設是會自動下載所有檔案，也可以勾選要下載的檔案</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070358292/131f3c25-500e-47e1-9b60-4c067b1d74fe.png" alt /></p>
<p>Include File</p>
<p>最後是 Target Location，他預設已經幫你選好檔案路徑，當然也可以修改想要的名稱</p>
<p>第二個新功能是提供了新的 Provider: UnPkg，讓你有新的選擇，UnPkg 是建立在 NPM 基礎上，所以有更多 Library 可以選擇使用</p>
<p>最後一個是新增了 CLI 介面，可以透過 Nuget 或是 Package Manager Console安裝 <code>Microsoft.Web.LibraryManager.Cli</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070360332/0febbdf4-617e-4f6d-9376-7bd1c81b22d7.png" alt /></p>
<pre><code>dotnet tool install -g Microsoft.Web.LibraryManager.Cli
</code></pre><p>安裝完後就可以用 Command Line 來進行 LibMan 的管理了，這邊偷懶用官方的圖</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070362427/a6e8d964-7138-4296-b592-94ce2ca7f105.png" alt /></p>
<h4 id="heading-5yd6icd">參考</h4>
<p>[<strong>Library Manager Released in 15.8</strong>
<em>NET web development and tools at Microsoft</em>blogs.msdn.microsoft.com](https://blogs.msdn.microsoft.com/webdev/2018/08/31/library-manager-release-in-15-8/ "https://blogs.msdn.microsoft.com/webdev/2018/08/31/library-manager-release-in-15-8/")</p>
]]></content:encoded></item><item><title><![CDATA[Microsoft Library Manager - ASP.NET Core 管理前端套件的新好工具]]></title><description><![CDATA[Microsoft Library Manager - A new good tool to manage client-side library for ASP.NET Core
之前為了 Bower 半生不死寫了一篇替代文章：ASP.NET Core 將 NPM Package 檔案複製到 wwwroot/lib 底下，但是總決還是有點不方便，每透過 npm 安裝新的套件都還要手動改一下設定檔，要做兩次動作
後來發現了一個尚未正式釋出的新專案：Microsoft Library Manage...]]></description><link>https://blog.yu.money/microsoft-library-manager-aspnet-core</link><guid isPermaLink="true">https://blog.yu.money/microsoft-library-manager-aspnet-core</guid><dc:creator><![CDATA[Money Yu]]></dc:creator><pubDate>Wed, 15 Aug 2018 09:09:42 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070338133/8d956467-7af0-4b63-9a30-5620083c2e14.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<hr />
<h4 id="heading-microsoft-library-manager-a-new-good-tool-to-manage-client-side-library-for-aspnet-core">Microsoft Library Manager - A new good tool to manage client-side library for ASP.NET Core</h4>
<p>之前為了 Bower 半生不死寫了一篇替代文章：<a target="_blank" href="https://blog.developer.money/asp-net-core-%E5%B0%87-npm-package-%E6%AA%94%E6%A1%88%E8%A4%87%E8%A3%BD%E5%88%B0-wwwroot-lib-%E5%BA%95%E4%B8%8B-810ff6e47387">ASP.NET Core 將 NPM Package 檔案複製到 wwwroot/lib 底下</a>，但是總決還是有點不方便，每透過 npm 安裝新的套件都還要手動改一下設定檔，要做兩次動作</p>
<p>後來發現了一個尚未正式釋出的新專案：<a target="_blank" href="https://github.com/aspnet/LibraryManager">Microsoft Library Manager</a>，初步使用覺得還不錯，解決了大部分後端開發者需要管理前端套件的需求且也不會太複雜；而且前一篇文章竟然被認識的人發現，只好來補一下功課</p>
<p>首先，<a target="_blank" href="https://github.com/aspnet/LibraryManager">Microsoft Library Manager</a> 因為尚未正式釋出，所以沒有內建在 Visual Studio 內，也沒有在 Visual Studio Marketplace 內；必須自己下載專案回來 Build 或是使用 <a target="_blank" href="https://ci.appveyor.com/project/aspnetci/librarymanager/branch/master/artifacts">CI 自動 Build 完的 Vsix</a>，但是要注意，目前專案設定是針對 VS 15.8 Preview 做建置(15.8 以後應該就內建了)，導致無法於 VS 15.7 上安裝，需要額外調整個設定，這邊請看下一篇文章：<a target="_blank" href="https://blog.developer.money/%E9%87%9D%E5%B0%8D-visual-studio-15-7-%E4%BB%A5%E4%B8%8B%E4%B9%8B%E7%89%88%E6%9C%AC%E5%BB%BA%E7%BD%AE-microsoft-library-manager-vsix-d057ef5a5bf2">針對 Visual Studio 15.7 以下之版本建置 Microsoft Library Manager.vsix</a></p>
<blockquote>
<p>備註：LibMan 不是用來取代 npm/yarn 的，我覺得主要是針對後端開發者只是需要用到些微管理前端相關 library，而非重度前端開發者</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070338133/8d956467-7af0-4b63-9a30-5620083c2e14.png" alt /></p>
<p>進入正題，安裝完 <a target="_blank" href="https://blog.developer.money/%E9%87%9D%E5%B0%8D-visual-studio-15-7-%E4%BB%A5%E4%B8%8B%E4%B9%8B%E7%89%88%E6%9C%AC%E5%BB%BA%E7%BD%AE-microsoft-library-manager-vsix-d057ef5a5bf2">Microsoft Library Manager.vsix</a> 後，於專案上點選右鍵即可看到 <strong>Manage Client-Side Libraries</strong> 選項，點選後即可看到於專案上會新增一檔案 <code>libman.json</code>，並已自動開啟</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070340290/43a057ee-a63f-46b0-8c47-af4cfee83a89.png" alt /><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070342422/1c060653-bae0-4682-9ec7-6f9eabf6ee28.png" alt /></p>
<p>此檔案結構為 json，預設有三個屬性，以下說明一下</p>
<h4 id="heading-version-string">version (可選): String</h4>
<p>用來指定 <code>libman.json</code> 之語法版本，目前只有 1.0 可用 (擷至 2018/08/15)</p>
<h4 id="heading-defaultprovider-string">defaultProvider (可選): String</h4>
<p>用來指定前端套件預設來源，雖然說是可以選，但是因為通常我們套件來源都是固定的，因此推薦一定要有，預設是從 cdnjs 讀取資料，還有 File System 可以用</p>
<h4 id="heading-libraries-object-array">libraries(必填): Object Array</h4>
<p>前端套件列表，用來列出所有受管理的套件與其設定，物件內容詳細說明請參照下說</p>
<p>首先我們先來看一下範例 <code>libman.json</code></p>
<p>其中可以看到多了 defaultDestination，這是套件預設安裝目錄，<strong>但是在現階段蠻雞肋的，他會將所有的套件檔案直接都放在此指定目錄裡</strong>，而不會分不同的套件名稱，所以暫時不太用裡他，取而代之目前會使用的是在每個套件描述裡指定目錄</p>
<p>libraries 底下的物件常用的屬性有三個：</p>
<h4 id="heading-library-string">library: String</h4>
<p>代表cdnjs上套件之名稱與版本，使用 <code>@</code>分隔，套件名稱沒有 IntelliSense 支援，但是版本就有，輸入完套件名稱後打上 <code>@</code> 就會出現版本的選單</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070344143/a2e9831c-3cac-4eab-9447-6df588ea8897.png" alt /></p>
<h4 id="heading-files-string-array">files(選填): String Array</h4>
<p>預設是不需要填此屬性，沒有此屬性時 LibMan 會自動下載所有相關資料夾結構與檔案，若是有指定只要某些檔案，可以在此新增，如：</p>
<pre><code><span class="hljs-string">"files"</span>: [ <span class="hljs-string">"jquery.min.js"</span> ]
</code></pre><p>代表只需要取得 jquery.min.js 即可，結果如下</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070346290/2707e71a-533a-426c-9bbb-1c27438fd0aa.png" alt /></p>
<h4 id="heading-destination-string">destination(必選填): string</h4>
<p>這邊代表要將此套件檔案放在哪裡，若有設定 defaultDestination 就不用必填，但是反過來說，沒有 defaultDestination 就需要填寫此屬性，已現在來說我推薦都使用此屬性來管理套件的擺放位置</p>
<p>完成以上填寫並存檔後，LibMan 就會自動還原套件檔案，您也可以透過手動觸發或是清除受管理之套件資料夾</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070348138/9e556f94-4385-468f-ad03-517cc64b340e.png" alt /></p>
<p>使用上述範例存檔後，從方案總管上來看會長成這樣</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070350283/97f4b012-b007-47b5-98d4-08a31bd54632.png" alt /></p>
<p>我個人認為這是一個對於後端開發者來說算是挺友善的前端套件管理套件，自從 Nuget 再也無法拿來管理前端套件後，尋尋覓覓應該到此就差不多終結了，希望他不要再死掉了</p>
<blockquote>
<p>發完文後發現 LibMan 已正式內建於 VS 15.8 且 Release 了，可以去嘗試看看</p>
</blockquote>
<h4 id="heading-5yd6icd">參考</h4>
<p>[<strong>aspnet/LibraryManager</strong>
<em>GitHub is where people build software. More than 28 million people use GitHub to discover, fork, and contribute to over…</em>github.com](https://github.com/aspnet/LibraryManager "https://github.com/aspnet/LibraryManager")</p>
]]></content:encoded></item><item><title><![CDATA[針對 Visual Studio 15.7 以下之版本建置 Microsoft Library Manager.vsix]]></title><description><![CDATA[Build Microsoft Library Manager.vsix for VS15.7 or below
如果是從 GitHub 上直接取得的 Vsix，在 Visual Studio 15.7 以下之版本安裝會得到以下錯誤
Install Error : System.InvalidOperationException: A value for 'Component' needs to be specified in the catalog.
這邊簡單介紹一下如何為 VS 15.7 或...]]></description><link>https://blog.yu.money/visual-studio-157-microsoft-library-managervsix</link><guid isPermaLink="true">https://blog.yu.money/visual-studio-157-microsoft-library-managervsix</guid><dc:creator><![CDATA[Money Yu]]></dc:creator><pubDate>Tue, 14 Aug 2018 15:09:21 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070332148/d2339634-68a9-4307-b0d1-03d289eb0a96.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<hr />
<h4 id="heading-build-microsoft-library-managervsix-for-vs157-or-below">Build Microsoft Library Manager.vsix for VS15.7 or below</h4>
<p>如果是從 GitHub 上直接取得的 Vsix，在 Visual Studio 15.7 以下之版本安裝會得到以下錯誤</p>
<pre><code>Install <span class="hljs-built_in">Error</span> : System.InvalidOperationException: A value <span class="hljs-keyword">for</span> <span class="hljs-string">'Component'</span> needs to be specified <span class="hljs-keyword">in</span> the catalog.
</code></pre><p>這邊簡單介紹一下如何為 VS 15.7 或以下之版本建置出可用之 Vsix 安裝檔</p>
<p>首先先從<a target="_blank" href="https://github.com/aspnet/LibraryManager/">專案 GitHub</a> 下載完整原始碼，先不要打開方案</p>
<p>編輯 <a target="_blank" href="https://github.com/aspnet/LibraryManager/blob/72bf21f2c5fc56447e27f0ed1b866154d0fb520c/src/LibraryManager.Vsix/Microsoft.Web.LibraryManager.Vsix.csproj#L30">LibraryManager/src/LibraryManager.Vsix/Microsoft.Web.LibraryManager.Vsix.csproj</a> 檔案</p>
<p>其中有一行程式碼為</p>
<pre><code>&lt;IsProductComponent&gt;<span class="hljs-literal">true</span>&lt;/IsProductComponent&gt;
</code></pre><p>將其修改為 false</p>
<pre><code>&lt;IsProductComponent&gt;<span class="hljs-literal">false</span>&lt;/IsProductComponent&gt;
</code></pre><blockquote>
<p>當設為 false 時，就可於沒有 Library Manager 之 Visual Studio 版本上安裝 (15.7 或以下)；然而此 vsix 無法更新於已經有 Library Manager 之 Visual Studio 版本 (15.8 Preview 或以上)</p>
</blockquote>
<p>修改完後就可以開啟方案，並調整 Configuration 為 Release 後進行建置</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070332148/d2339634-68a9-4307-b0d1-03d289eb0a96.png" alt /></p>
<p>建置完後打開相對應之資料夾即可看到產生的 Vsix 檔案，點選進行安裝即可</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070334451/b5d79081-565b-43cf-b96a-e0536643230d.png" alt /></p>
]]></content:encoded></item><item><title><![CDATA[在 Mac OS Mojave 上執行 VirtualBox]]></title><description><![CDATA[Run VirtualBOx at Mac OS Mojave
最近將我的 MacBookPro 升級到了 Mac OS Mojave Beta，為了要使用 Dark Mode，不過一升級後就發現無法執行 VirtualBox 了，會出現以下錯誤：

原因是因為 Apple 從 Mojave 開始封鎖所有不到 5.3 版本的 kext，而 VirtualBox 剛好使用的是 5.2 版本的 kext，基本上正式的解決方法只能等 Oracle 官方升級 kext 版本
除了等待 Oracle 官方...]]></description><link>https://blog.yu.money/mac-os-mojave-virtualbox</link><guid isPermaLink="true">https://blog.yu.money/mac-os-mojave-virtualbox</guid><dc:creator><![CDATA[Money Yu]]></dc:creator><pubDate>Wed, 11 Jul 2018 16:59:21 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070316113/499414ce-b130-43f0-aeff-0ad034ed1a83.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<hr />
<h4 id="heading-run-virtualbox-at-mac-os-mojave">Run VirtualBOx at Mac OS Mojave</h4>
<p>最近將我的 MacBookPro 升級到了 Mac OS Mojave Beta，為了要使用 Dark Mode，不過一升級後就發現無法執行 VirtualBox 了，會出現以下錯誤：</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070316113/499414ce-b130-43f0-aeff-0ad034ed1a83.png" alt /></p>
<p>原因是因為 Apple 從 Mojave 開始封鎖所有不到 5.3 版本的 kext，而 VirtualBox 剛好使用的是 5.2 版本的 kext，基本上正式的解決方法只能等 Oracle 官方升級 kext 版本</p>
<p>除了等待 Oracle 官方升級以外，目前現在還有個 Workaround，以下介紹作法</p>
<ol>
<li>安裝 VirtualBox 5.2 以上的版本，一定要 5.2 以上的版本才可以使用這個 Workaround</li>
<li>關閉 Mac 的 SIP (<a target="_blank" href="https://support.apple.com/en-us/HT204899">System Integrity Protection</a>)，關閉方式可參考此：<a target="_blank" href="https://blog.developer.money/%E9%97%9C%E9%96%89-mac-%E7%9A%84-sip-system-integrity-protection-8f679c4fdd9e">關閉 Mac 的 SIP (System Integrity Protection)</a>，若本來就已經關閉的可以略過此步驟</li>
<li>執行以下語法，用以將 VirtualBox 的 kext 加入白名單</li>
</ol>
<p>這樣就可以執行 VirtualBox 了</p>
<p>正式解法還是要等官方出囉</p>
<p>Reference</p>
]]></content:encoded></item><item><title><![CDATA[關閉 Mac 的 SIP (System Integrity Protection)]]></title><description><![CDATA[Mac disable System Integrity Protection (SIP)

這篇是要簡單介紹 Mac 要如何關閉 SIP (System Integrity Protection)，若是沒有必要，請不要亂關閉安全保護的機制，這篇是為了 VirtualBox 無法在 Mojave 上使用的其中一篇子文章

首先將 Mac 用 Recovery Mode 開機，於重開機時按住 Command + R 直到 Apple 的 Logo 出現後放開，即可進入復原模式
於上方選單中，點選：...]]></description><link>https://blog.yu.money/mac-sip-system-integrity-protection</link><guid isPermaLink="true">https://blog.yu.money/mac-sip-system-integrity-protection</guid><dc:creator><![CDATA[Money Yu]]></dc:creator><pubDate>Wed, 11 Jul 2018 16:56:50 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070312121/6eb1f82a-c965-4256-83c8-2bee355a5326.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<hr />
<h4 id="heading-mac-disable-system-integrity-protection-sip">Mac disable System Integrity Protection (SIP)</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070312121/6eb1f82a-c965-4256-83c8-2bee355a5326.jpeg" alt /></p>
<p>這篇是要簡單介紹 Mac 要如何關閉 SIP (System Integrity Protection)，若是沒有必要，請不要亂關閉安全保護的機制，這篇是為了 VirtualBox 無法在 Mojave 上使用的其中一篇子文章</p>
<ol>
<li>首先將 Mac 用 Recovery Mode 開機，於重開機時按住 <strong><em>Command + R</em></strong> 直到 Apple 的 Logo 出現後放開，即可進入復原模式</li>
<li>於上方選單中，點選： Utilities &gt; Terminal，開啟終端機</li>
<li>執行以下語法，用以關閉 SIP</li>
</ol>
<pre><code>csrutil disable
</code></pre><ol start="4">
<li>重新開機</li>
</ol>
<p>這樣就完成關閉 SIP 的動作了</p>
<p>若需要確認是否成功，可以執行以下語法</p>
<pre><code>ls -lO /System /usr
</code></pre><p>列出的資料夾有 <strong>restricted</strong> 字眼，代表被 SIP 所保護</p>
<p>預設 (= SIP enabled)，以下的資料夾應該都是被 restricted 的 (<a target="_blank" href="https://support.apple.com/en-us/HT204899">Apple Support page</a>)</p>
<pre><code>/System
/usr
/bin
/sbin
Apps that are pre-installed <span class="hljs-keyword">with</span> OS X
</code></pre><p>而下列的資料夾則應該是可以自由存取的：</p>
<pre><code>/Applications
/Library
/usr/local
</code></pre><p>[<strong>How do I disable System Integrity Protection (SIP) AKA "rootless" on macOs [OS X]</strong>
<em>Apple has introduced System Integrity Protection, also known as "rootless", with OS X 10.11, El Capitan. I understand…</em>apple.stackexchange.com](https://apple.stackexchange.com/a/208481 "https://apple.stackexchange.com/a/208481")</p>
]]></content:encoded></item><item><title><![CDATA[Firefox 設定之個人偏好設定篇]]></title><description><![CDATA[Firefox Setting for myself

Firefox
我是忠實的火狐愛用者，其中有一個很大的原因是因為: Tab Mix Plus 這個擴充套件，實在提供了很多功能；嘗試換過 Chrome、Edge 但都唯獨缺少此套件所提供的功能，也無替代方案，所以全數放棄
但是在 Firefox 新版上 (Firefox Quantum) 就無法使用也不在提供更新了，所以實在沒辦法只好找了一下一些相關替代設定，以下紀錄相關資訊，以供日後使用
其中要直接修改 Firefox 的設定，開啟 ab...]]></description><link>https://blog.yu.money/firefox</link><guid isPermaLink="true">https://blog.yu.money/firefox</guid><dc:creator><![CDATA[Money Yu]]></dc:creator><pubDate>Wed, 11 Jul 2018 16:21:03 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070328976/13aaf799-258b-4c9e-a45b-326ea3c629fd.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<hr />
<h4 id="heading-firefox-setting-for-myself">Firefox Setting for myself</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070328976/13aaf799-258b-4c9e-a45b-326ea3c629fd.png" alt /></p>
<p>Firefox</p>
<p>我是忠實的火狐愛用者，其中有一個很大的原因是因為: Tab Mix Plus 這個擴充套件，實在提供了很多功能；嘗試換過 Chrome、Edge 但都唯獨缺少此套件所提供的功能，也無替代方案，所以全數放棄</p>
<p>但是在 Firefox 新版上 (Firefox Quantum) 就無法使用也不在提供更新了，所以實在沒辦法只好找了一下一些相關替代設定，以下紀錄相關資訊，以供日後使用</p>
<p>其中要直接修改 Firefox 的設定，開啟 <strong>about:config</strong>，並於搜尋欄中搜尋以下設定關鍵字</p>
<h4 id="heading-6acb57gk6kit5a6a">頁籤設定</h4>
<ol>
<li>書籤列點擊我的最愛時開啟於新頁籤：</li>
</ol>
<pre><code>browser.tabs.loadBookmarksInTabs: <span class="hljs-literal">true</span>
</code></pre><ol start="2">
<li>搜尋欄搜尋時開啟於新頁籤：</li>
</ol>
<pre><code>browser.search.openintab: <span class="hljs-literal">true</span>
</code></pre><ol start="3">
<li>連結位於不同網域時開啟於新頁籤：</li>
</ol>
<pre><code>browser.link.open_newwindow: <span class="hljs-number">3</span>
</code></pre><ol start="4">
<li>於網址列輸入後開啟於新頁籤：</li>
</ol>
<pre><code>browser.urlbar.openintab: <span class="hljs-literal">true</span>
</code></pre><p>這樣就可以在網址列、搜尋列或是開啟我的最愛時都是開啟於新頁籤，而不會是直接用原來的頁籤開啟，保留原來所瀏覽的資訊</p>
<hr />
<h4 id="heading-5po05ywf5awx5lu2">擴充套件</h4>
<ol>
<li>Fire Drag</li>
<li>Download Manager (S3)</li>
<li>Last Pass: Free Password Manager</li>
<li>New Tong Wen Tang</li>
<li>uBlock Origin</li>
</ol>
<hr />
<p>Edge 臨時存放區</p>
<p><a target="_blank" href="https://chrome.google.com/webstore/detail/tab-thumbnails-switcher/jpaiaplhepeiilhiegfnknedhjepknng/related">Tab Thumbnails Switcher — Chrome 線上應用程式商店 (google.com)</a></p>
]]></content:encoded></item><item><title><![CDATA[Nuget 套件封裝之相依版本設定]]></title><description><![CDATA[Nuget dependencies version setting

平常有將需要用到的工具發佈為 nuget 套件的習慣，在 ASP.NET MVC 中很常用到的分頁套件：X.PagedList 中，其 X.PagedList.MVC 最近遇到了最新版本有重大改變的問題，所以之前針對 Bootstrap4 所寫的輔助工具(X.PagedList.Mvc.Bootstrap4)就失效了，被網友開了 Issue，最後決定要跟著 X.PagedList 版本走，但遇到了在 7.2.X 之前是一種版...]]></description><link>https://blog.yu.money/nuget</link><guid isPermaLink="true">https://blog.yu.money/nuget</guid><dc:creator><![CDATA[Money Yu]]></dc:creator><pubDate>Sun, 08 Jul 2018 23:12:35 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070308163/709d5693-374d-4c02-b407-7663bedd5f08.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<hr />
<p>Nuget dependencies version setting</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1776070308163/709d5693-374d-4c02-b407-7663bedd5f08.png" alt /></p>
<p>平常有將需要用到的工具發佈為 nuget 套件的習慣，在 ASP.NET MVC 中很常用到的分頁套件：<a target="_blank" href="https://www.nuget.org/packages/X.PagedList/">X.PagedList</a> 中，其 <a target="_blank" href="https://www.nuget.org/packages/X.PagedList.Mvc/">X.PagedList.MVC</a> 最近遇到了最新版本有重大改變的問題，所以之前針對 Bootstrap4 所寫的輔助工具(<a target="_blank" href="https://www.nuget.org/packages/X.PagedList.Mvc.Bootstrap4/">X.PagedList.Mvc.Bootstrap4</a>)就失效了，被網友開了 Issue，最後決定要跟著 X.PagedList 版本走，但遇到了在 7.2.X 之前是一種版本，7.5.X 之後要換另外一個版本套件的問題，需要在 Nuget 封裝時就設定好，避免誤用錯誤版本</p>
<p>這邊就紀錄一下要如何在 Nuget 套件中設定其相依版本之條件</p>
<p>簡單來說，是透過一連串符號來代表是需要：大於、小於還是等於，然後數字就代表是甚麼版本</p>
<p>甚麼都沒有輸入，就代表至少要大於等於所指定之版本
例如：7.2，代表就是相依套件之版本 ≥ 7.2</p>
<p>若需要小於或等於所指定之版本，則不太依樣，需要用 (] 包住，並於左邊加入逗號
例如：(,7.2]，代表依套件之版本 ≤ 7.2</p>
<p>用括號包起來且加上逗號則代表不包含等於，大於或是小於則由逗號放在哪邊決定，若逗號放在左邊代表小於，右邊代表大於
例如：(7.2,)，代表相依套件之版本 &gt; 7.2
(,7.2)，代表相依套件之版本 &lt; 7.2</p>
<p>若需要強制指定特定版本時，則可以使用 [] 組合
例如：[7.2]，代表相依套件之版本 == 7.2</p>
<p>若要指定版本區間則是將兩個版本用 () 或是 [] 包起來，並於中間加入逗號
例如： [7.2,7.5]，代表 7.2 ≤ x ≤ 7.5
(7.2,7.5)，代表 7.2 &lt; x &lt; 7.5
[7.2,7.5)，代表 7.2 ≤ x &lt; 7.5
(7.2,7.5]，代表 7.2 &lt; x ≤ 7.5</p>
<p>特此紀錄一下，方便之後用到</p>
<p>[<strong>NuGet 封裝版本的參考</strong>
<em>確切的指定版本號碼和範圍而定的 NuGet 封裝，並安裝相依性的方式在其他封裝的詳細資訊。</em>docs.microsoft.com](https://docs.microsoft.com/zh-tw/nuget/reference/package-versioning "https://docs.microsoft.com/zh-tw/nuget/reference/package-versioning")</p>
]]></content:encoded></item></channel></rss>