在共享虛擬主機環境,呼叫 System.IO.Directory.CreateDirectory 或 DirectoryInfo.CreateSubdirectory 常拋出 DirectoryNotFoundException: 未找到路徑 "E:\" 的一部分。原因:Directory 類別內部會嘗試遍歷磁碟根目錄(如 E:\)檢查權限,但虛擬主機的 Network Service / IIS_IUSRS 帳號通常無磁碟根目錄讀取權限。
System.IO.DirectoryNotFoundException: 未找到路徑 "E:\" 的一部分。
at System.IO.__Error.WinIOError(Int32 errorCode, String str)
at System.IO.Directory.InternalCreateDirectory(String fullPath, String path)
at System.IO.Directory.CreateDirectory(String path)
錯誤路徑顯示為磁碟根目錄(E:\、D:\ 等),而非目標資料夾路徑,證實是遍歷根目錄時遭拒。
前提:主機啟用 Microsoft Scripting Runtime (scrrun.dll) 且信任層級允許 COM Interop。
using Scripting;
public void CreateFolder(string path)
{
FileSystemObject fso = new FileSystemObjectClass();
if (!fso.FolderExists(path))
{
fso.CreateFolder(path);
}
}
優點:不觸發 .NET 根目錄遍歷。缺點:依賴 COM 元件、64 位元相容性需測試、中信任環境可能被禁止。
許多錯誤源於路徑拼接錯誤導致指向非預期根目錄。
string targetPath = Server.MapPath("~/Uploads/" + folderName);
// 確保父目錄存在
DirectoryInfo di = new DirectoryInfo(targetPath);
if (!di.Parent.Exists)
di.Parent.Create(); // 這裡仍可能觸發權限問題
di.Create();
若仍報錯,請要求主機商對 Uploads 資料夾授予 IIS_IUSRS 修改 權限(寫入+刪除)。
// ASP.NET Core 控制器中
var uploads = Path.Combine(_env.WebRootPath, "uploads", folderName);
Directory.CreateDirectory(uploads); // Core 版本已優化權限檢查邏輯
.NET Core 執行時不再強制遍歷磁碟根目錄,相容性大幅提升。
Path.GetTempPath() 系統暫存目錄(通常有寫入權限)。/Uploads、/App_Data)授予 IIS_IUSRS 修改權限。Medium Trust 以上才能使用 FileIO 權限。Microsoft Scripting Runtime COM 元件。| 方案 | 適用情境 | 風險 |
|---|---|---|
| FSO COM | 舊專案、無法改權限、主機支援 COM | 相容性、安全性疑慮 |
| 要求主機授權 | 最標準、最乾淨 | 需主機商配合、等待時間 |
| 遷移至雲端儲存 | 新專案、高擴充性需求 | 架構變更成本 |
| 升級 .NET Core | 長期維護專案 | 重寫成本 |
遇到此問題時,優先嘗試「要求主機商授權特定資料夾權限」,若不可行再評估 FSO 或架構調整。