public static string GetMsiProductCode(string msiName) // Enumerates the MSIs present in the system. If 'msiName' // exists, it returns its product code. If not, it returns // the empty string. { const int GUID_LEN = 39; const int BUF_LEN = 128; int err; int len; StringBuilder productCode = new StringBuilder(GUID_LEN, GUID_LEN); StringBuilder productName = new StringBuilder(BUF_LEN, BUF_LEN); Trace.WriteLine( "Checking if \'" + msiName + "\' is present in system.." ); for (int i = 0; (err = Msi.MsiEnumProducts(i, productCode)) == WinError.ERROR_SUCCESS; ++i) { len = BUF_LEN; // Get ProductName from Product GUID err = Msi.MsiGetProductInfo( productCode.ToString(), Msi.INSTALLPROPERTY.INSTALLEDPRODUCTNAME, productName, ref len ); if (err != WinError.ERROR_SUCCESS) { Trace.WriteLine("Failed to read the name of msi " + productCode.ToString()); continue; } if (msiName.Equals( productName.ToString(), StringComparison.OrdinalIgnoreCase)) { Trace.WriteLine( "Product found; Code: \'" + productCode.ToString() + "\'" ); return(productCode.ToString()); } } if (err == WinError.ERROR_NO_MORE_ITEMS) { Trace.WriteLine("Product not found"); return(""); } else { Win32Error.Set("MsiEnumProducts", err); throw new Exception(Win32Error.GetFullErrMsg()); } }
public static bool DeleteService(string serviceName) // Marks the specified service for deletion from // the service control manager database { Trace.WriteLine( "Deleting service: \'" + serviceName + "\'" ); IntPtr scManagerHandle = AdvApi32.OpenSCManager( null, null, AdvApi32.SC_MANAGER_ALL_ACCESS ); if (scManagerHandle == IntPtr.Zero) { Win32Error.Set("OpenSCManager"); Trace.WriteLine(Win32Error.GetFullErrMsg()); return(false); } IntPtr serviceHandle = AdvApi32.OpenService( scManagerHandle, serviceName, AdvApi32.DELETE ); if (serviceHandle == IntPtr.Zero) { Win32Error.Set("OpenService"); Trace.WriteLine(Win32Error.GetFullErrMsg()); AdvApi32.CloseServiceHandle(scManagerHandle); return(false); } bool success = AdvApi32.DeleteService(serviceHandle); if (success) { Trace.WriteLine("Service deleted successfully"); } else { Win32Error.Set("DeleteService"); Trace.WriteLine(Win32Error.GetFullErrMsg()); } AdvApi32.CloseServiceHandle(serviceHandle); AdvApi32.CloseServiceHandle(scManagerHandle); return(success); }
public static void UninstallDriverPackages(string hwId) // Scans all oem*.inf files present in the system // and uninstalls all that match 'hwId' { string infPath = Path.Combine( Environment.GetEnvironmentVariable("windir"), "inf" ); Trace.WriteLine( "Searching drivers in system for \'" + hwId + "\'" ); foreach (string oemFile in Directory.GetFiles(infPath, "oem*.inf")) { // This is currently the only way to ignore case... if (File.ReadAllText(oemFile).IndexOf( hwId, StringComparison.OrdinalIgnoreCase) == -1) { continue; } Trace.WriteLine( "\'" + hwId + "\' matches" + "\'" + oemFile + "\';" ); bool needreboot; Trace.WriteLine("Uninstalling..."); int err = DIFxAPI.DriverPackageUninstall( oemFile, (int)(DIFxAPI.DRIVER_PACKAGE.SILENT | DIFxAPI.DRIVER_PACKAGE.FORCE | DIFxAPI.DRIVER_PACKAGE.DELETE_FILES), // N.B.: Starting with Windows 7, // 'DELETE_FILES' is ignored IntPtr.Zero, out needreboot ); if (err != WinError.ERROR_SUCCESS) { Win32Error.Set("DriverPackageUninstall", err); throw new Exception(Win32Error.GetFullErrMsg()); } Trace.WriteLine("Uninstalled"); } }
public static string GetDeviceInstanceId(string enum_device) // Returns the device instance ID of the specified device // 'enum_device' should have the following format: // <enumerator>\<device_id> { const int BUFFER_SIZE = 4096; string enumerator = enum_device.Split(new char[] { '\\' })[0]; StringBuilder deviceInstanceId = new StringBuilder(BUFFER_SIZE); SetupApi.SP_DEVINFO_DATA devInfoData; int reqSize; using (SetupApi.DeviceInfoSet devInfoSet = new SetupApi.DeviceInfoSet( IntPtr.Zero, enumerator, IntPtr.Zero, SetupApi.DiGetClassFlags.DIGCF_ALLCLASSES | SetupApi.DiGetClassFlags.DIGCF_PRESENT)) { devInfoData = Device.FindInSystem( enum_device, devInfoSet, false ); if (devInfoData == null) { return(""); } if (!SetupApi.SetupDiGetDeviceInstanceId( devInfoSet.Get(), devInfoData, deviceInstanceId, BUFFER_SIZE, out reqSize)) { Win32Error.Set("SetupDiGetDeviceInstanceId"); throw new Exception(Win32Error.GetFullErrMsg()); } } return(deviceInstanceId.ToString()); }
public static int GetDevNode(string enum_device = "") // Returns the device node of the specified device // 'enum_device' should have the following format: // <enumerator>\<device_id> // If it is the empty string, the root of the device // tree will be returned { CfgMgr32.CR err; int devNode; string deviceInstanceId; if (!String.IsNullOrEmpty(enum_device)) { deviceInstanceId = GetDeviceInstanceId(enum_device); if (String.IsNullOrEmpty(deviceInstanceId)) { Trace.WriteLine("No instance exists in system"); return(-1); } } else { deviceInstanceId = ""; } err = CfgMgr32.CM_Locate_DevNode( out devNode, deviceInstanceId, CfgMgr32.CM_LOCATE_DEVNODE.NORMAL ); if (err != CfgMgr32.CR.SUCCESS) { Win32Error.SetCR("CM_Locate_DevNode", err); throw new Exception(Win32Error.GetFullErrMsg()); } return(devNode); }
public static void InstallDriver( string infPath, NewDev.DIIRFLAG flags = NewDev.DIIRFLAG.ZERO) { bool reboot; Trace.WriteLine( "Installing driver: \'" + Path.GetFileName(infPath) + "\'" ); if (!NewDev.DiInstallDriver( IntPtr.Zero, infPath, flags, out reboot)) { Win32Error.Set("DiInstallDriver"); throw new Exception(Win32Error.GetFullErrMsg()); } Trace.WriteLine("Driver installed successfully"); }
public static bool Enumerate( string enum_device = "", bool installDevices = false) // 'enum_device' should have the following format: // <enumerator>\<device_id> // If it is the empty string, the root of the device // tree will be enumerated // If 'installDevices' is 'true', PnP will try to complete // installation of any not-fully-installed devices. { CfgMgr32.CR err; int devNode = GetDevNode(enum_device); CfgMgr32.CM_REENUMERATE ulFlags = CfgMgr32.CM_REENUMERATE.NORMAL; if (installDevices) { ulFlags |= CfgMgr32.CM_REENUMERATE.RETRY_INSTALLATION; } if (devNode == -1) { Trace.WriteLine("Could not get DevNode"); return(false); } Helpers.AcquireSystemPrivilege(AdvApi32.SE_LOAD_DRIVER_NAME); err = CfgMgr32.CM_Reenumerate_DevNode(devNode, ulFlags); if (err != CfgMgr32.CR.SUCCESS) { Win32Error.SetCR("CM_Reenumerate_DevNode", err); throw new Exception(Win32Error.GetFullErrMsg()); } Trace.WriteLine("Enumeration completed successfully"); return(true); }
public static WtsApi32.WTS_SESSION_INFO[] GetWTSSessions(IntPtr server) { List <WtsApi32.WTS_SESSION_INFO> ret = new List <WtsApi32.WTS_SESSION_INFO>(); int structSize = Marshal.SizeOf(typeof(WtsApi32.WTS_SESSION_INFO)); IntPtr ppSessionInfo; uint count; if (!WtsApi32.WTSEnumerateSessions( server, 0, 1, out ppSessionInfo, out count)) { Win32Error.Set("WTSEnumerateSessions"); throw new Exception(Win32Error.GetFullErrMsg()); } IntPtr element = ppSessionInfo; for (uint i = 0; i < count; ++i) { ret.Add( (WtsApi32.WTS_SESSION_INFO)Marshal.PtrToStructure( element, typeof(WtsApi32.WTS_SESSION_INFO) ) ); element = (IntPtr)((Int64)element + structSize); } WtsApi32.WTSFreeMemory(ppSessionInfo); return(ret.ToArray()); }
public static void AcquireSystemPrivilege(string name) { AdvApi32.TOKEN_PRIVILEGES tkp; IntPtr token; tkp.Privileges = new AdvApi32.LUID_AND_ATTRIBUTES[1]; AdvApi32.LookupPrivilegeValue( IntPtr.Zero, name, out tkp.Privileges[0].Luid ); tkp.PrivilegeCount = 1; tkp.Privileges[0].Attributes = (uint)AdvApi32.Se_Privilege.ENABLED; if (!AdvApi32.OpenProcessToken( Process.GetCurrentProcess().Handle, (uint)(AdvApi32.Token.ADJUST_PRIVILEGES | AdvApi32.Token.QUERY), out token)) { Win32Error.Set("OpenProcessToken"); throw new Exception(Win32Error.GetFullErrMsg()); } if (!AdvApi32.AdjustTokenPrivileges( token, false, ref tkp, 0, IntPtr.Zero, IntPtr.Zero)) { Win32Error.Set("AdjustTokenPrivileges"); throw new Exception(Win32Error.GetFullErrMsg()); } }
public static bool BlockUntilNoDriversInstalling(uint timeout) // Returns true, if no drivers are installing before the timeout // is reached. Returns false, if timeout is reached. To block // until no drivers are installing pass PInvoke.Winbase.INFINITE // 'timeout' is counted in seconds. { Winbase.WAIT result; Trace.WriteLine("Checking if drivers are currently installing"); if (timeout != Winbase.INFINITE) { Trace.WriteLine("Blocking for " + timeout + " seconds.."); timeout *= 1000; } else { Trace.WriteLine("Blocking until no drivers are installing"); } result = CfgMgr32.CMP_WaitNoPendingInstallEvents( timeout ); if (result == Winbase.WAIT.OBJECT_0) { Trace.WriteLine("No drivers installing"); return(true); } else if (result == Winbase.WAIT.FAILED) { Win32Error.Set("CMP_WaitNoPendingInstallEvents"); throw new Exception(Win32Error.GetFullErrMsg()); } Trace.WriteLine("Timeout reached - drivers still installing"); return(false); }
public static bool HasChildren(Devs xenBusDev) { CfgMgr32.CR err; string xenBusHwId = XenBus.hwIDs[ Helpers.BitIdxFromFlag((uint)xenBusDev) ]; int xenBusNode = Device.GetDevNode(xenBusHwId); int xenBusChild; if (xenBusNode == -1) { Trace.WriteLine("Could not get XenBus DevNode"); return(false); } err = CfgMgr32.CM_Get_Child( out xenBusChild, xenBusNode, 0 ); if (err == CfgMgr32.CR.NO_SUCH_DEVNODE) { Trace.WriteLine("XenBus device has no children"); return(false); } else if (err != CfgMgr32.CR.SUCCESS) { Win32Error.SetCR("CM_Get_Child", err); throw new Exception(Win32Error.GetFullErrMsg()); } Trace.WriteLine("XenBus device has at least one child"); return(true); }
private static bool InformInstallerInitiator(uint timeout = 0) // Informs the user who ran Setup.exe about the overall // success or failure of the 'InstallAgent' // Returns 'true' if the user was successfully informed; // 'false' otherwise { string text = Branding.GetString("BRANDING_managementName"); if (installStatus == InstallStatus.Installed) { text = text + " " + Branding.GetString("BRANDING_installSuccess"); } else if (installStatus == InstallStatus.Failed) { text = text + " " + Branding.GetString("BRANDING_installFailed"); } else { throw new Exception( "InstallStatus: \'" + installStatus + "\' " + Branding.GetString("BRANDING_notSupport") ); } string caption = Branding.GetString("BRANDING_manufacturer") + " " + Branding.GetString("BRANDING_hypervisorProduct") + " " + Branding.GetString("BRANDING_managementName") + " " + Branding.GetString("BRANDING_setupString"); string sid = GetInstallerInitiatorSid(); WtsApi32.ID resp; WtsApi32.WTS_SESSION_INFO[] sessions = Helpers.GetWTSSessions( WtsApi32.WTS_CURRENT_SERVER_HANDLE ); foreach (WtsApi32.WTS_SESSION_INFO si in sessions) { bool equalSessionId; try { equalSessionId = (si.State == WtsApi32.WTS_CONNECTSTATE_CLASS.WTSActive && sid.Equals(Helpers.GetUserSidFromSessionId(si.SessionID))); } catch (Exception e) { Trace.WriteLine("Unknown user for session id " + si.SessionID.ToString() + " " + e.ToString()); continue; } if (equalSessionId) { if (!WtsApi32.WTSSendMessage( WtsApi32.WTS_CURRENT_SERVER_HANDLE, si.SessionID, caption, (uint)caption.Length * sizeof(Char), text, (uint)text.Length * sizeof(Char), WtsApi32.MB.OK | WtsApi32.MB.ICONINFORMATION, timeout, out resp, false)) { Win32Error.Set("WTSSendMessage"); throw new Exception(Win32Error.GetFullErrMsg()); } return(true); } } return(false); }
public static bool ChangeServiceStartMode( string serviceName, ExpandedServiceStartMode mode) { Trace.WriteLine( "Changing Start Mode of service: \'" + serviceName + "\'" ); IntPtr scManagerHandle = AdvApi32.OpenSCManager( null, null, AdvApi32.SC_MANAGER_ALL_ACCESS ); if (scManagerHandle == IntPtr.Zero) { Trace.WriteLine("Open Service Manager Error"); return(false); } IntPtr serviceHandle = AdvApi32.OpenService( scManagerHandle, serviceName, AdvApi32.SERVICE_QUERY_CONFIG | AdvApi32.SERVICE_CHANGE_CONFIG ); if (serviceHandle == IntPtr.Zero) { Trace.WriteLine("Open Service Error"); return(false); } if (!AdvApi32.ChangeServiceConfig( serviceHandle, AdvApi32.SERVICE_NO_CHANGE, (uint)mode, AdvApi32.SERVICE_NO_CHANGE, null, null, IntPtr.Zero, null, null, null, null)) { Win32Error.Set("ChangeServiceConfig"); Trace.WriteLine(Win32Error.GetFullErrMsg()); return(false); } AdvApi32.CloseServiceHandle(serviceHandle); AdvApi32.CloseServiceHandle(scManagerHandle); Trace.WriteLine( "Start Mode successfully changed to: \'" + mode.ToString() + "\'" ); return(true); }
public static bool RemoveFromSystem( SetupApi.DeviceInfoSet devInfoSet, string hwID, bool strictSearch) // WARNING: Removes ONLY the particular device // instance referenced by 'devInfoSet' { SetupApi.SP_DEVINFO_DATA devInfoData; devInfoData = FindInSystem( hwID, devInfoSet, strictSearch ); if (devInfoData == null) { return(false); } SetupApi.SP_REMOVEDEVICE_PARAMS rparams = new SetupApi.SP_REMOVEDEVICE_PARAMS(); rparams.ClassInstallHeader.cbSize = (uint)Marshal.SizeOf(rparams.ClassInstallHeader); rparams.ClassInstallHeader.InstallFunction = SetupApi.DI_FUNCTION.DIF_REMOVE; rparams.HwProfile = 0; rparams.Scope = SetupApi.DI_REMOVE_DEVICE_GLOBAL; GCHandle handle1 = GCHandle.Alloc(rparams); if (!SetupApi.SetupDiSetClassInstallParams( devInfoSet.Get(), devInfoData, ref rparams, Marshal.SizeOf(rparams))) { Win32Error.Set("SetupDiSetClassInstallParams"); throw new Exception( Win32Error.GetFullErrMsg() ); } Trace.WriteLine( "Removing device \'" + hwID + "\' from system" ); if (!SetupApi.SetupDiCallClassInstaller( SetupApi.DI_FUNCTION.DIF_REMOVE, devInfoSet.Get(), devInfoData)) { Win32Error.Set("SetupDiCallClassInstaller"); if (Win32Error.GetErrorNo() != WinError.ERROR_KEY_DOES_NOT_EXIST) { throw new Exception( Win32Error.GetFullErrMsg() ); } } Trace.WriteLine("Remove should have worked"); return(true); }
public static SetupApi.SP_DEVINFO_DATA FindInSystem( string hwID, SetupApi.DeviceInfoSet devInfoSet, bool strictSearch) // The function takes as input an initialized 'deviceInfoSet' // object and a hardware ID string we want to search the system // for. If 'strictSearch' is true, the device needs to exactly // match the hwID to be returned. Otherwise, the device's name // needs to start with the supplied hwID string. If the device // is found, a fully initialized 'SP_DEVINFO_DATA' object is // returned. If not, the function returns 'null'. { SetupApi.SP_DEVINFO_DATA devInfoData = new SetupApi.SP_DEVINFO_DATA(); devInfoData.cbSize = (uint)Marshal.SizeOf(devInfoData); // Select which string comparison function // to use, depending on 'strictSearch' Func <string, string, bool> hwIDFound; if (strictSearch) { hwIDFound = (string _enumID, string _hwID) => _enumID.Equals( _hwID, StringComparison.OrdinalIgnoreCase ); } else { hwIDFound = (string _enumID, string _hwID) => _enumID.StartsWith( _hwID, StringComparison.OrdinalIgnoreCase ); } Trace.WriteLine( "Searching system for device: \'" + hwID + "\'; (strict search: \'" + strictSearch + "\')" ); for (uint i = 0; SetupApi.SetupDiEnumDeviceInfo( devInfoSet.Get(), i, devInfoData); ++i) { string [] ids = GetDevRegPropertyMultiStr( devInfoSet, devInfoData, SetupApi.SPDRP.HARDWAREID ); foreach (string id in ids) { if (hwIDFound(id, hwID)) { Trace.WriteLine( "Found: \'" + String.Join(" ", ids) + "\'" ); return(devInfoData); } } } Win32Error.Set("SetupDiEnumDeviceInfo"); if (Win32Error.GetErrorNo() == WinError.ERROR_NO_MORE_ITEMS) { Trace.WriteLine("Device not found"); return(null); } throw new Exception(Win32Error.GetFullErrMsg()); }
private static bool InformInstallerInitiator( string installStatus, uint timeout = 0) // Informs the user who ran Setup.exe about the overall // success or failure of the 'InstallAgent' // Returns 'true' if the user was successfully informed; // 'false' otherwise { string text = Branding.GetString("BRANDING_managementName"); if (installStatus.Equals("Installed")) { text += " installed successfully"; } else if (installStatus.Equals("Failed")) { text += " failed to install"; } else { throw new Exception( "InstallStatus: \'" + installStatus + "\' not supported" ); } string caption = Branding.GetString("BRANDING_manufacturer") + " " + Branding.GetString("BRANDING_hypervisorProduct") + " " + Branding.GetString("BRANDING_managementName") + " " + "Setup"; string sid = GetInstallerInitiatorSid(); WtsApi32.ID resp; WtsApi32.WTS_SESSION_INFO[] sessions = Helpers.GetWTSSessions( WtsApi32.WTS_CURRENT_SERVER_HANDLE ); foreach (WtsApi32.WTS_SESSION_INFO si in sessions) { if (si.State == WtsApi32.WTS_CONNECTSTATE_CLASS.WTSActive && sid.Equals(Helpers.GetUserSidFromSessionId(si.SessionID))) { if (!WtsApi32.WTSSendMessage( WtsApi32.WTS_CURRENT_SERVER_HANDLE, si.SessionID, caption, (uint)caption.Length * sizeof(Char), text, (uint)text.Length * sizeof(Char), WtsApi32.MB.OK | WtsApi32.MB.ICONINFORMATION, timeout, out resp, false)) { Win32Error.Set("WTSSendMessage"); throw new Exception(Win32Error.GetFullErrMsg()); } return(true); } } return(false); }
public static string GetUserSidFromSessionId(UInt32 sessionId) // Gets the unique Security Identifier (SID) // of the User logged on to 'sessionId' { IntPtr token = (IntPtr)0; IntPtr tokenInf = IntPtr.Zero; uint tokenInfLen = 0; IntPtr szSid = IntPtr.Zero; string sid; try { AcquireSystemPrivilege(AdvApi32.SE_TCB_NAME); Trace.WriteLine("Using session id " + sessionId.ToString()); if (!WtsApi32.WTSQueryUserToken(sessionId, out token)) { Win32Error.Set("WTSQueryUserToken"); throw new Exception(Win32Error.GetFullErrMsg()); } // Get tokenInfLen AdvApi32.GetTokenInformation( token, AdvApi32.TOKEN_INFORMATION_CLASS.TokenUser, tokenInf, tokenInfLen, out tokenInfLen ); Win32Error.Set("GetTokenInformation"); if (Win32Error.GetErrorNo() != WinError.ERROR_INSUFFICIENT_BUFFER) { throw new Exception(Win32Error.GetFullErrMsg()); } tokenInf = Marshal.AllocHGlobal((int)tokenInfLen); if (!AdvApi32.GetTokenInformation( token, AdvApi32.TOKEN_INFORMATION_CLASS.TokenUser, tokenInf, tokenInfLen, out tokenInfLen)) { Win32Error.Set("GetTokenInformation"); throw new Exception(Win32Error.GetFullErrMsg()); } AdvApi32.TOKEN_USER tokenUser = (AdvApi32.TOKEN_USER)Marshal.PtrToStructure( tokenInf, typeof(AdvApi32.TOKEN_USER) ); if (!AdvApi32.ConvertSidToStringSid( tokenUser.User.Sid, out szSid)) { Win32Error.Set("ConvertSidToStringSid"); throw new Exception(Win32Error.GetFullErrMsg()); } sid = Marshal.PtrToStringAuto(szSid); return(sid); } finally { if (szSid != IntPtr.Zero) { Kernel32.LocalFree(szSid); } if (tokenInf != IntPtr.Zero) { Marshal.FreeHGlobal(tokenInf); } if (token != IntPtr.Zero) { Kernel32.CloseHandle(token); } } }
private static void VifDisableEnable(bool enable) { string action = enable ? "enable" : "disable"; Trace.WriteLine("===> VifDisableEnable: \'" + action + "\'"); using (SetupApi.DeviceInfoSet devInfoSet = new SetupApi.DeviceInfoSet( IntPtr.Zero, "XENVIF", IntPtr.Zero, SetupApi.DiGetClassFlags.DIGCF_PRESENT | SetupApi.DiGetClassFlags.DIGCF_ALLCLASSES)) { SetupApi.SP_DEVINFO_DATA devInfoData = new SetupApi.SP_DEVINFO_DATA(); devInfoData.cbSize = (uint)Marshal.SizeOf(devInfoData); for (uint i = 0; SetupApi.SetupDiEnumDeviceInfo( devInfoSet.Get(), i, devInfoData); ++i) { SetupApi.PropertyChangeParameters pcParams = new SetupApi.PropertyChangeParameters(); pcParams.size = 8; pcParams.diFunction = SetupApi.DI_FUNCTION.DIF_PROPERTYCHANGE; pcParams.scope = SetupApi.Scopes.Global; if (enable) { pcParams.stateChange = SetupApi.StateChangeAction.Enable; } else { pcParams.stateChange = SetupApi.StateChangeAction.Disable; } pcParams.hwProfile = 0; var pinned = GCHandle.Alloc(pcParams, GCHandleType.Pinned); byte[] temp = new byte[Marshal.SizeOf(pcParams)]; Marshal.Copy( pinned.AddrOfPinnedObject(), temp, 0, Marshal.SizeOf(pcParams) ); var pdd = GCHandle.Alloc(devInfoData, GCHandleType.Pinned); if (!SetupApi.SetupDiSetClassInstallParams( devInfoSet.Get(), pdd.AddrOfPinnedObject(), pinned.AddrOfPinnedObject(), Marshal.SizeOf(pcParams))) { Win32Error.Set("SetupDiSetClassInstallParams"); Trace.WriteLine(Win32Error.GetFullErrMsg()); } if (!SetupApi.SetupDiCallClassInstaller( SetupApi.DI_FUNCTION.DIF_PROPERTYCHANGE, devInfoSet.Get(), pdd.AddrOfPinnedObject())) { Win32Error.Set("SetupDiCallClassInstaller"); Trace.WriteLine(Win32Error.GetFullErrMsg()); } pdd.Free(); pinned.Free(); } } Trace.WriteLine("<=== VifDisableEnable"); }
public static void UninstallMsi( string msiCode, string args = "", int tries = 1) // Uses 'msiexec.exe' to uninstall MSI with product code // 'msiCode'. If the exit code is none of 'ERROR_SUCCCESS', // the function sleeps and then retries. The amount of time // sleeping is doubled on every try, starting at 1 second. { if (tries < 1) { throw new Exception("tries = " + tries + " < 1"); } int secs; ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.FileName = "msiexec.exe"; startInfo.Arguments = "/x " + msiCode + " " + args; startInfo.WindowStyle = ProcessWindowStyle.Hidden; startInfo.CreateNoWindow = true; for (int i = 0; i < tries; ++i) { Trace.WriteLine( "Running: \'" + startInfo.FileName + " " + startInfo.Arguments + "\'" ); using (Process proc = Process.Start(startInfo)) { proc.WaitForExit(); Win32Error.Set(proc.ExitCode); switch (proc.ExitCode) { case WinError.ERROR_SUCCESS: case WinError.ERROR_SUCCESS_REBOOT_INITIATED: case WinError.ERROR_SUCCESS_REBOOT_REQUIRED: Trace.WriteLine(Win32Error.GetFullErrMsg()); return; default: if (i == tries - 1) { throw new Exception( "Tries exhausted; " + Win32Error.GetFullErrMsg() ); } secs = (int)Math.Pow(2.0, (double)i); Trace.WriteLine( "Msi uninstall failed; " + Win32Error.GetFullErrMsg() ); Trace.WriteLine( "Retrying in " + secs + " seconds" ); Thread.Sleep(secs * 1000); break; } } } }
public static void InstallDriver( string name, string infPath, out bool reboot, NewDev.DIIRFLAG flags = NewDev.DIIRFLAG.ZERO) { Trace.WriteLine("Add to driverstore " + infPath); int size = 0; bool success = SetupApi.SetupCopyOEMInf(infPath, "", SetupApi.SPOST.NONE, SetupApi.SP_COPY.NOOVERWRITE, IntPtr.Zero, 0, ref size, IntPtr.Zero); bool bcontinue = true; reboot = false; if (!success) { int error = Marshal.GetLastWin32Error(); Trace.WriteLine("Unable to update driver - code " + error.ToString()); if ((error == 0) || (error == 0x50)) { // We still try to install the driver even the OEMInf file has already been copied, // For the case of install driver not finished, but system shutdown Trace.WriteLine("OEMInf file already copied"); } else { bcontinue = false; // Other error, does not continue } } if (!bcontinue) { return; } Trace.WriteLine( "Installing driver: \'" + Path.GetFileName(infPath) + "\'" ); NewDev.DiInstallDriver( IntPtr.Zero, infPath, flags, out reboot ); Win32Error.Set("DiInstallDriver"); if (Win32Error.GetErrorNo() == WinError.ERROR_SUCCESS) { Trace.WriteLine("Driver installed successfully"); } else if (Win32Error.GetErrorNo() == WinError.ERROR_NO_MORE_ITEMS) // DiInstallDriver() returns ERROR_NO_MORE_ITEMS when the // hardware ID in the inf file is found, but the specified // driver is not a better match than the current one and // DIIRFLAG_FORCE_INF is not used { Trace.WriteLine( "Driver not installed; newer driver already present" ); } else { throw new Exception(Win32Error.GetFullErrMsg()); } }