當使用者在桌面或檔案總管右鍵選單點選「新建」,Windows 會掃描 HKEY_CLASSES_ROOT 下所有副檔名鍵值,尋找包含 ShellNew 子鍵的項目。本文示範如何以 C# 程式碼註冊 .cs 副檔名,關聯至「C# 程式碼檔案」,預設使用「記事本」開啟,並出現在「新建」選單中。
HKCR\.cs → (Default) = "csfile"(ProgID)。HKCR\.cs\ShellNew → NullFile = ""(建立零位元組空檔案)。HKCR\csfile → (Default) = "C# 程式碼檔案"(顯示名稱)。HKCR\csfile\DefaultIcon → (Default) = "C:\Windows\System32\notepad.exe,1"。HKCR\csfile\shell\open\command → (Default) = "C:\Windows\System32\notepad.exe "%1""。
using System;
using Microsoft.Win32;
public static class CsFileAssociation
{
private const string Extension = ".cs";
private const string ProgId = "csfile";
private const string Description = "C# 程式碼檔案";
private const string OpenCommand = @"C:\Windows\System32\notepad.exe ""%1""";
private const string DefaultIcon = @"C:\Windows\System32\notepad.exe,1";
public static void Register()
{
// 1. 建立/開啟副檔名鍵
using (var extKey = Registry.ClassesRoot.CreateSubKey(Extension)) {
extKey.SetValue("", ProgId); // (Default) = ProgID
// 2. 建立 ShellNew 子鍵(出現在「新建」選單)
using (var shellNewKey = extKey.CreateSubKey("ShellNew")) {
shellNewKey.SetValue("NullFile", ""); // 建立空檔案
// 替代方案:指定範本檔案
// shellNewKey.SetValue("FileName", @"C:\Templates\Empty.cs");
// shellNewKey.SetValue("Data", "using System;\nclass MyClass { }"); // 直接內嵌內容
}
}
// 3. 建立/開啟 ProgID 鍵
using (var progIdKey = Registry.ClassesRoot.CreateSubKey(ProgId)) {
progIdKey.SetValue("", Description); // (Default) = 顯示名稱
// 4. 設定預設圖示
using (var iconKey = progIdKey.CreateSubKey("DefaultIcon")) {
iconKey.SetValue("", DefaultIcon);
}
// 5. 設定開啟命令
using (var cmdKey = progIdKey.CreateSubKey(@"shell\open\command")) {
cmdKey.SetValue("", OpenCommand);
}
}
// 通知 Shell 更新(可選)
SHChangeNotify(0x08000000, 0, IntPtr.Zero, IntPtr.Zero); // SHCNE_ASSOCCHANGED
}
public static void Unregister()
{
Registry.ClassesRoot.DeleteSubKeyTree(Extension, false);
Registry.ClassesRoot.DeleteSubKeyTree(ProgId, false);
SHChangeNotify(0x08000000, 0, IntPtr.Zero, IntPtr.Zero);
}
// P/Invoke 通知 Shell 關聯變更
[System.Runtime.InteropServices.DllImport("shell32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
private static extern void SHChangeNotify(uint wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2);
}
| 項目 | 說明 |
|---|---|
NullFile | 建立零位元組空檔案。最簡單、相容性最好。 |
FileName | 指定範本檔案完整路徑(需預先部署範本檔)。 |
Data | 直接指定新檔案內容(字串),無需範本檔。適用於簡單內容。 |
DefaultIcon | 格式:"路徑,索引"。索引 0 為第一個圖示資源。 |
shell\open\command | %1 會被替換為雙引號包裹的檔案完整路徑。 |
SHChangeNotify | 廣播 SHCNE_ASSOCCHANGED (0x08000000),讓總管立即刷新圖示與選單,免重啟 Explorer。 |
| 權限 | 寫入 HKCR 需管理員權限(UAC 提升)。建議在安裝程式(需管理員)中執行。 |
using (var progIdKey = Registry.ClassesRoot.CreateSubKey(ProgId)) {
// ... 既有程式碼 ...
// 新增「編輯」動作
using (var editKey = progIdKey.CreateSubKey(@"shell\edit\command")) {
editKey.SetValue("", @"C:\Windows\System32\notepad.exe ""%1""");
}
// 新增「用 VS Code 開啟」動作
using (var vscodeKey = progIdKey.CreateSubKey(@"shell\OpenWithVSCode\command")) {
vscodeKey.SetValue("", @"C:\Program Files\Microsoft VS Code\Code.exe ""%1""");
}
}
CsFileAssociation.Register()(需管理員權限)。Test.cs,雙擊 → 應以記事本開啟。regedit 檢查 HKEY_CLASSES_ROOT\.cs、HKEY_CLASSES_ROOT\csfile 結構正確性。ie4uinit.exe -show 或重啟 explorer.exe。Package.appxmanifest 中 uap:Extension Category="windows.fileTypeAssociation")。透過 Registry.ClassesRoot.CreateSubKey 建立副檔名 → ProgID → ShellNew → 圖示 → 開啟命令 的完整鍵值鏈,即可將任意副檔名註冊至 Windows「新建」右鍵選單。關鍵在於:NullFile 啟用空檔案建立、SHChangeNotify 即時刷新 Shell、管理員權限寫入 HKCR。現代部署建議使用 WiX/MSIX 等安裝程式框架聲明式管理關聯,減少手寫登錄表程式碼的維護負擔。