由于VDS已被弃用且Windows Storage Management API正在取代它 - 是否有任何WMI,IOCTL,DeviceIoControl或Windows Storage Management API方法等同于VDS方法" UninstallDisks"?
我无法找到任何其他方法来执行VDS方法" UninstallDisks"确实
任何帮助都将不胜感激。
答案 0 :(得分:0)
使用其他贡献者代码组合自己计算出来。
参考: Win32 API function to programmatically enable/disable device
下面的主要代码库:
using Microsoft.Win32.SafeHandles;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
namespace WindowsStorageManagementAPI.Devices
{
public class DeviceInfoData
{
public int Size { get; set; }
public Guid ClassGuid { get; set; }
public int DevInst { get; set; }
public IntPtr Reserved { get; set; }
}
public class SetupApiWrapper
{
private const string SetupAPI = "setupapi.dll";
private const string NewDevLib = "Newdev.dll";
#region NATIVE ENUMS
[Flags()]
private enum SetupDiGetClassDevsFlags
{
Default = 1,
Present = 2,
AllClasses = (int)0x04,
Profile = 8,
DeviceInterface = (int)0x10
}
private enum DiFunction
{
SelectDevice = 1,
InstallDevice = 2,
AssignResources = 3,
Properties = 4,
Remove = 5,
FirstTimeSetup = 6,
FoundDevice = 7,
SelectClassDrivers = 8,
ValidateClassDrivers = 9,
InstallClassDrivers = (int)0xa,
CalcDiskSpace = (int)0xb,
DestroyPrivateData = (int)0xc,
ValidateDriver = (int)0xd,
Detect = (int)0xf,
InstallWizard = (int)0x10,
DestroyWizardData = (int)0x11,
PropertyChange = (int)0x12,
EnableClass = (int)0x13,
DetectVerify = (int)0x14,
InstallDeviceFiles = (int)0x15,
UnRemove = (int)0x16,
SelectBestCompatDrv = (int)0x17,
AllowInstall = (int)0x18,
RegisterDevice = (int)0x19,
NewDeviceWizardPreSelect = (int)0x1a,
NewDeviceWizardSelect = (int)0x1b,
NewDeviceWizardPreAnalyze = (int)0x1c,
NewDeviceWizardPostAnalyze = (int)0x1d,
NewDeviceWizardFinishInstall = (int)0x1e,
Unused1 = (int)0x1f,
InstallInterfaces = (int)0x20,
DetectCancel = (int)0x21,
RegisterCoInstallers = (int)0x22,
AddPropertyPageAdvanced = (int)0x23,
AddPropertyPageBasic = (int)0x24,
Reserved1 = (int)0x25,
Troubleshooter = (int)0x26,
PowerMessageWake = (int)0x27,
AddRemotePropertyPageAdvanced = (int)0x28,
UpdateDriverUI = (int)0x29,
Reserved2 = (int)0x30
}
private enum StateChangeAction
{
Enable = 1,
Disable = 2,
PropChange = 3,
Start = 4,
Stop = 5
}
[Flags()]
private enum Scope
{
Global = 1,
ConfigSpecific = 2,
ConfigGeneral = 4
}
private enum SetupApiError
{
NoAssociatedClass = unchecked((int)0xe0000200),
ClassMismatch = unchecked((int)0xe0000201),
DuplicateFound = unchecked((int)0xe0000202),
NoDriverSelected = unchecked((int)0xe0000203),
KeyDoesNotExist = unchecked((int)0xe0000204),
InvalidDevinstName = unchecked((int)0xe0000205),
InvalidClass = unchecked((int)0xe0000206),
DevinstAlreadyExists = unchecked((int)0xe0000207),
DevinfoNotRegistered = unchecked((int)0xe0000208),
InvalidRegProperty = unchecked((int)0xe0000209),
NoInf = unchecked((int)0xe000020a),
NoSuchHDevinst = unchecked((int)0xe000020b),
CantLoadClassIcon = unchecked((int)0xe000020c),
InvalidClassInstaller = unchecked((int)0xe000020d),
DiDoDefault = unchecked((int)0xe000020e),
DiNoFileCopy = unchecked((int)0xe000020f),
InvalidHwProfile = unchecked((int)0xe0000210),
NoDeviceSelected = unchecked((int)0xe0000211),
DevinfolistLocked = unchecked((int)0xe0000212),
DevinfodataLocked = unchecked((int)0xe0000213),
DiBadPath = unchecked((int)0xe0000214),
NoClassInstallParams = unchecked((int)0xe0000215),
FileQueueLocked = unchecked((int)0xe0000216),
BadServiceInstallSect = unchecked((int)0xe0000217),
NoClassDriverList = unchecked((int)0xe0000218),
NoAssociatedService = unchecked((int)0xe0000219),
NoDefaultDeviceInterface = unchecked((int)0xe000021a),
DeviceInterfaceActive = unchecked((int)0xe000021b),
DeviceInterfaceRemoved = unchecked((int)0xe000021c),
BadInterfaceInstallSect = unchecked((int)0xe000021d),
NoSuchInterfaceClass = unchecked((int)0xe000021e),
InvalidReferenceString = unchecked((int)0xe000021f),
InvalidMachineName = unchecked((int)0xe0000220),
RemoteCommFailure = unchecked((int)0xe0000221),
MachineUnavailable = unchecked((int)0xe0000222),
NoConfigMgrServices = unchecked((int)0xe0000223),
InvalidPropPageProvider = unchecked((int)0xe0000224),
NoSuchDeviceInterface = unchecked((int)0xe0000225),
DiPostProcessingRequired = unchecked((int)0xe0000226),
InvalidCOInstaller = unchecked((int)0xe0000227),
NoCompatDrivers = unchecked((int)0xe0000228),
NoDeviceIcon = unchecked((int)0xe0000229),
InvalidInfLogConfig = unchecked((int)0xe000022a),
DiDontInstall = unchecked((int)0xe000022b),
InvalidFilterDriver = unchecked((int)0xe000022c),
NonWindowsNTDriver = unchecked((int)0xe000022d),
NonWindowsDriver = unchecked((int)0xe000022e),
NoCatalogForOemInf = unchecked((int)0xe000022f),
DevInstallQueueNonNative = unchecked((int)0xe0000230),
NotDisableable = unchecked((int)0xe0000231),
CantRemoveDevinst = unchecked((int)0xe0000232),
InvalidTarget = unchecked((int)0xe0000233),
DriverNonNative = unchecked((int)0xe0000234),
InWow64 = unchecked((int)0xe0000235),
SetSystemRestorePoint = unchecked((int)0xe0000236),
IncorrectlyCopiedInf = unchecked((int)0xe0000237),
SceDisabled = unchecked((int)0xe0000238),
UnknownException = unchecked((int)0xe0000239),
PnpRegistryError = unchecked((int)0xe000023a),
RemoteRequestUnsupported = unchecked((int)0xe000023b),
NotAnInstalledOemInf = unchecked((int)0xe000023c),
InfInUseByDevices = unchecked((int)0xe000023d),
DiFunctionObsolete = unchecked((int)0xe000023e),
NoAuthenticodeCatalog = unchecked((int)0xe000023f),
AuthenticodeDisallowed = unchecked((int)0xe0000240),
AuthenticodeTrustedPublisher = unchecked((int)0xe0000241),
AuthenticodeTrustNotEstablished = unchecked((int)0xe0000242),
AuthenticodePublisherNotTrusted = unchecked((int)0xe0000243),
SignatureOSAttributeMismatch = unchecked((int)0xe0000244),
OnlyValidateViaAuthenticode = unchecked((int)0xe0000245),
NoMoreItems = unchecked((int)0xe0000259),
ElementNotFound = unchecked((int)0xe0001168),
InvalidData = unchecked((int)0xe0000013),
}
#endregion
#region NATIVE STRUCTS
[StructLayout(LayoutKind.Sequential)]
private struct DeviceInfoDataNative
{
public int Size;
public Guid ClassGuid;
public int DeviceInstance;
public IntPtr Reserved;
}
[StructLayout(LayoutKind.Sequential)]
private struct ClassInstallHeader
{
public int Size;
public DiFunction InstallFunction;
}
[StructLayout(LayoutKind.Sequential)]
private struct PropertyChangeParameters
{
public ClassInstallHeader ClassInstallHeader;
public StateChangeAction StateChange;
public Scope Scope;
public int HwProfile;
}
[StructLayout(LayoutKind.Sequential)]
private struct RemoveDeviceParameters
{
public ClassInstallHeader ClassInstallHeader;
public Scope Scope;
public int HwProfile;
}
[StructLayout(LayoutKind.Sequential)]
private struct DevicePropertyKey
{
public Guid fmtId;
public int pId;
// from devpkey.h
public static readonly DevicePropertyKey Device_Parent = new DevicePropertyKey { fmtId = new Guid("{4340A6C5-93FA-4706-972C-7B648008A5A7}"), pId = 8 };
public static readonly DevicePropertyKey Device_Children = new DevicePropertyKey { fmtId = new Guid("{4340A6C5-93FA-4706-972C-7B648008A5A7}"), pId = 9 };
}
#endregion
#region P/INVOKE
[SuppressUnmanagedCodeSecurity()]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[DllImport(SetupAPI, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetupDiDestroyDeviceInfoList(IntPtr deviceInfoSet);
[DllImport(SetupAPI, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetupDiCallClassInstaller(DiFunction installFunction, SafeDeviceInfoSetHandle deviceInfoSet, [In()] ref DeviceInfoDataNative deviceInfoData);
[DllImport(SetupAPI, SetLastError = true)]
private static extern bool SetupDiEnumDeviceInfo(SafeDeviceInfoSetHandle DeviceInfoSet, int MemberIndex, ref DeviceInfoDataNative DeviceInfoData);
[DllImport(SetupAPI, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode, SetLastError = true)]
private static extern SafeDeviceInfoSetHandle SetupDiGetClassDevs(ref Guid ClassGuid, [MarshalAs(UnmanagedType.LPWStr)] string Enumerator, IntPtr HwndParent, SetupDiGetClassDevsFlags Flags);
[DllImport(SetupAPI, SetLastError = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetupDiGetDeviceInstanceId(IntPtr deviceInfoSet, ref DeviceInfoDataNative did, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder DeviceInstanceId, int DeviceInstanceIdSize, out int RequiredSize);
[DllImport(SetupAPI, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetupDiSetClassInstallParams(SafeDeviceInfoSetHandle deviceInfoSet, [In()] ref DeviceInfoDataNative deviceInfoData, [In()] ref RemoveDeviceParameters classInstallParams, int classInstallParamsSize);
[DllImport("Newdev.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool DiUninstallDevice(IntPtr hwnd, [In()] SafeDeviceInfoSetHandle deviceInfoSet, [In()] ref DeviceInfoDataNative deviceInfoData, [In()] int flags, out bool NeedReboot);
[DllImport(SetupAPI, SetLastError = true, EntryPoint = "SetupDiGetDevicePropertyW")]
private static extern bool SetupDiGetDeviceProperty(SafeDeviceInfoSetHandle deviceInfoSet, ref DeviceInfoDataNative DeviceInfoData, ref DevicePropertyKey propertyKey, out int propertyType, IntPtr propertyBuffer, int propertyBufferSize, out int requiredSize, int flags);
#endregion
private class SafeDeviceInfoSetHandle : SafeHandleZeroOrMinusOneIsInvalid
{
private SafeDeviceInfoSetHandle() : base(true)
{
}
protected override bool ReleaseHandle()
{
return SetupDiDestroyDeviceInfoList(this.handle);
}
}
private static DeviceInfoDataNative GetDeviceInfoData(SafeDeviceInfoSetHandle handle)
{
DeviceInfoDataNative _data = new DeviceInfoDataNative();
_data.Size = Marshal.SizeOf(_data);
if (!SetupDiEnumDeviceInfo(handle, 0, ref _data))
{
int error = Marshal.GetLastWin32Error();
if (error == (int)SetupApiError.NoMoreItems)
return _data;
throw new Win32Exception(error);
}
return _data;
}
private static DeviceInfoDataNative[] GetDevicesInfoData(SafeDeviceInfoSetHandle handle)
{
List<DeviceInfoDataNative> _data = new List<DeviceInfoDataNative>();
DeviceInfoDataNative deviceInfoData = new DeviceInfoDataNative();
int index = 0;
int deviceInfoDataSize = Marshal.SizeOf(deviceInfoData);
deviceInfoData.Size = deviceInfoDataSize;
while (SetupDiEnumDeviceInfo(handle, index, ref deviceInfoData))
{
_data.Add(deviceInfoData);
index += 1;
deviceInfoData = new DeviceInfoDataNative();
deviceInfoData.Size = deviceInfoDataSize;
}
return _data.ToArray();
}
private static int GetIndexOfInstance(SafeDeviceInfoSetHandle handle, DeviceInfoDataNative[] diData, string instanceId)
{
const int ERROR_INSUFFICIENT_BUFFER = 122;
for (int index = 0; index <= diData.Length - 1; index++)
{
StringBuilder sb = new StringBuilder(1);
int requiredSize = 0;
bool result = SetupDiGetDeviceInstanceId(handle.DangerousGetHandle(), ref diData[index], sb, sb.Capacity, out requiredSize);
if (result == false && Marshal.GetLastWin32Error() == ERROR_INSUFFICIENT_BUFFER)
{
sb.Capacity = requiredSize;
result = SetupDiGetDeviceInstanceId(handle.DangerousGetHandle(), ref diData[index], sb, sb.Capacity, out requiredSize);
}
if (result == false)
throw new Win32Exception();
if (instanceId.Equals(sb.ToString()))
{
return index;
}
}
// not found
return -1;
}
public static bool UninstallDevice(Guid classGuid, string instanceId)
{
SafeDeviceInfoSetHandle handle = null;
bool result = false;
try
{
// Get the handle to a device information set for all devices matching classGuid that are present on the system.
handle = SetupDiGetClassDevs(ref classGuid, instanceId, IntPtr.Zero, SetupDiGetClassDevsFlags.AllClasses | SetupDiGetClassDevsFlags.DeviceInterface);
if (handle.IsInvalid)
throw new Win32Exception(Marshal.GetLastWin32Error());
// Get the device information data for each matching device.
DeviceInfoDataNative data = GetDeviceInfoData(handle);
// Find the index of our instance. i.e. the touchpad mouse - I have 3 mice attached...
//int index = GetIndexOfInstance(handle, diData, instanceId);
// TODO: Check the data structure first
// Uninstall
result = StartUninstallDevice(handle, data);
}
finally
{
if (handle != null)
{
if (handle.IsClosed == false)
{
handle.Close();
}
handle.Dispose();
}
}
return result;
}
private static bool StartUninstallDevice(SafeDeviceInfoSetHandle handle, DeviceInfoDataNative data)
{
ClassInstallHeader header = new ClassInstallHeader();
RemoveDeviceParameters removalParameters = new RemoveDeviceParameters();
bool needsReboot;
removalParameters.ClassInstallHeader.Size = Marshal.SizeOf(header);
removalParameters.ClassInstallHeader.InstallFunction = DiFunction.Remove;
removalParameters.Scope = Scope.Global;
removalParameters.HwProfile = 0;
bool result = SetupDiSetClassInstallParams(handle, ref data, ref removalParameters, Marshal.SizeOf(removalParameters));
if (result == false)
throw new Win32Exception();
result = DiUninstallDevice(IntPtr.Zero, handle, ref data, 0, out needsReboot);
// TODO: Check if need reboot
if (result == false)
{
int error = Marshal.GetLastWin32Error();
if (error == (int)SetupApiError.NotDisableable)
throw new ArgumentException("Device can't be disabled (programmatically or in Device Manager)");
else if (error >= (int)SetupApiError.NoAssociatedClass && error <= (int)SetupApiError.OnlyValidateViaAuthenticode)
throw new Win32Exception("SetupAPI Error: " + ((SetupApiError)error).ToString());
else
throw new Win32Exception();
}
return result;
}
public static void RemoveDevice(Guid classGuid, string instanceId)
{
SafeDeviceInfoSetHandle handle = null;
try
{
// Get the handle to a device information set for all devices matching classGuid that are present on the system.
handle = SetupDiGetClassDevs(ref classGuid, instanceId, IntPtr.Zero, SetupDiGetClassDevsFlags.AllClasses | SetupDiGetClassDevsFlags.DeviceInterface);
if (handle.IsInvalid)
throw new Win32Exception(Marshal.GetLastWin32Error());
// Get the device information data for each matching device.
DeviceInfoDataNative data = GetDeviceInfoData(handle);
// Find the index of our instance. i.e. the touchpad mouse - I have 3 mice attached...
//int index = GetIndexOfInstance(handle, diData, instanceId);
// Uninstall
bool result = StartRemoveDevice(handle, data);
}
finally
{
if (handle != null)
{
if (handle.IsClosed == false)
{
handle.Close();
}
handle.Dispose();
}
}
}
private static bool StartRemoveDevice(SafeDeviceInfoSetHandle handle, DeviceInfoDataNative data)
{
ClassInstallHeader header = new ClassInstallHeader();
RemoveDeviceParameters removalParameters = new RemoveDeviceParameters();
removalParameters.ClassInstallHeader.Size = Marshal.SizeOf(header);
removalParameters.ClassInstallHeader.InstallFunction = DiFunction.Remove;
removalParameters.Scope = Scope.Global;
removalParameters.HwProfile = 0;
bool result = SetupDiSetClassInstallParams(handle, ref data, ref removalParameters, Marshal.SizeOf(removalParameters));
if (result == false)
throw new Win32Exception();
result = SetupDiCallClassInstaller(DiFunction.Remove, handle, ref data);
if (result == false)
{
int error = Marshal.GetLastWin32Error();
if (error == (int)SetupApiError.NotDisableable)
throw new ArgumentException("Device can't be disabled (programmatically or in Device Manager).");
else if (error >= (int)SetupApiError.NoAssociatedClass && error <= (int)SetupApiError.OnlyValidateViaAuthenticode)
throw new Win32Exception("SetupAPI Error: " + ((SetupApiError)error).ToString());
else
throw new Win32Exception();
}
return result;
}
}
}
用法:
/////* CD-ROM as an example */////
// Found in the Device Manager under <Device> -> Properties -> Details -> Class Guid
Guid cdromClassGuid = new Guid("4d36e965-e325-11ce-bfc1-08002be10318");
// Found using WMI calls -> Disk -> Partitions -> LogicalDisks
// For the CD-ROM example: Device Manager under <Device> -> Properties -> Details -> Device Instance Path
string cdromInstancePath = @"SCSI\CDROM&VEN_MATSHITA&PROD_BD-RE_UJ260AF\4&315C1285&0&000000";
bool success = SetupApiWrapper.UninstallDevice(cdromClassGuid, cdromInstancePath);