Harmony 是一個 .NET 的開源 Runtime Patching 函式庫,由 Andreas Pardeike 開發,這個函式庫能夠在不具有原始碼的狀況下動態修改任何 .NET 方法的行為。這系列文章記錄一些關於這個函式庫的使用方式。
如何安裝
- 透過 Package Manager Console:輸入 Install-Package Lib.Harmony
透過圖形化介面:

補丁的種類
Harmony 提供多種補丁方式,每種都有不同用途:
- Prefix – 在原始方法執行前呼叫。
• 改變或檢查原始方法的參數
• 決定是否跳過原始方法
• 設定狀態供 Postfix 使用 - Postfix – 在原始方法執行後呼叫。
• 讀取或修改原始方法的回傳值
• 存取原始方法的參數
• 使用 Prefix 設定的狀態 - Transpiler – 不直接執行,而是修改原始方法的 IL 指令碼。適合進行進階的程式碼重寫。
- Finalizer – 在所有 Postfix 之後執行,並包裹 try/catch。
• 保證某段程式碼一定會執行
• 攔截或修改例外狀況 - Reverse Patch – 與其他不同,它是把「原始方法」補丁到你自己的方法 stub 上,方便在自訂程式碼中呼叫原始邏輯。
執行補丁的方式
- 手動補丁
• 你自行取得 MethodInfo ,並用 HarmonyMethod 包裝後傳給 Patch()。
• 方法名稱可自由,但必須是 static。 - 使用 annotation
• 在類別上加上 HarmonyPatch attribute。
• 在類別中定義 Prefix、Postfix、Transpiler 等方法。
• 方法名稱可用 attribute 指定,例如 HarmonyPostfix attribute。
適用的技術情況
- 無法修改原始程式碼:例如第三方 DLL、Unity 遊戲、封閉的 API。
- 需要在方法執行前後插入邏輯:紀錄日誌、驗證輸入、修改回傳值。
- 要完全跳過某個方法:Prefix 可直接 return false。
- 要修改 IL 指令碼:Transpiler 可進行進階程式碼重寫。
- 要呼叫私有方法或取得原始邏輯:Reverse Patch 可直接嵌入原始方法,不需反射。
- 要呼叫原始方法但稍微改寫:Transpiled Reverse Patch 可先用 Transpiler 改 IL,再嵌入。
使用限制
- 補丁方法必須是靜態方法
Prefix、Postfix、Transpiler、Finalizer、Reverse Patch 等補丁方法都必須宣告為 ,因為 Harmony 只能儲存方法指標,無法管理執行個體。 - 僅能在目前 應用程式定義域 (AppDomain) 中運作
Harmony 的補丁無法跨越 AppDomain,因此在某些特殊環境(例如多 AppDomain 的應用程式)可能受限。 - 泛型支援有限
雖然 Harmony 可以補丁泛型方法,但支援仍屬實驗性,某些情況下可能會失敗或行為不一致。 - 方法被編譯器 inline 時可能失效
如果目標方法被 JIT 編譯器或 C# 編譯器內聯 (inline),Harmony 就無法攔截它。 - 僅能補丁 IL 方法
Harmony 依靠 IL 指令碼修改,因此無法補丁某些特殊方法(例如純原生程式碼、P/Invoke)。 - 與其他補丁或工具衝突
如果同一方法被多個補丁或其他工具修改,可能會出現衝突或執行順序問題。 - 需要正確的簽名匹配
補丁方法的參數必須與目標方法相符,否則 Harmony 無法正確注入。
資料來源
對於 Harmony Library 的簡單介紹到這裡,下一篇開始介紹實作的流程。