In today’s blog I am going to give you the method I use to obtain the Windows Product Activation information in Astronomy.
Q: So, where does this information come from?
A: Well, as you may know, you can obtain this information from the following script:
C:\Windows\System32\slmgr.vbs
I always felt this needed to be modified for use in .Net, so I refactored this a bit and created my own replacement method:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | /// <summary> /// Retrieves licensing information. /// </summary> /// <param name="managementScope">The management scope.</param> /// <returns></returns> public static string GetLicensingInfo(ManagementScope managementScope) { // Output string result = "Information Unavailable" ; const string windowsAppId = "55c92734-d682-4d71-983e-d6ec3f16059f" ; // Default values const uint HR_SL_E_GRACE_TIME_EXPIRED = 0xC004F009; const uint HR_SL_E_NOT_GENUINE = 0xC004F200; // Set WMI query var query = new WqlObjectQuery( "SELECT LicenseStatus, GracePeriodRemaining " + "FROM SoftwareLicensingProduct " + "WHERE (PartialProductKey <> NULL) AND " + "(ApplicationId='" + windowsAppId + "')" ); // Get items using ( var searcher = new ManagementObjectSearcher(managementScope, query)) // Get data using ( var colItems = searcher.Get()) { foreach (ManagementBaseObject obj in colItems) { string subline; // License Status int licenseStatus = Convert.ToInt32(obj.GetPropertyValue( "LicenseStatus" )); // Time remaining: minutes / days int gpMin = Convert.ToInt32(obj.GetPropertyValue( "GracePeriodRemaining" )); int gpDay = gpMin / (24 * 60); // Evaluate switch (licenseStatus) { case 0: result = "Unlicensed" ; break ; case 1: result = "Licensed" ; if (gpMin > 0) { subline = String.Format( "Activation expiration: " + "{0} minute(s) ({1} day(s))" , gpMin, gpDay); result += "\n" + subline; } break ; case 2: result = "Initial grace period" ; subline = String.Format( "Time remaining: {0} minute(s) " + "({1} day(s))" , gpMin, gpDay); result += "\n" + subline; break ; case 3: result = "Additional grace period (KMS license expired or " + "hardware out of tolerance)" ; subline = String.Format( "Time remaining: {0} minute(s) " + "({1} day(s))" , gpMin, gpDay); result += "\n" + subline; break ; case 4: result = "Non-genuine grace period." ; subline = String.Format( "Time remaining: {0} minute(s) " + "({1} day(s))" , gpMin, gpDay); result += "\n" + subline; break ; case 5: result = "Notification" ; uint licenseStatusReason; uint .TryParse(obj.GetPropertyValue( "GracePeriodRemaining" ).ToString(), out licenseStatusReason); // Evaluate switch (licenseStatusReason) { case HR_SL_E_NOT_GENUINE: subline = String.Format( "Notification Reason: 0x{0} " + "(non-genuine)." , licenseStatusReason); break ; case HR_SL_E_GRACE_TIME_EXPIRED: subline = String.Format( "Notification Reason: 0x{0} " + "(grace time expired)." , licenseStatusReason); break ; default : subline = String.Format( "Notification Reason: 0x{0}." , licenseStatusReason); break ; } result += "\n" + subline; break ; case 6: result = "Extended grace period" ; subline = String.Format( "Time remaining: {0} minute(s) " + "({1} day(s))" , gpMin, gpDay); result += "\n" + subline; break ; default : result = "Unknown" ; break ; } } } // return return result; } |
An overboard implementation:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | /// <summary> /// Connects to a target computer through Kerberos authentication. /// </summary> /// <param name="computername">The computername.</param> /// <param name="user">The user.</param> /// <param name="securePass">The secure pass.</param> /// <returns> /// A ManagementScope context for the current connection. /// </returns> public static ManagementScope Connect( string computername, string user, SecureString securePass) { // Build an options object for the remote connection var options = new ConnectionOptions { Impersonation = ImpersonationLevel.Impersonate, EnablePrivileges = true }; // Set properties // Check name if (String.IsNullOrEmpty(computername)) { computername = "." ; } // Check credentials // Cannot pass a blank user and password. if (!String.IsNullOrEmpty(user)) { options.Username = user; options.SecurePassword = securePass; } // Make a connection to a remote computer. var managementScope = new ManagementScope($ @"\{computername}\root\cimv2" , options); try { // Connect managementScope.Connect(); } catch (Exception ex) { throw ex; } // return return managementScope; } /// <summary> /// Gets the license you so desperately want. /// </summary> public void GetMyLicense() { // Get the management scope var myManagementScope = Connect( "." , "XCALIBUR\jarzt" , {my secure password}); // Get the licensing string licensing = GetLicensingInfo(myManagementScope); // Report to client MessageBox.Show( "My current licensing status: " + licensing); } |
So, really that’s all there is to it.
Happy coding!