I am trying to write a metod that will change the CDROM drive from letter D to letter Z and not having any luck with WMI. Is there some other way that I can do this using C#?
public void setVolCDROM()
{
SelectQuery queryCDROM =
new SelectQuery("SELECT * FROM Win32_cdromdrive");
ManagementObjectSearcher searcherCDROM =
new ManagementObjectSearcher(queryCDROM);
foreach(ManagementObject cdromLetter in searcherCDROM.Get())
{
MessageBox.Show(cdromLetter["Drive"].ToString() + "\n"
+ cdromLetter["Manufacturer"].ToString());
if (cdromLetter["Drive"].ToString() == "D:")
{
cdromLetter["Drive"] = "Z:";
cd开发者_StackOverflow社区romLetter.Put();
}
}
}
I don't know about WMI, but you can change the drive letter with winapi, here is an example that I ported (just the part you need) to C#
[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);
const int MAX_PATH = 260;
private void ChangeDriveLetter()
{
StringBuilder volume = new StringBuilder(MAX_PATH);
if (!GetVolumeNameForVolumeMountPoint(@"D:\", volume, (uint)MAX_PATH))
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
if (!DeleteVolumeMountPoint(@"D:\"))
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
if (!SetVolumeMountPoint(@"Z:\", volume.ToString()))
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
}
Be careful running this code, you have to delete the drive mount point before assigning it to a new letter, this could lead to problems, from the original code:
/*****************************************************************
WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
This program will change drive letter assignments, and the
changes persist through reboots. Do not remove drive letters
of your hard disks if you do not have this program on floppy
disk or you might not be able to access your hard disks again!
*****************************************************************/
jason, you can use the Win32_Volume
class
try this code
ManagementObjectSearcher disks = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_Volume WHERE DriveLetter = 'D:'");
foreach (ManagementObject disk in disks.Get())
{
disk.Get();
disk["DriveLetter"] = "Z:";
disk.Put();
}
Thanks Rodrigo! That was exactly what I was looking for. I just added some wmi code infront of it so that I could make sure I was grabbing the CDROM drive.
public void setCDROM(){
SelectQuery queryCDROM =
new SelectQuery("SELECT * FROM Win32_cdromdrive");
ManagementObjectSearcher searcherCDROM =
new ManagementObjectSearcher(queryCDROM);
int i = 0;
foreach(ManagementObject cdromLetter in searcherCDROM.Get())
{
// if stement in place to handle if there is more than one cdrom drive
// this will only handle the first cdrom drive encountered
i = i + 1;
if (i == 1)
{
// run the ChangeDriveLetter method passing the drive letter string
ChangeDriveLetter(cdromLetter["Drive"].ToString());
}
}
}
I think WMI's SelectQueries are supposed to only read/query information and not to perform any update. I can be wrong but I think to change the drive letter you should go lower in some Win32 Api...
See IOCTL_MOUNTMGR_CREATE_POINT.
Good luck.
I would just like to add a note to rodrigoq's solution, that in Vista and up, you will need to run your app with elevated privileges otherwise you will not be able to delete the mount point and assign it a new drive letter which will cause an exception to be thrown.
精彩评论