以下內容基於原文情境,抽取並擴充成可教學、可實作的 16 個完整案例。每個案例均包含:問題、根因、解法(含關鍵指令/設定/程式碼或具體操作流程)、與實際效益描述,以利在實戰教學、專案練習與能力評估中使用。
Case #1: VS2008 編譯錯誤:找不到 VJSharpCodeProvider(源自 App_Data 的 .java)
Problem Statement(問題陳述)
業務場景:在本機建立 BlogEngine.NET 1.4.5.0 的開發環境,先從官方原始碼正常編譯成功。為了測試 PostViewCounter 與自製 SecurePost 擴充功能,需要帶入正式站的範例資料,因此將網站的 App_Data 也一併搬入。此後,Visual Studio 2008 Build 出現錯誤訊息「The CodeDom provider type Microsoft.VJSharp.VJSharpCodeProvider… could not be located」,導致無法 F5 附加除錯。 技術挑戰:錯誤訊息沒有檔名與行號,難以定位;網站仍可執行,但編譯不過,無法設定中斷點直接 F5 除錯。 影響範圍:阻斷開發者除錯迴圈,降低生產力;CI/Build 也可能中斷。 複雜度評級:中
Root Cause Analysis(根因分析)
直接原因:
- App_Data 中存在 .java 原始碼檔案,觸發 CodeDom 尋找 J# 編譯器。
- 開發機未安裝 Visual J#,導致無法載入 VJSharpCodeProvider。
- Website 模型的建置會掃描站台範圍,將異質語言檔案納入判斷。
深層原因:
- 架構層面:採用 Website 動態編譯模型,對檔案掃描較寬鬆。
- 技術層面:資料夾混放原始碼與網站資料,缺乏檔案型別治理。
- 流程層面:從正式站複製資料未經白名單/黑名單篩選。
Solution Design(解決方案設計)
解決策略:將 App_Data 視為純資料區,移除或移出 .java 等原始碼檔,並清除 ASP.NET 暫存後重建,恢復正常 F5 除錯。後續以目錄守則與腳本避免重犯。
實施步驟:
- 檔案稽核
- 實作細節:搜尋站台目錄是否有 *.java
- 所需資源:PowerShell 或 grep
- 預估時間:5 分鐘
- 移除/移出異質原始碼
- 實作細節:將 .java 自 App_Data 移至 repos 外或壓縮保存
- 所需資源:檔案系統操作
- 預估時間:5 分鐘
- 清除暫存並重建
- 實作細節:刪除 Temporary ASP.NET Files 與 bin,重開 VS 後建置
- 所需資源:系統管理權限
- 預估時間:10 分鐘
關鍵程式碼/設定:
# 尋找可疑 .java 檔
Get-ChildItem -Recurse -Filter *.java | Select-Object FullName
# 移除或搬移
Move-Item .\App_Data\files\*.java ..\_archive\ -Force
# 清理 ASP.NET 暫存 (請依 .NET 版本調整路徑)
$framework = "$env:windir\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files"
if (Test-Path $framework) { Remove-Item $framework -Recurse -Force }
實際案例:BlogEngine.NET 專案在加入 App_Data 後編譯失敗,刪除 ~/App_Data/files 下的舊 Java Applet 原始碼後,建置立即恢復。 實作環境:Windows + VS2008、.NET 2.0/3.5、BlogEngine.NET 1.4.5.0(Website 模型) 實測數據:
- 改善前:建置 1 錯誤,無法 F5
- 改善後:建置 0 錯誤,可 F5 設中斷點
- 改善幅度:該錯誤 100% 移除;除錯步驟由手動 Attach 降為一鍵 F5
Learning Points(學習要點) 核心知識點:
- Website 模型的檔案掃描與動態編譯行為
- App_Data 並非萬能「黑盒」,放錯檔會被建置影響
- J# CodeDom Provider 缺失的錯誤型態與徵候
技能要求:
- 必備技能:VS 建置與 ASP.NET 暫存目錄管理、檔案稽核
- 進階技能:建置流程治理、資料夾策略設計
延伸思考:
- 其他語言檔(如 .fs、.ts)也可能引發類似問題?
- 若一定要保留檔案,是否可封存或移出網站根目錄?
- 是否考慮改用 Web Application 以收斂編譯範圍?
Practice Exercise(練習題)
- 基礎練習:在 App_Data 放入任一 .java 檔,重現錯誤並移除修復(30 分鐘)
- 進階練習:寫一個 PowerShell 腳本自動找出異質原始碼並清除(2 小時)
- 專案練習:建立一個「資料夾守則 + 稽核腳本 + 文件」的整體方案(8 小時)
Assessment Criteria(評估標準)
- 功能完整性(40%):能重現與修復錯誤,F5 恢復
- 程式碼品質(30%):腳本清晰,錯誤處理完善
- 效能優化(20%):掃描速度與清理效率
- 創新性(10%):改善流程的自動化與防呆設計
Case #2: 無檔名/行號的編譯錯誤診斷流程
Problem Statement(問題陳述)
業務場景:建置 Website 時出現「找不到 VJSharpCodeProvider」等無檔名、無行號的錯誤,僅知「掛了」。網站可跑但無法編譯通過,影響 F5 除錯。 技術挑戰:缺乏檔案對位訊息,傳統逐檔排查耗時;需要快速定位根因。 影響範圍:診斷時間過長、影響交付進度。 複雜度評級:中
Root Cause Analysis(根因分析)
直接原因:
- Website 建置將訊息彙整,錯誤未帶入檔名。
- 例外源於 CodeDom Provider 載入時期,非程式碼語法錯誤層級。
- 預設 VS 輸出詳盡度不足。
深層原因:
- 架構層面:Website 動態編譯注重整體站台而非單一專案檔。
- 技術層面:未使用外部編譯器(aspnet_compiler)輔助定位。
- 流程層面:缺少標準化的錯誤診斷步驟。
Solution Design(解決方案設計)
解決策略:使用 aspnet_compiler 與提升 VS 建置輸出的詳盡度,取得更完整堆疊與掃描線索,輔以副檔名搜尋法,快速鎖定成因檔。
實施步驟:
- 提升輸出詳盡度
- 實作細節:VS 設定 Build output verbosity 為 Detailed/Diagnostic
- 所需資源:VS2008
- 預估時間:3 分鐘
- 使用 aspnet_compiler 重建
- 實作細節:以命令列預先編譯網站,擷取更完整堆疊
- 所需資源:.NET SDK
- 預估時間:10 分鐘
- 副檔名掃描與比對
- 實作細節:配合錯誤線索搜尋 .java 等異質檔
- 所需資源:PowerShell
- 預估時間:10 分鐘
關鍵程式碼/設定:
:: 提升 VS 輸出(操作介面):Tools > Options > Projects and Solutions > Build and Run > MSBuild output = Detailed/Diagnostic
:: 使用 aspnet_compiler(請修正路徑)
aspnet_compiler -v / -p "C:\path\to\Website" -errorstack -f "C:\out\PrecompiledSite"
實際案例:以 aspnet_compiler 取得堆疊含「VJSharpCodeProvider」型別載入失敗線索,進而搜尋 .java,鎖定 App_Data/files 舊檔。 實作環境:VS2008、.NET 2.0/3.5、IIS/內建伺服器皆可 實測數據:
- 改善前:僅有通用錯誤訊息,無檔名
- 改善後:可取得型別載入與 Provider 線索,診斷時間 < 30 分鐘
Learning Points(學習要點)
- aspnet_compiler 在 Website 診斷中的價值
- VS 輸出詳盡度對除錯效率的影響
- 訊息極少時的「副檔名逆向搜尋」技巧
技能要求:
- 必備技能:命令列工具操作、VS 設定
- 進階技能:讀懂 Compiler/Provider 堆疊
延伸思考:
- 是否能在 CI 用 aspnet_compiler 做預檢?
- 有無必要將 Website 轉為 Web Application 降低此類問題?
Practice Exercise(練習題)
- 基礎:啟用 Detailed/Diagnostic,重現一次錯誤輸出(30 分鐘)
- 進階:以 aspnet_compiler 對本機網站做預編譯,收集堆疊(2 小時)
- 專案:將 aspnet_compiler 納入 CI 流程並輸出結構化報表(8 小時)
Assessment Criteria(評估標準)
- 功能完整性:能產出更具體的堆疊
- 程式碼品質:腳本與紀錄清晰
- 效能優化:診斷時間顯著縮短
- 創新性:報表化與自動化程度
Case #3: App_Data 只存資料,不放原始碼的目錄治理
Problem Statement(問題陳述)
業務場景:為了帶入測試用資料,將正式站整個 App_Data 搬到開發機,結果混入舊 Java Applet 原始碼導致建置失敗。 技術挑戰:Website 對目錄掃描寬鬆,App_Data 被視為資料但仍可能被工具掃描到異質檔。 影響範圍:建置不穩定、除錯阻塞、交付風險。 複雜度評級:低
Root Cause Analysis(根因分析)
直接原因:
- App_Data 夾雜原始碼,違背目錄職責。
- 沒有目錄守則或 README 說明。
- 未實施檔案型別白名單。
深層原因:
- 架構層面:網站目錄未模組化資料與程式界線。
- 技術層面:Website 掃描機制不易收斂。
- 流程層面:缺乏檔案放置規範與稽核。
Solution Design(解決方案設計)
解決策略:建立資料/程式分離的目錄規範,App_Data 僅容許特定資料型別;原始碼以壓縮或移出網站根目錄保存。
實施步驟:
- 設計與公布目錄守則
- 實作細節:制定允許副檔名清單與不允許清單
- 所需資源:團隊共識與文件
- 預估時間:2 小時
- 加入 README 與檔案監控
- 實作細節:README 說明用途並提供掃描腳本
- 所需資源:文件與腳本
- 預估時間:1 小時
- 清理現有混雜檔案
- 實作細節:一次性稽核清理,後續例行掃描
- 所需資源:PowerShell
- 預估時間:1-2 小時
關鍵程式碼/設定:
# App_Data/README.md(摘要)
本目錄僅允許:.xml, .json, .db, .md, .txt
禁止:.cs, .vb, .java, .fs, .ts, .js(原始碼)
如需保存範例原始碼,請壓縮為 .zip 放置於 /static/archives
實際案例:移除 App_Data/files 中的 .java 原始碼後,建置恢復正常。 實作環境:VS2008 + BlogEngine.NET 1.4.5.0 實測數據:
- 改善前:App_Data 夾雜原始碼觸發建置錯誤
- 改善後:建置穩定,未再出現相同錯誤
Learning Points(學習要點)
- 目錄職責劃分的重要性
- 白名單策略比黑名單更易維護
- 文檔與機制並行才能有效落地
技能要求:
- 必備技能:目錄規劃、文件撰寫
- 進階技能:自動化稽核腳本
延伸思考:
- 是否需要在 Web.config 設置下載保護,防止資料外洩?
- 是否需要對大檔與二進位檔有額外策略?
Practice Exercise(練習題)
- 基礎:撰寫 README 草案並落地(30 分鐘)
- 進階:實作白名單掃描腳本(2 小時)
- 專案:制定全站目錄治理與自動化稽核方案(8 小時)
Assessment Criteria(評估標準)
- 功能完整性:規範可執行且被採納
- 程式碼品質:掃描腳本可維護
- 效能優化:掃描時間合理
- 創新性:自動化與可視化程度
Case #4: 從正式站搬到開發機的「白名單同步」腳本
Problem Statement(問題陳述)
業務場景:開發者為了測試需要樣本資料,將正式站整個網站目錄搬來,結果混入非必要檔案(如 .java),造成建置失敗。 技術挑戰:手動挑選易遺漏;需要可重複、可審計的檔案同步機制。 影響範圍:建置不穩、時間浪費、風險外溢。 複雜度評級:中
Root Cause Analysis(根因分析)
直接原因:
- 粗暴整包複製導致垃圾檔帶入。
- 缺乏「只同步必要資料」的腳本。
- 無檔案型別白名單機制。
深層原因:
- 架構層面:資料與程式無清楚分層的同步策略。
- 技術層面:缺少自動化同步工具。
- 流程層面:搬遷作業未制度化。
Solution Design(解決方案設計)
解決策略:用白名單複製策略,只同步核准的資料型別與目錄,避免將異質原始碼帶入開發環境。
實施步驟:
- 定義白名單
- 實作細節:列出允許的資料夾與副檔名
- 所需資源:文件
- 預估時間:1 小時
- 編寫同步腳本
- 實作細節:使用 robocopy 或 PowerShell 製作白名單同步
- 所需資源:Windows 工具
- 預估時間:1-2 小時
- 納入流程
- 實作細節:版本化腳本並定期審視
- 所需資源:版控
- 預估時間:30 分鐘
關鍵程式碼/設定:
# 只同步白名單資料(範例)
$src = "C:\prod\site"
$dst = "C:\dev\site"
$allow = @("*.xml","*.json","*.db","*.txt","*.png","*.jpg")
robocopy $src $dst /MIR /XD "bin" "obj" ".git" `
/XF "*.cs" "*.vb" "*.java" "*.fs" "*.ts" "*.js" `
/IF /R:1 /W:1
# 額外:僅複製 App_Data 下必要子資料夾
robocopy "$src\App_Data" "$dst\App_Data" posts /E
robocopy "$src\App_Data" "$dst\App_Data" images /E
實際案例:僅同步必要資料,避免 .java 帶入,建置順利。 實作環境:Windows + VS2008 實測數據:
- 改善前:手動複製易夾雜垃圾檔
- 改善後:白名單同步,錯誤未再發生
Learning Points(學習要點)
- 白名單同步比黑名單更可控
- robocopy/PowerShell 的高效用法
- 搬遷流程亦需版本化與審計
技能要求:
- 必備技能:Windows 檔案工具
- 進階技能:腳本化與例外處理
延伸思考:
- 是否需對大檔分批同步或增量同步?
- 是否加上哈希校驗以確保資料一致性?
Practice Exercise(練習題)
- 基礎:撰寫一個只複製特定副檔名的腳本(30 分鐘)
- 進階:加入日誌與錯誤回報(2 小時)
- 專案:打造可設定的同步工具(8 小時)
Assessment Criteria(評估標準)
- 功能完整性:白名單準確,重複可用
- 程式碼品質:模組化、易維護
- 效能優化:同步耗時合理
- 創新性:錯誤處理與日誌追蹤
Case #5: 權宜之計:安裝 Visual J# Provider 解臨時燃眉之急
Problem Statement(問題陳述)
業務場景:建置因 .java 被掃描而找不到 VJSharpCodeProvider;短期內無法移除檔案(例如使用者不方便更動內容)。 技術挑戰:需暫時讓建置通過,恢復 F5 流程;但不希望長期依賴已淘汰元件。 影響範圍:短期交付壓力;長期技術債。 複雜度評級:低
Root Cause Analysis(根因分析)
直接原因:
- 未安裝 Visual J# Redistributable。
- Website 掃描到 .java 檔。
- 無法立即移除檔案。
深層原因:
- 架構層面:Website 模型敏感於異質原始碼。
- 技術層面:J# 已 EOL,風險存在。
- 流程層面:臨時救火替代了根因治理。
Solution Design(解決方案設計)
解決策略:暫時安裝 Visual J# 2.0 Redistributable 以度過交付期,並規劃後續移除與資料夾清理,避免長期依賴。
實施步驟:
- 安裝 J# Runtime
- 實作細節:安裝 VJ# 2.0(注意來源可信與 EOL)
- 所需資源:安裝權限
- 預估時間:10-20 分鐘
- 建置驗證
- 實作細節:重建專案,確認錯誤消失
- 所需資源:VS2008
- 預估時間:5 分鐘
- 風險告警與移除計畫
- 實作細節:記錄技術債,排程移除 J# 依賴
- 所需資源:任務管理
- 預估時間:30 分鐘
關鍵程式碼/設定:
注意:J# 已停止維護,僅作為短期權宜。
長期仍需移除 .java 或改造目錄結構,避免依賴過時 Provider。
實際案例:安裝後建置可過,F5 恢復;後續仍移除 .java 才是正解。 實作環境:Windows + VS2008 實測數據:
- 改善前:建置失敗
- 改善後:建置成功
- 風險:增加一項過時依賴,需追蹤移除
Learning Points(學習要點)
- 權宜與根治的取捨
- 老舊元件的生命週期管理
技能要求:
- 必備技能:Windows 套件安裝
- 進階技能:風險管理
延伸思考:
- 是否改採 Web Application 替代?
- 是否能以封存檔案方式無痛移除 .java?
Practice Exercise(練習題)
- 基礎:模擬安裝與撤除流程(30 分鐘)
- 進階:撰寫風險告警文件(2 小時)
- 專案:制定過時元件移除計畫(8 小時)
Assessment Criteria(評估標準)
- 功能完整性:短期可建置
- 程式碼品質:N/A(流程為主)
- 效能優化:建置時間穩定
- 創新性:風險控制方案
Case #6: 編譯失敗時的除錯權宜:Attach to Process
Problem Statement(問題陳述)
業務場景:因建置不過無法 F5,需以「手動 Attach Process」除錯繼續開發。 技術挑戰:每次附加耗時,容易遺漏正確程序(w3wp 或 WebDev.WebServer.EXE)。 影響範圍:除錯迭代變慢,開發體驗不佳。 複雜度評級:低
Root Cause Analysis(根因分析)
直接原因:
- 建置失敗阻斷 F5。
- 人工 Attach 步驟多。
- 多個工作進程易選錯。
深層原因:
- 架構層面:Website F5 與建置耦合。
- 技術層面:開發伺服器與 IIS 流程不同。
- 流程層面:未建立除錯 SOP。
Solution Design(解決方案設計)
解決策略:制定 Attach SOP 與快速鍵流程,列出常見程序與附加設定,作為建置修復前的暫時性手段。
實施步驟:
- 確認宿主
- 實作細節:內建伺服器選 WebDev.WebServer.EXE;IIS 選 w3wp.exe
- 所需資源:VS2008
- 預估時間:5 分鐘
- 附加設定
- 實作細節:Debug > Attach to Process… > 選擇 Managed (v2.0, v3.5)
- 所需資源:VS2008
- 預估時間:5 分鐘
- 設置快捷流程
- 實作細節:建立書籤文件與截圖 SOP
- 所需資源:團隊 Wiki
- 預估時間:30 分鐘
關鍵程式碼/設定:
VS2008 步驟:
- Debug > Attach to Process…
- 勾選 Show processes from all users
- 依開發模式選:
- WebDev.WebServer.EXE(內建伺服器)
- w3wp.exe(IIS,若無請先「以管理員身分」執行 VS,並瀏覽一次頁面啟動工作程序)
實際案例:在修復前,先以 Attach 方式持續開發;修復後恢復 F5。 實作環境:VS2008 + ASP.NET 實測數據:
- 改善前:每次除錯需多步驟手動附加
- 改善後:SOP 化,將附加時間穩定控制在 1 分鐘內
Learning Points(學習要點)
- 了解不同宿主的工作程序
- 建立臨時除錯 SOP 提升效率
技能要求:
- 必備技能:VS 除錯面板操作
- 進階技能:IIS 工作程序管理
延伸思考:
- 可否以 scripts 自動附加?(新版本 VS 支援度更佳)
- 長期仍應修復建置問題
Practice Exercise(練習題)
- 基礎:分別對 WebDev/WebServer 與 w3wp 進行附加(30 分鐘)
- 進階:撰寫 SOP 與常見問題集(2 小時)
- 專案:整合到團隊 Wiki 並培訓(8 小時)
Assessment Criteria(評估標準)
- 功能完整性:可持續除錯
- 程式碼品質:N/A
- 效能優化:附加時間縮短
- 創新性:SOP 範本與教具
Case #7: 將 Website 轉為 Web Application,明確控管編譯範圍
Problem Statement(問題陳述)
業務場景:Website 模型導致動態掃描,異質檔(如 .java)易觸發建置問題。需更可控的專案模型。 技術挑戰:轉換需要搬遷檔案與調整命名空間、設計時支援。 影響範圍:一次性改造,長期穩定。 複雜度評級:中-高
Root Cause Analysis(根因分析)
直接原因:
- Website 無 .csproj,編譯範圍較寬。
- 無法對檔案設置 Build Action。
- 難以排除特定檔案夾。
深層原因:
- 架構層面:Website 的動態編譯設計。
- 技術層面:專案系統限制。
- 流程層面:缺乏轉換計畫。
Solution Design(解決方案設計)
解決策略:建立新的 Web Application 專案,將必要檔案移入並顯式納入編譯,App_Data 只標記為 Content,從根本上避免掃描異質原始碼。
實施步驟:
- 建立 Web Application 專案
- 實作細節:VS 新建 Web Application(.NET 3.5)
- 所需資源:VS2008
- 預估時間:15 分鐘
- 搬遷檔案並設定屬性
- 實作細節:將 .cs 設為 Compile;App_Data 設為 Content
- 所需資源:VS 專案系統
- 預估時間:1-2 小時
- 修正命名空間與參照
- 實作細節:一次性修正 code-behind 與命名空間
- 所需資源:C# 基礎
- 預估時間:1-2 小時
關鍵程式碼/設定:
<!-- Web Application .csproj 片段:顯式收斂編譯範圍 -->
<ItemGroup>
<Compile Include="App_Code\*.cs" />
<Content Include="App_Data\**\*.*" />
</ItemGroup>
實際案例:轉為 Web Application 後,App_Data 即使含非程式檔也不會被編譯檢視。 實作環境:VS2008、.NET 3.5 實測數據:
- 改善前:Website 建置受目錄污染影響
- 改善後:可控編譯清單,建置穩定
Learning Points(學習要點)
- Website vs Web Application 的差異
- csproj 的編譯/內容管理
技能要求:
- 必備技能:VS 專案管理
- 進階技能:命名空間與參照修正
延伸思考:
- 路徑相依與部署策略調整
- 團隊共識與改造時機
Practice Exercise(練習題)
- 基礎:建立 Web App 並加入 Content/Compile 範例(30 分鐘)
- 進階:將小型 Website 轉換完成(2 小時)
- 專案:完成整站轉換與測試(8 小時)
Assessment Criteria(評估標準)
- 功能完整性:可建置與部署
- 程式碼品質:專案檔清楚、無多餘
- 效能優化:建置時間可控
- 創新性:轉換自動化腳本
Case #8: 在 web.config 顯式移除 VJ# CodeDom Provider 對 .java 的關聯
Problem Statement(問題陳述)
業務場景:環境中 machine.config 可能包含對 .java 的 J# Provider 設定;避免即使存在 .java 也嘗試載入 Provider。 技術挑戰:需了解 system.codedom 的 compilers 規則與移除語法。 影響範圍:可降低載入錯誤干擾,但不等於允許放 .java。 複雜度評級:中
Root Cause Analysis(根因分析)
直接原因:
- machine.config 自動包含 J# compiler 設定。
- Website 掃描 .java 觸發載入。
- 當未安裝 J#,載入失敗。
深層原因:
- 架構層面:CodeDom 透過 config 綁定 Provider。
- 技術層面:不熟悉
規則。 - 流程層面:缺少環境層級治理。
Solution Design(解決方案設計)
解決策略:在 web.config 以
實施步驟:
- 檢查 machine.config
- 實作細節:確認是否有 J# compiler 項
- 所需資源:系統權限
- 預估時間:10 分鐘
- web.config 覆寫移除
- 實作細節:加入
的 <remove .../> - 所需資源:web.config 編輯
- 預估時間:10 分鐘
- 實作細節:加入
- 測試建置
- 實作細節:重建並觀察錯誤變化
- 所需資源:VS2008
- 預估時間:10 分鐘
關鍵程式碼/設定:
<configuration>
<system.codedom>
<compilers>
<!-- 視實際 machine.config 的語言/副檔名設定移除 -->
<remove extension=".java" />
<!-- 或 -->
<remove language="J#;jsl;java" />
</compilers>
</system.codedom>
</configuration>
實際案例:移除設定可避免 J# 載入錯誤,但仍應移除 .java 檔案以徹底解決。 實作環境:.NET 2.0/3.5 + VS2008 實測數據:
- 改善前:嘗試載入 VJ# 失敗即報錯
- 改善後:不再嘗試載入;建置依舊建議移除 .java
Learning Points(學習要點)
- CodeDom Provider 綁定與覆寫
- web.config 對 machine.config 的細粒度控制
技能要求:
- 必備技能:配置檔編輯與驗證
- 進階技能:.NET 組態繼承與覆寫
延伸思考:
- 是否以此作為組織既定模板?
- 防呆仍應以檔案治理為主
Practice Exercise(練習題)
- 基礎:在 web.config 測試移除設定(30 分鐘)
- 進階:撰寫說明文檔與風險提示(2 小時)
- 專案:建立組織級 web.config 片段庫(8 小時)
Assessment Criteria(評估標準)
- 功能完整性:能阻斷 Provider 載入
- 程式碼品質:設定清晰,附註明細
- 效能優化:建置過程穩定
- 創新性:組態治理方法
Case #9: 加入「預建置掃描」找出不允許的原始碼副檔名
Problem Statement(問題陳述)
業務場景:在建置前先找出 .java 等不允許副檔名,避免進入漫長且無助的建置錯誤。 技術挑戰:Website 無 .csproj 項目事件;需以解決方案級腳本或 CI 前置步驟實作。 影響範圍:早期失敗、清晰訊息,節省時間。 複雜度評級:中
Root Cause Analysis(根因分析)
直接原因:
- 缺少前置檢查機制。
- 異質檔案混入不易察覺。
- 錯誤訊息延後至建置期才顯示。
深層原因:
- 架構層面:Website 架構限制 pre-build。
- 技術層面:需外掛腳本接管。
- 流程層面:CI 未內建靜態檢查。
Solution Design(解決方案設計)
解決策略:撰寫獨立 PowerShell 腳本,掃描站台根目錄並列印阻擋訊息;在 CI 或本機批次檔中先行呼叫。
實施步驟:
- 編寫掃描腳本
- 實作細節:尋找不允許副檔名,若存在則返回非 0 退出碼
- 所需資源:PowerShell
- 預估時間:1 小時
- 整合到流程
- 實作細節:在建置批次最前面呼叫
- 所需資源:批次檔或 CI
- 預估時間:30 分鐘
- 文件與維護
- 實作細節:白名單/黑名單維護
- 所需資源:文件
- 預估時間:30 分鐘
關鍵程式碼/設定:
# prebuild-scan.ps1
param([string]$root=".")
$blocked = @("*.java","*.cs","*.vb","*.fs","*.ts") # 視需求調整
$bad = @()
foreach ($p in $blocked) { $bad += Get-ChildItem $root -Recurse -Filter $p -ErrorAction SilentlyContinue }
if ($bad.Count -gt 0) {
Write-Error "Blocked source files detected:`n$($bad.FullName -join "`n")"
exit 1
}
Write-Host "Prebuild scan passed."
實際案例:掃描先擋下 .java,提供明確路徑,避免 VS 無頭錯誤。 實作環境:Windows + PowerShell 實測數據:
- 改善前:錯誤發生在建置中期,訊息不清
- 改善後:快速失敗並提供具體檔案列表
Learning Points(學習要點)
- 早期失敗的價值
- 腳本化前置檢查
技能要求:
- 必備技能:PowerShell、批次整合
- 進階技能:CI 彈性配置
延伸思考:
- 是否做為 Git pre-commit hook?
- 是否生成 HTML 報表?
Practice Exercise(練習題)
- 基礎:在示例站台跑一次掃描(30 分鐘)
- 進階:加入白名單與排除目錄(2 小時)
- 專案:整合到 CI Pipeline(8 小時)
Assessment Criteria(評估標準)
- 功能完整性:能阻擋不允許檔案
- 程式碼品質:參數化、日誌清晰
- 效能優化:掃描速度快
- 創新性:報表與可視化
Case #10: 修正後清理 ASP.NET 暫存與 Bin 避免殘留影響
Problem Statement(問題陳述)
業務場景:移除 .java 後仍偶見建置怪異,疑似暫存殘留。 技術挑戰:ASP.NET 有 Temporary ASP.NET Files;Website 還可能有 bin 與 obj 殘留。 影響範圍:修復後的穩定性。 複雜度評級:低
Root Cause Analysis(根因分析)
直接原因:
- 暫存編譯產物未清理。
- VS/ASP.NET 快取未刷新。
- 舊 DLL 或中介碼殘留。
深層原因:
- 架構層面:ASP.NET 動態編譯快取機制。
- 技術層面:不熟悉暫存路徑。
- 流程層面:無清理 SOP。
Solution Design(解決方案設計)
解決策略:制訂清理腳本,包含 Temporary ASP.NET Files、bin、obj;修復後執行清理再建置。
實施步驟:
- 撰寫清理腳本
- 實作細節:刪除既知暫存路徑
- 所需資源:PowerShell
- 預估時間:30 分鐘
- 納入流程
- 實作細節:修復後必執步驟
- 所需資源:文件
- 預估時間:10 分鐘
- 驗證
- 實作細節:重建與執行 Smoke Test
- 所需資源:VS2008
- 預估時間:10 分鐘
關鍵程式碼/設定:
# clean-aspnet-temp.ps1
$paths = @(
"$env:windir\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files",
"$env:windir\Microsoft.NET\Framework64\v2.0.50727\Temporary ASP.NET Files",
".\bin", ".\obj"
)
foreach ($p in $paths) {
if (Test-Path $p) { Remove-Item $p -Recurse -Force -ErrorAction SilentlyContinue }
}
Write-Host "Clean done."
實際案例:清理後建置行為穩定,避免「幽靈錯誤」。 實作環境:Windows + VS2008 實測數據:
- 改善前:偶發殘留問題
- 改善後:建置一致性提升
Learning Points(學習要點)
- 熟悉暫存路徑對於 ASP.NET 的重要性
- 清理 SOP 的價值
技能要求:
- 必備技能:檔案系統與 PowerShell
- 進階技能:自動化與條件清理
延伸思考:
- 是否在 CI/本機建置前自動清理?
- 是否僅在變更大範圍檔案時清理?
Practice Exercise(練習題)
- 基礎:執行一次清理並重建(30 分鐘)
- 進階:加入日誌與失敗回報(2 小時)
- 專案:建置前自動清理整合(8 小時)
Assessment Criteria(評估標準)
- 功能完整性:清理確實奏效
- 程式碼品質:錯誤容忍與回報完善
- 效能優化:清理時間合理
- 創新性:條件化清理策略
Case #11: 以 README 與目錄守則防呆,避免把原始碼丟進 App_Data
Problem Statement(問題陳述)
業務場景:團隊成員習慣把備份或範例原始碼丟進 App_Data,埋下建置雷。 技術挑戰:口頭規範無法持久;需有明確文件與可見提醒。 影響範圍:反覆踩雷、團隊成本。 複雜度評級:低
Root Cause Analysis(根因分析)
直接原因:
- 缺乏就地文件提醒。
- 新人不了解 Website 掃描行為。
- 沒有違規示範與範本。
深層原因:
- 架構層面:Website 易受影響。
- 技術層面:目錄知識缺失。
- 流程層面:知識傳承薄弱。
Solution Design(解決方案設計)
解決策略:在關鍵目錄放置 README 與範本,說明允許/禁止清單與替代作法(壓縮/移出)。
實施步驟:
- 撰寫 README
- 實作細節:包含允許副檔名、禁止清單、替代方案
- 所需資源:文件
- 預估時間:30 分鐘
- 製作範例
- 實作細節:提供範例壓縮存放位置
- 所需資源:目錄與示例
- 預估時間:30 分鐘
- 教育宣導
- 實作細節:在入職訓練/團隊會議解說
- 所需資源:講義
- 預估時間:30 分鐘
關鍵程式碼/設定:
# App_Data 使用規範(摘要)
- 僅允許:.json, .xml, .db, .txt, .md
- 禁止:任何程式原始碼(.cs, .vb, .java, .fs, .ts, .js)
- 替代:將範例原始碼壓縮為 .zip 放 /static/archives
- 理由:避免 Website 建置掃描導致無法 F5 除錯
實際案例:放置 README 後,將舊 Java Applet 轉為 .zip 存放,未再觸發錯誤。 實作環境:通用 實測數據:
- 改善前:反覆誤放原始碼
- 改善後:違規下降,建置穩定
Learning Points(學習要點)
- 文件即制度,近點提醒最有效
- 提供替代選項提升遵循度
技能要求:
- 必備技能:文件撰寫
- 進階技能:教學設計
延伸思考:
- 可否在 README 內嵌掃描腳本使用說明?
- 加入多語版本以利跨區域團隊
Practice Exercise(練習題)
- 基礎:撰寫 README 並審閱(30 分鐘)
- 進階:加入 FAQ(2 小時)
- 專案:製作新人成員訓練教材(8 小時)
Assessment Criteria(評估標準)
- 功能完整性:規範被看見與遵循
- 程式碼品質:N/A
- 效能優化:違規率下降
- 創新性:教具與指引品質
Case #12: 以版控 ignore 規則阻止 .java 等檔案進入網站原始碼
Problem Statement(問題陳述)
業務場景:開發者不慎將不允許的原始碼放入網站根目錄並提交。 技術挑戰:依靠人工檢查不可靠;需版控級防線。 影響範圍:污染主幹,造成團隊建置失敗。 複雜度評級:低
Root Cause Analysis(根因分析)
直接原因:
- 缺少 .gitignore/.tfignore 規則。
- 忙碌時容易誤提交。
- 無 pre-commit 檢查。
深層原因:
- 架構層面:資料與程式混放。
- 技術層面:版控規則未完備。
- 流程層面:缺乏守門機制。
Solution Design(解決方案設計)
解決策略:在版本庫根目錄加入忽略規則,特別是 App_Data 與敏感目錄,阻止異質原始碼被追蹤。
實施步驟:
- 編寫 ignore 規則
- 實作細節:忽略 .java/.cs/.vb 等在資料目錄
- 所需資源:版控工具
- 預估時間:20 分鐘
- 全倉掃描
- 實作細節:清理已追蹤的不當檔
- 所需資源:git rm –cached
- 預估時間:30 分鐘
- 教育與審查
- 實作細節:Code Review 檢視敏感目錄差異
- 所需資源:流程
- 預估時間:持續
關鍵程式碼/設定:
# 針對網站專案
/App_Data/**/*.java
/App_Data/**/*.cs
/App_Data/**/*.vb
/App_Data/**/*.fs
/App_Data/**/*.ts
/App_Data/**/*.js
/bin/
/obj/
實際案例:加入 ignore 後,即使不慎放入也不會提交污染主幹。 實作環境:Git 或等效系統 實測數據:
- 改善前:誤提交導致同儕建置失敗
- 改善後:主幹乾淨,建置穩定
Learning Points(學習要點)
- 版控忽略規則的防線價值
- 忽略規則需配合目錄政策
技能要求:
- 必備技能:Git 基礎
- 進階技能:倉庫整潔化
延伸思考:
- 是否加上 pre-commit 檢查進一步強化?
- 不同環境(如 TFS/SVN)等效規則
Practice Exercise(練習題)
- 基礎:新增 ignore 並測試(30 分鐘)
- 進階:清理既有污染歷史(2 小時)
- 專案:建立共用 ignore 模板(8 小時)
Assessment Criteria(評估標準)
- 功能完整性:能防止污染
- 程式碼品質:規則清晰、無誤傷
- 效能優化:倉庫輕量
- 創新性:模板化與可移植性
Case #13: 啟動前驗證測試:App_Data 僅含允許類型
Problem Statement(問題陳述)
業務場景:希望在應用啟動或 CI 測試階段就攔下不當檔案,避免上線後才發現建置/執行問題。 技術挑戰:需撰寫快速、穩定的檔案驗證測試。 影響範圍:穩定性與可維運性。 複雜度評級:低-中
Root Cause Analysis(根因分析)
直接原因:
- 無自動化驗證。
- 人工作業不可靠。
- 問題延後至建置或執行期。
深層原因:
- 架構層面:缺少防呆測試。
- 技術層面:未建立測試工具化。
- 流程層面:CI 未覆蓋靜態驗證。
Solution Design(解決方案設計)
解決策略:撰寫單元/整合測試,於啟動前掃描 App_Data,若發現不允許副檔名則測試失敗。
實施步驟:
- 撰寫測試
- 實作細節:C# 單元測試掃描與斷言
- 所需資源:測試框架(NUnit/MSTest)
- 預估時間:1 小時
- 整合到 CI
- 實作細節:將測試做為必過門檻
- 所需資源:CI 工具
- 預估時間:30 分鐘
- 維護白名單
- 實作細節:集中配置允許清單
- 所需資源:設定檔
- 預估時間:30 分鐘
關鍵程式碼/設定:
[TestMethod]
public void AppData_Should_Not_Contain_SourceCode()
{
var root = Path.Combine(TestContext.DeploymentDirectory, "App_Data");
var blocked = new[] { "*.java", "*.cs", "*.vb", "*.fs", "*.ts", "*.js" };
var bad = blocked.SelectMany(p => Directory.GetFiles(root, p, SearchOption.AllDirectories)).ToList();
Assert.IsTrue(bad.Count == 0, "Blocked files found:\n" + string.Join("\n", bad));
}
實際案例:在 CI 上即擋下 .java 混入,避免 VS 建置才報錯。 實作環境:.NET 測試框架 實測數據:
- 改善前:本機建置才發現
- 改善後:CI 測試階段即報明確檔案清單
Learning Points(學習要點)
- 測試亦可用於靜態驗證
- 白名單集中管理的好處
技能要求:
- 必備技能:C# 測試框架
- 進階技能:CI 整合
延伸思考:
- 擴充為站台全域目錄掃描?
- 是否加入容量/結構驗證?
Practice Exercise(練習題)
- 基礎:撰寫並執行一次測試(30 分鐘)
- 進階:參數化白名單來源(2 小時)
- 專案:整合至 CI 並產生報表(8 小時)
Assessment Criteria(評估標準)
- 功能完整性:能攔截不當檔案
- 程式碼品質:測試清晰可維護
- 效能優化:掃描快速
- 創新性:白名單設計
Case #14: 在 CI/Build Pipeline 加入明確錯誤訊息的檢查步驟
Problem Statement(問題陳述)
業務場景:VS 無頭錯誤不利診斷;希望 CI 階段直接輸出具體清單。 技術挑戰:需在 CI 管線中前置加入檔案檢查與清單輸出。 影響範圍:團隊診斷效率大幅提升。 複雜度評級:中
Root Cause Analysis(根因分析)
直接原因:
- CI 僅執行建置,未做靜態檢查。
- 無錯誤清單輸出。
- 問題拖延到後段。
深層原因:
- 架構層面:管線設計單薄。
- 技術層面:缺少檢查腳本整合。
- 流程層面:缺少明確失敗準則。
Solution Design(解決方案設計)
解決策略:在 CI 最前段加入掃描腳本,若發現不允許檔案即失敗並輸出詳細清單。
實施步驟:
- 準備掃描腳本
- 實作細節:沿用 prebuild-scan.ps1
- 所需資源:PowerShell
- 預估時間:30 分鐘
- 整合 CI
- 實作細節:在管線第一步執行,收集輸出
- 所需資源:CI 配置
- 預估時間:30-60 分鐘
- 報表化
- 實作細節:輸出到工件或註解
- 所需資源:CI 工具
- 預估時間:1 小時
關鍵程式碼/設定:
# 假設使用 YAML 類 CI(概念示例)
steps:
- powershell: |
./scripts/prebuild-scan.ps1 -root $(Build.SourcesDirectory)
displayName: "Prebuild scan for blocked file types"
實際案例:CI 直接報出 .java 的完整路徑,快速通知修復。 實作環境:任意 CI 實測數據:
- 改善前:建置才失敗且訊息含混
- 改善後:前段快速失敗,訊息明確
Learning Points(學習要點)
- 前置檢查的 ROI 很高
- CI 報表化提升團隊溝通
技能要求:
- 必備技能:CI 設定
- 進階技能:輸出報表與通知
延伸思考:
- 加入更多靜態檢查(祕密掃描、授權掃描)
- 與 Code Review 流程聯動
Practice Exercise(練習題)
- 基礎:把掃描步驟加進 CI(30 分鐘)
- 進階:將結果存成工件供下載(2 小時)
- 專案:建立通用 CI 模板(8 小時)
Assessment Criteria(評估標準)
- 功能完整性:檢查能阻擋問題
- 程式碼品質:管線結構清晰
- 效能優化:執行快速
- 創新性:報表與整合度
Case #15: 快速定位法:以二分法移除/還原目錄與副檔名
Problem Statement(問題陳述)
業務場景:錯誤訊息無指向,需快速找出觸發檔案;手動逐個檔案太慢。 技術挑戰:在不明成因下仍要有效縮小範圍。 影響範圍:診斷時間與成本。 複雜度評級:低-中
Root Cause Analysis(根因分析)
直接原因:
- 無頭錯誤無法直接定位。
- 站台檔案數量龐大。
- 沒有系統化排除法。
深層原因:
- 架構層面:Website 錯誤聚合。
- 技術層面:對檔案型別與掃描行為不熟。
- 流程層面:缺乏診斷套路。
Solution Design(解決方案設計)
解決策略:將目錄或副檔名分批移出(或改名),每次建置觀察變化;採二分法快速收斂到問題檔案群,再精確定位。
實施步驟:
- 目錄級測試
- 實作細節:先移出 App_Data、再逐步還原子目錄
- 所需資源:檔案系統操作
- 預估時間:30-60 分鐘
- 副檔名級測試
- 實作細節:針對可疑副檔名先改名 *.ban
- 所需資源:腳本
- 預估時間:30 分鐘
- 精確定位
- 實作細節:還原到單檔,逐一驗證
- 所需資源:VS
- 預估時間:30 分鐘
關鍵程式碼/設定:
# 批次改名以隔離(示例:暫時屏蔽 *.java)
Get-ChildItem .\App_Data -Recurse -Filter *.java | Rename-Item -NewName { $_.Name + ".ban" }
# 測試後再還原
Get-ChildItem .\App_Data -Recurse -Filter *.java.ban | Rename-Item -NewName { $_.Name -replace "\.ban$","" }
實際案例:以「搜尋 *.java → 移除」快速驗證即修復。 實作環境:Windows + VS2008 實測數據:
- 改善前:無從著手
- 改善後:30 分鐘內收斂至問題檔案
Learning Points(學習要點)
- 二分法/排除法在系統診斷的有效性
- 合理的猜測(副檔名)可加速定位
技能要求:
- 必備技能:檔案批次操作
- 進階技能:系統化診斷思維
延伸思考:
- 可否將此法工具化?
- 是否加入日誌記錄收斂過程?
Practice Exercise(練習題)
- 基礎:對示例專案演練二分法(30 分鐘)
- 進階:工具化為小指令(2 小時)
- 專案:做成 GUI 小工具(8 小時)
Assessment Criteria(評估標準)
- 功能完整性:能收斂並定位
- 程式碼品質:腳本簡潔安全
- 效能優化:步驟最小化
- 創新性:工具化程度
Case #16: 保留歷史檔案但不造成編譯:以 zip 封存或移出網站根
Problem Statement(問題陳述)
業務場景:需保留研究所時期的 Java Applet 原始碼作紀念或參考,但又不能影響建置。 技術挑戰:在保留與不干擾間取得平衡。 影響範圍:知識保存與開發穩定性。 複雜度評級:低
Root Cause Analysis(根因分析)
直接原因:
- 原始碼以明文存在網站根。
- 編譯掃描容易受影響。
- 無封存策略。
深層原因:
- 架構層面:資料與程式未隔離。
- 技術層面:缺乏封存機制。
- 流程層面:無知識保存規範。
Solution Design(解決方案設計)
解決策略:將非本專案原始碼封存為 zip,移到網站根外(或專用 /static/archives),並以 README 註明來源與用途。
實施步驟:
- 封存檔案
- 實作細節:使用 Compress-Archive
- 所需資源:PowerShell
- 預估時間:10 分鐘
- 移出網站根
- 實作細節:放置於 repo 外或非掃描目錄
- 所需資源:檔案操作
- 預估時間:5 分鐘
- 文件化
- 實作細節:記錄來源、日期、用途
- 所需資源:README
- 預估時間:10 分鐘
關鍵程式碼/設定:
Compress-Archive -Path .\App_Data\files\*.java -DestinationPath ..\_archives\legacy-java.zip -Force
Remove-Item .\App_Data\files\*.java -Force
實際案例:封存後建置恢復,亦保留歷史資料可追溯。 實作環境:Windows 實測數據:
- 改善前:建置受影響
- 改善後:建置穩定,資料得以保存
Learning Points(學習要點)
- 知識保存與工程穩定的兩全方式
- 壓縮封存降低風險
技能要求:
- 必備技能:檔案封存
- 進階技能:資料治理
延伸思考:
- 是否加上存檔簽章與校驗?
- 是否建立標準封存目錄與規約?
Practice Exercise(練習題)
- 基礎:封存與移出操作(30 分鐘)
- 進階:撰寫封存 SOP(2 小時)
- 專案:建立封存工具與目錄結構(8 小時)
Assessment Criteria(評估標準)
- 功能完整性:封存且不影響建置
- 程式碼品質:腳本可重用
- 效能優化:封存快速
- 創新性:規範與工具化
案例分類
- 按難度分類
- 入門級(適合初學者)
- Case 3, 5, 6, 10, 11, 12, 16
- 中級(需要一定基礎)
- Case 1, 2, 4, 8, 9, 13, 14, 15
- 高級(需要深厚經驗)
- Case 7
- 入門級(適合初學者)
- 按技術領域分類
- 架構設計類
- Case 3, 7, 11, 16
- 效能優化類
- Case 10
- 整合開發類
- Case 4, 8, 12, 14
- 除錯診斷類
- Case 1, 2, 6, 9, 13, 15
- 安全防護類
- Case 12(版控治理延伸到供應鏈安全)
- 架構設計類
- 按學習目標分類
- 概念理解型
- Case 3, 7, 11
- 技能練習型
- Case 2, 4, 6, 9, 10, 12, 13, 16
- 問題解決型
- Case 1, 5, 8, 14, 15
- 創新應用型
- Case 7, 14, 16
- 概念理解型
案例關聯圖(學習路徑建議)
- 建議先學
- Case 3(App_Data 目錄治理基本觀念)
- Case 1(本事件的核心修復)
- Case 2(無頭錯誤的診斷技巧)
- 依賴關係
- Case 4(白名單同步)依賴 Case 3 的目錄規則
- Case 9(預建置掃描)與 Case 14(CI 檢查)可共享掃描腳本
- Case 13(啟動前驗證)依賴白名單策略(Case 3)
- Case 7(Web Application 轉換)在理解 Website 問題後執行(Case 1, 2, 3)
- Case 8(web.config 覆寫)屬輔助,仍以 Case 1/3 為主
- Case 10(清理暫存)作為 Case 1 修復後的收尾
- Case 11、12、16 是長期治理與防呆,依據 Case 3 原則延伸
- Case 5、6 為權宜方案,僅在 Case 1 修復前暫用
- Case 15(二分法)可在 Case 2 診斷流程中套用
- 完整學習路徑建議
1) 概念打底:Case 3 → Case 2
2) 問題修復:Case 1 → Case 10
3) 診斷通用技法:Case 15 → Case 9
4) 流程化與防線:Case 4 → Case 11 → Case 12 → Case 13 → Case 14
5) 架構級優化:Case 7(必要時) → 輔助設定 Case 8
6) 權宜方案(視情況):Case 6 → Case 5
7) 長期保存與治理:Case 16
此學習路徑由近因處置到長期治理與架構優化,循序漸進,既能快速復原生產力,也能避免未來重犯與擴大穩定性。