2016年3月25日 星期五

Get and change CD ROM drive letter (修改光碟機代號)

CD ROM 的 drive letter 記錄在 Windows Registry 裡面:
  • HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\CD Burning\DriveIndex

若要使用 C# 修改CD ROM 的 drive letter, 必須透過 WMI 取得目前的drive letter, 再透過 WinAPI 改變drive letter。

1). 透過 WMI 取得目前的drive letter -

先加入 System.Management.dll 參考,在使用SelectQuery ManagementObjectSearcher ,如下:


SelectQuery queryCDROM = new SelectQuery("SELECT * FROM Win32_cdromdrive");
ManagementObjectSearcher searcherCDROM = new ManagementObjectSearcher(queryCDROM);
       
 foreach (ManagementObject cdromLetter in searcherCDROM.Get())
{
        string letter = cdromLetter["Drive"] + @"\";
        ChangeDriveLetter(letter); // sub-function to change drive letter, please see 2). 
}


2). 透過 WinAPI 改變drive letter - 
  • 先用DllImport把下列三個win api 載入進來:
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool GetVolumeNameForVolumeMountPoint(string lpszVolumeMountPoint, [Out] StringBuilder lpszVolumeName, uint cchBufferLength);

[DllImport("kernel32.dll")]
static extern bool DeleteVolumeMountPoint(string lpszVolumeMountPoint);

[DllImport("kernel32.dll")]
static extern bool SetVolumeMountPoint(string lpszVolumeMountPoint, string lpszVolumeName);


  • 在ChangeDriveLetter() 方法中,使用上述的三個win api:
        private void ChangeDriveLetter(string driveLetter)
        {
            const int MAX_PATH = 260; 
            StringBuilder volume = new StringBuilder(MAX_PATH);
            if (!GetVolumeNameForVolumeMountPoint(driveLetter, volume, (uint) MAX_PATH))
            {
                Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
            }

            if (!DeleteVolumeMountPoint(driveLetter))
            {
                Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
            }

            if (!SetVolumeMountPoint(@"W:\", volume.ToString()))  // assume to change to W:\
            {
                Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
            }
        }

** 上面列的程式碼,是先 delete 舊有的drive letter, 在 set 新的drive letter, 使用上要很小心,避免delete 非預期的drive letter。 


沒有留言:

張貼留言