// enable/disable... private static void EnableDevice(SafeDeviceInfoSetHandle handle, DeviceInfoData diData, bool enable) { PropertyChangeParameters @params = new PropertyChangeParameters(); // The size is just the size of the header, but we've flattened the structure. // The header comprises the first two fields, both integer. @params.Size = 8; @params.DiFunction = DiFunction.PropertyChange; @params.Scope = Scopes.Global; if (enable) { @params.StateChange = StateChangeAction.Enable; } else { @params.StateChange = StateChangeAction.Disable; } bool result = NativeMethods.SetupDiSetClassInstallParams(handle, ref diData, ref @params, Marshal.SizeOf(@params)); if (result == false) { throw new Win32Exception(); } result = NativeMethods.SetupDiCallClassInstaller(DiFunction.PropertyChange, handle, ref diData); if (result == false) { int err = Marshal.GetLastWin32Error(); if (err == (int)SetupApiError.NotDisableable) { throw new ArgumentException("Device can't be disabled (programmatically or in Device Manager)."); } else if (err >= (int)SetupApiError.NoAssociatedClass && err <= (int)SetupApiError.OnlyValidateViaAuthenticode) { throw new Win32Exception("SetupAPI error: " + ((SetupApiError)err).ToString()); } else { throw new Win32Exception(); } } }
public static extern bool SetupDiSetClassInstallParams( SafeDeviceInfoSetHandle deviceInfoSet, [In()] ref DeviceInfoData deviceInfoData, [In()] ref PropertyChangeParameters classInstallParams, int classInstallParamsSize);
public static extern bool SetupDiEnumDeviceInfo( SafeDeviceInfoSetHandle deviceInfoSet, int memberIndex, ref DeviceInfoData deviceInfoData);
public static extern bool SetupDiCallClassInstaller( DiFunction installFunction, SafeDeviceInfoSetHandle deviceInfoSet, [In()] ref DeviceInfoData deviceInfoData);
private static bool DiCallInstall(SafeDeviceInfoSetHandle handle, ref DeviceInfoData diData) { bool result = NativeMethods.SetupDiCallClassInstaller(DiFunction.PropertyChange, handle, ref diData); if (result == false) { int err = Marshal.GetLastWin32Error(); logger.Debug($"Throw error={err} NativeMethods.SetupDiCallClassInstaller"); if (err == (int)SetupApiError.NotDisableable) { throw new ArgumentException("Device can't be disabled (programmatically or in Device Manager)."); } else if (err >= (int)SetupApiError.NoAssociatedClass && err <= (int)SetupApiError.OnlyValidateViaAuthenticode) { throw new Win32Exception("SetupAPI error: " + ((SetupApiError)err).ToString()); } else if (err == 5) { if (restartCount < 2) { string info = ($"OS={Environment.OSVersion.Version.Major}; restart={restartCount}; "); logger.Info(info); //LogUser log = null; //if (restartCount >= 1) // log = new LogUser(); restartCount++; try { result = DiCallInstall(handle, ref diData); } catch (Exception ex) { if (restartCount >= 1) { logger.Error(ex, info + ex.Message); throw; } } finally { //log?.Out(); } } else { if (Environment.OSVersion.Version.Major < 6) //windows xp { new Win32Exception($"(WinXP) Не удалось программно перезапустить устройство. Сделайте это вручную. {nameof(err)}={err}").Throw(); } else { new Win32Exception($"Требуется запускать программу в режиме совместимости с Windows XP. {nameof(err)}={err}").Throw(); } } } else if (err == 13) { new Win32Exception($"{nameof(err)}={err} Не удалось программно перезапустить порт. Сделайте это вручную.").Throw(); } //throw new Win32Exception("Требуется закрыть COM-порт перед его отключением."); else { new Win32Exception($"{nameof(err)}={err}").Throw(); } } return(result); }