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:
/// <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:
/// <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!
Usage would be nice 🙂