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!