using System; using System.Collections.Generic; using System.Text; using System.Management; using System.Diagnostics; using Developpez.Dotnet.System.Providers.Windows; using Microsoft.Win32; namespace Developpez.Dotnet.System.Providers { /// /// Fournisseur d'informations systèmes sur l'environnement Windows /// public class WindowsProvider : NullSystemProvider { #region Display name /// /// Obtient le nom du système grâce aux WMI, sans jamais lever d'exception /// protected virtual string OSName { get { try { ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_OperatingSystem"); foreach (ManagementObject queryObj in searcher.Get()) { return queryObj["Caption"] as string; } /* non trouvé */ return null; } catch (ManagementException e) { try { Trace.TraceWarning(e.ToString()); } catch { } return null; } } } /// /// Renvoi le nom du système. Equivalent à dans la plupart /// des cas /// public override string PlatformDisplayedName { get { string val = OSName; if (String.IsNullOrEmpty(val)) return Environment.OSVersion.VersionString; else return val; } } #endregion #region Reboot /// /// Accorde au processus actuel le droit d'effectuer un redémarrage du système /// /// true si l'opération est un succès, false sinon protected virtual bool AdjustShutdownTokenPriveleges() { bool ret; IntPtr hProc = IntPtr.Zero; IntPtr hToken = IntPtr.Zero; LUID luidRestore; TOKEN_PRIVILEGES tokenPriviliges; // get the current current process security token hProc = global::System.Diagnostics.Process.GetCurrentProcess().Handle; ret = Win32Api.OpenProcessToken(hProc, Win32Api.TOKEN_ADJUST_PRIVILEGES | Win32Api.TOKEN_QUERY, out hToken); if (!ret) return false; // lookup the LUID for the shutdown privilege ret = Win32Api.LookupPrivilegeValue(String.Empty, Win32Api.SE_SHUTDOWN_NAME, out luidRestore); if (!ret) return false; // adjust the privileges of the current process to include the shutdown privilege tokenPriviliges.PrivilegeCount = 1; tokenPriviliges.Luid = luidRestore; tokenPriviliges.Attributes = Win32Api.SE_PRIVILEGE_ENABLED; //TOKEN_PRIVILEGES tokenTemp = new TOKEN_PRIVILEGES(); ret = Win32Api.AdjustTokenPrivileges(hToken, false, ref tokenPriviliges, 0, IntPtr.Zero, IntPtr.Zero); if (!ret) return false; return true; } /// /// Convertit une valeur RebootReason en ShutdownReason équivalent /// /// Infrastructure /// Raison du redémarrage /// Valeur convertie internal virtual ShutdownReason ParseRebootReason(RebootReason reason) { switch (reason) { default: case RebootReason.None: { return ShutdownReason.MajorOther | ShutdownReason.MinorOther; } case RebootReason.InstallApplication: { return ShutdownReason.MajorApplication | ShutdownReason.MinorInstallation; } case RebootReason.UnInstallApplication: { return ShutdownReason.MajorApplication | ShutdownReason.MinorMaintenance; } case RebootReason.UpdateApplication: { return ShutdownReason.MajorApplication | ShutdownReason.MinorUpgrade; } } } /// /// Redémarre le système avec la raison spécifiée /// /// Raison du redémarrage /// true si le redémarrage a été initialisé, false sinon public override bool Reboot(RebootReason reason) { // Ajuster les privilèges bool ret = AdjustShutdownTokenPriveleges(); if (!ret) return false; // Et on ferme windows return Win32Api.ExitWindowsEx(ShutdownMethod.Reboot, ParseRebootReason(reason)); } #endregion #region Framework version /// /// Obtient la version installée du Framework .NET /// /// Version du Framework public override FrameworkVersion GetFrameworkVersion() { FrameworkVersion baseVersion = new FrameworkVersion(); if (FrameworkVersionRegistryHelper.IsFX35Installed()) { baseVersion.Version = new Version(3, 5); baseVersion.ServicePack = FrameworkVersionRegistryHelper.GetFX35SPLevel(); } else if (FrameworkVersionRegistryHelper.IsFX30Installed()) { baseVersion.Version = new Version(3, 0); baseVersion.ServicePack = FrameworkVersionRegistryHelper.GetFX30SPLevel(); } else if (FrameworkVersionRegistryHelper.IsFX20Installed()) { baseVersion.Version = new Version(2, 0); baseVersion.ServicePack = FrameworkVersionRegistryHelper.GetFX20SPLevel(); } else { baseVersion.Version = new Version(0, 0); /* inconnu */ baseVersion.ServicePack = 0; } return baseVersion; } #endregion #region DirectX Version /// /// Classe d'obtention des informations sur DirectX /// /// Infrastructure internal static class DXVersionInfo { /// /// Obtient un tableau de 4 ints représentant la version de DirectX /// /// public static int[] GetLiteralDXVersion() { int[] result = new int[] { 0, 0, 0, 0 }; try { using (RegistryKey DirectX = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\DirectX")) { if (DirectX == null) return result; string version_str = DirectX.GetValue("Version", null) as string; if (version_str == null) return result; else { string[] parts = version_str.Split(new string[] { "." }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length != 4) return result; else { for (int i = 0; i < 4; i++) result[i] = int.Parse(parts[i]); return result; } } } } catch { return new int[] { 0, 0, 0, 0 }; } } /// /// Désactive la gestion automatique de DirectX sur Vista (renvoi 10 si ce système est détecté) /// static bool disableVistaAutoHandler = false; /// /// Par défaut la version retournée de DirectX sur Vista est DX 10. /// Vous pouvez forcer la vérification de la version en spécifiant /// true à cette propriété ( false par défaut ) /// public static bool DisableVistaAutoHandler { get { return DXVersionInfo.disableVistaAutoHandler; } set { DXVersionInfo.disableVistaAutoHandler = value; } } /// /// Recharge les informations de version concernant DirectX /// public static void Refresh() { try { actualVersion = DirectXVersion.Unknown; switch (Environment.OSVersion.Platform) { case PlatformID.Win32NT: case PlatformID.Win32S: case PlatformID.Win32Windows: case PlatformID.WinCE: { /* a priori, ça marche */ break; } default: { actualVersion = DirectXVersion.NotSupported; return; } } if (!DisableVistaAutoHandler && Environment.OSVersion.Platform == PlatformID.Win32NT && Environment.OSVersion.Version.Major >= 6) { /* Windows Vista ou plus */ actualVersion = DirectXVersion.DirectX_10; } else { int[] parts_i = GetLiteralDXVersion(); if (parts_i[0] < 4) actualVersion = DirectXVersion.LessThanDX8; else if (parts_i[0] > 4) actualVersion = DirectXVersion.MostRecent; else { if (parts_i[1] < 8) actualVersion = DirectXVersion.LessThanDX8; else if (parts_i[1] == 8) { //DirectX 8 if (parts_i[2] < 1) actualVersion = DirectXVersion.LessThanDX8; else if (parts_i[2] == 1) { //1, 1a ou 1b switch (parts_i[3]) { default: { actualVersion = DirectXVersion.Unknown; break; } case 810: { actualVersion = DirectXVersion.DirectX_8_1_XP; break; } case 881: { actualVersion = DirectXVersion.DirectX_8_1_DO; break; } case 901: { actualVersion = DirectXVersion.DirectX_8_1_a_Or_b; break; } } } else if (parts_i[2] == 2) { switch (parts_i[3]) { default: { actualVersion = DirectXVersion.Unknown; break; } case 134: { actualVersion = DirectXVersion.DirectX_8_2; break; } } } else actualVersion = DirectXVersion.Unknown; } else if (parts_i[1] == 9) { //DirectX 9 if (parts_i[2] != 0) actualVersion = DirectXVersion.Unknown; else { switch (parts_i[3]) { default: { actualVersion = DirectXVersion.Unknown; break; } case 900: { actualVersion = DirectXVersion.DirectX_9; break; } case 901: { actualVersion = DirectXVersion.DirectX_9_a; break; } case 902: { actualVersion = DirectXVersion.DirectX_9_b; break; } case 903: case 904: { actualVersion = DirectXVersion.DirectX_9_c; break; } } } } else actualVersion = DirectXVersion.MostRecent; } } } catch { actualVersion = DirectXVersion.Unknown; } } /// /// Version actuelle de DirectX /// static DirectXVersion? actualVersion = null; /// /// Charge la version actuelle de DirectX /// /// Descriptif de la version actuelle de DirectX public static DirectXVersion GetDirectXVersion() { if (actualVersion == null) Refresh(); return actualVersion.Value; } } /// /// Obtient la version détectée de DirectX actuellement installée sur le système /// public override DirectXVersion DirectXVersion { get { return DXVersionInfo.GetDirectXVersion(); } } #endregion } }